Skip to content

Instantly share code, notes, and snippets.

Part 1: Data acquisition from MQTT broker

Context

At AMMP we acquire and process data from a range of different devices and vendors, in the context of (renewable) energy systems. While we do much of our data acquisition over REST APIs, we also have dataloggers deployed at several hundred sites. These read data directly from the energy equipment - such as PV inverters or batteries - and send it to us over MQTT.

Details on infra/architecture

With respect to MQTT, most dataloggers send directly to the main AMMP MQTT broker at mqtt.ammp.io. We also have a staging (testing) broker at mqtt.stage.ammp.io.

We use AWS for all hosting. Most of our code runs either directly on an EC2 instance, or in an ECS container, or as a Lambda (serverless) function. We generally use ECS for more resource-intensive or long-running acquisition functions, and we prefer to use Lambdas for more "bursty" loads.

import { GraphQLServer } from 'graphql-yoga'
import mongoose from "mongoose"
const connection = mongoose.connect('mongodb://my_awesome_db')
const Schema = mongoose.Schema;
const productSchema = new Schema({
name: {type:String},
description: {type:String},
@ImreC
ImreC / resolvers.js
Created May 8, 2018 13:54
GraphQL tutorial
const resolvers = {
Query: {
product: async (_id) => {
return (await products.findOne(_id))
},
products: async () => {
return (await products.find({}))
},
},
}
@ImreC
ImreC / types.js
Last active May 8, 2018 13:52
Graphql tutorial
const typeDefs =
`type Product {
_id: String
name: String
description: String
image: String
price: Float
}
type Query {
@ImreC
ImreC / mongoose.js
Created May 8, 2018 13:47
Graphql tutorial
import mongoose from "mongoose";
const Schema = mongoose.Schema;
const productSchema = new Schema({
name: {type:String},
description: {type:String},
image: {type:String},
price: {type:Number}
}, {collection:"products"}); // Defining the collection is redundant in this case.
@ImreC
ImreC / .babelrc
Created May 8, 2018 13:41
Graphql tutorial
{
"presets": [
"es2015"
],
"plugins": [
"syntax-async-functions",
"transform-regenerator"
]
}
@ImreC
ImreC / package.json
Created May 8, 2018 13:32
Package.json for graphql tutorial
{
"name": "tutorial-graphql",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "nodemon ./index.js --exec babel-node",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Imre Gelens",
before: {
all: [],
find: [ authenticate('jwt') ],
get: [ authenticate('jwt') ],
create: [
hashPassword(),
verifyHooks.addVerification()
],
update: [
commonHooks.disallow('external')
<html>
<body>
<p id = "info">
Sending token
</p>
<script>
var url = new URL(window.location.href);
var token = url.searchParams.get("token");
var obj = {
action: 'verifySignupLong',
const { authenticate } = require('@feathersjs/authentication').hooks;
const verifyHooks = require('feathers-authentication-management').hooks;
const accountService = require('../authmanagement/notifier');
const {
hashPassword, protect
} = require('@feathersjs/authentication-local').hooks;
module.exports = {
before: {