Skip to content

Commit

Permalink
feat!: Add outgoing MQTT support
Browse files Browse the repository at this point in the history
  • Loading branch information
mountaindude committed Oct 22, 2021
1 parent 98710c4 commit 0a190cb
Show file tree
Hide file tree
Showing 5 changed files with 469 additions and 6 deletions.
36 changes: 32 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,25 @@ There are instructions in [the template file](https://github.com/ptarmiganlabs/b

This file contains sensitive information about where to find the Sense server certificates used when connecting to the Sense servers, as well as other parameters used to run the actual cache warming service. This file is stored on local disk.

## MQTT support

[MQTT](https://mqtt.org) is a lightweight, robust, publish-subscribe (pub-sub) protocol used in the IoT sector and elsewhere.
It's very easy to use and makes it trivial to send data from one source system to any number of destination systems ("subscribers") that are interested in this particular data.

Butler CW can be configured to send a MQTT message every time an app is cache warmed.
The configuration is done in the `mqttConfig` section of the main config file:

```YAML
# MQTT config parameters
mqttConfig:
out:
enable: true # Should info about cache run/warming events be sent as MQTT messages?
baseTopic: butler-cw/ # Topic to send cache run events to. Should end with /
tzFormat: UTC # LOCAL or UTC. Default is UTC
broker: # MQTT server/broker config
uri: mqtt://<MQTT server ip/FQDN>:<port> ## Port is usually 1883
```

## Installation and setup

### Running as a native Node.js app
Expand Down Expand Up @@ -181,6 +200,16 @@ clientCertPath: /nodeapp/config/certificate/client.pem
clientCertKeyPath: /nodeapp/config/certificate/client_key.pem
clientCertCAPath: /nodeapp/config/certificate/root.pem

# MQTT config parameters
mqttConfig:
out:
enable: true # Should info about cache run/warming events be sent as MQTT messages?
baseTopic: butler-cw/ # Topic to send cache run events to. Should end with /
tzFormat: UTC # LOCAL or UTC. Default is UTC
# Items below are mandatory if mqttConfig.enable=true
broker:
uri: mqtt://1.2.3.4:1883 ## Port is usually 1883

# QIX version to use
qixVersion: 12.170.2

Expand Down Expand Up @@ -228,26 +257,25 @@ proton:butler-cw-docker goran$ cat config/apps.yaml
# doInitialLoad: Set to true to do an initial load of this app when Butler CW is started.
# freq: Text value representation of how often the app should be loaded


apps:
- server: sense1.mydomain.com
appId: c36bfbdb-0c4b-4d57-9939-b851d2af1cb5
appDescription: License monitor
appStepThroughSheets: true
doInitialLoad: true
freq: every 60 minutes
freq: every 5 mins every weekend
- server: sense1.mydomain.com
appId: dead6f4a-da0b-4b9c-82a2-3f94fdc72599
appDescription: Meetup.com
appStepThroughSheets: true
doInitialLoad: false
freq: every 10 minutes
freq: at 5:00 pm
- server: sense2.mydomain.com
appId: 492a1bca-1c41-4a01-9104-543a2334c465
appDescription: 2018 sales targets
appStepThroughSheets: true
doInitialLoad: false
freq: every 30 minutes
freq: every 2 hours
proton:butler-cw-docker goran$
```

Expand Down
9 changes: 9 additions & 0 deletions config/default_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ clientCertCAPath: /path/to/client/cert/root.pem
# clientCertKeyPath: /nodeapp/config/certificate/client_key.pem
# clientCertCAPath: /nodeapp/config/certificate/root.pem

# MQTT config parameters
mqttConfig:
out:
enable: true # Should info about cache run/warming events be sent as MQTT messages?
baseTopic: butler-cw/ # Topic to send cache run events to. Should end with /
tzFormat: UTC # LOCAL or UTC. Default is UTC
broker: # MQTT server/broker config
uri: mqtt://<MQTT server ip/FQDN>:<port> ## Port is usually 1883

# QIX version to use
qixVersion: 12.170.2

Expand Down
31 changes: 29 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const dockerHealthCheckServer = require('fastify')({ logger: false });
const yaml = require('js-yaml');
const later = require('@breejs/later');
const GitHubApi = require('@octokit/rest');
const mqtt = require('mqtt');

const globals = require('./globals');
const heartbeat = require('./heartbeat');
Expand All @@ -16,6 +17,7 @@ let schema;
let rootCert;
let client;
let clientKey;
let mqttClient;

async function loadAppIntoCache(appConfig) {
globals.logger.log('verbose', `Starting loading of appid ${appConfig.appId}`);
Expand Down Expand Up @@ -141,11 +143,27 @@ async function loadAppIntoCache(appConfig) {
'info',
`App ${appConfig.appId}: Cached ${visCnt} visualizations on ${sheetCnt} sheets.`
);
// globals.logger.log('verbose', `Heap used: ${formatter.format(process.memoryUsage().heapUsed)}`);

const sched = later.parse.text(appConfig.freq);
const occurrence = later.schedule(sched).next();
let nextRun;

if (globals.config.get('mqttConfig.out.tzFormat').toLowerCase() === 'local') {
// Use local timezone
nextRun = occurrence.toString();
} else {
nextRun = occurrence.toUTCString();
}

// eslint-disable-next-line no-param-reassign
appConfig.nextRun = nextRun;
mqttClient.publish(
globals.config.get('mqttConfig.out.baseTopic'),
JSON.stringify(appConfig)
);
});
} else {
app.session.close();
// globals.logger.log('verbose', `Heap used: ${formatter.format(process.memoryUsage().heapUsed)}`);
}
}

Expand Down Expand Up @@ -285,6 +303,15 @@ async function mainScript() {
later.date.UTC();
}

// Set up outgoing MQTT
if (
globals.config.has('mqttConfig.out.enable') &&
globals.config.get('mqttConfig.out.enable') === true
) {
mqttClient = mqtt.connect(globals.config.get('mqttConfig.broker.uri'));
}

// Load cache warming config
try {
if (globals.config.get('appConfig.configSource') === 'disk') {
appConfigYaml = fs.readFileSync(globals.config.get('appConfig.diskConfigFile'), 'utf8');
Expand Down

0 comments on commit 0a190cb

Please sign in to comment.