Skip to content
This repository was archived by the owner on Apr 13, 2025. It is now read-only.

Add MQTT service & sample bundle #265

Merged
merged 13 commits into from
Oct 17, 2021
87 changes: 87 additions & 0 deletions nodecg-io-mqtt-client/extension/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { NodeCG } from "nodecg-types/types/server";
import { Result, emptySuccess, success, ServiceBundle, error } from "nodecg-io-core";
import { MqttClient, connect } from "mqtt";

interface MQTTClientServiceConfig {
address: string;
topics: [string];
username?: string;
password?: string;
}

export class MQTTClientServiceClient {
client: MqttClient;
once: (event: string, cb: () => void) => void;
close: () => void;
on: (event: string, cb: () => void) => void;
off: (event: string | symbol, listener: (...args: unknown[]) => void) => void;

connect(url: string, username: string | undefined, password: string | undefined): Promise<void> {
return new Promise((resolve, reject) => {
this.client = connect(url, {
username: username,
password: password,
});
this.client.on("error", (err: Error) => {
this.client.end();
reject(err.message);
});
this.client.on("connect", resolve);

this.once = this.client.once;
this.on = this.client.on;
this.close = this.client.end;
this.off = this.client.off;
});
}

subscribe(topics: string[]): void {
topics.forEach((topic: string) => {
this.client.subscribe(topic);
});
}

onClose(func: () => void): MqttClient {
return this.client.on("close", func);
}

onMessage(func: (topic: string, message: Buffer) => void): MqttClient {
return this.client.on("message", func);
}

onError(func: (error: Error) => void): MqttClient {
return this.client.on("error", func);
}
}

module.exports = (nodecg: NodeCG) => {
new MQTTClientService(nodecg, "mqtt-client", __dirname, "../mqtt-schema.json").register();
};

class MQTTClientService extends ServiceBundle<MQTTClientServiceConfig, MQTTClientServiceClient> {
async validateConfig(config: MQTTClientServiceConfig): Promise<Result<void>> {
const client = new MQTTClientServiceClient();

await client.connect(config.address, config.username, config.password);
client.close();
return emptySuccess();
}

async createClient(config: MQTTClientServiceConfig): Promise<Result<MQTTClientServiceClient>> {
const client = new MQTTClientServiceClient();
await client.connect(config.address, config.username, config.password);
client.subscribe(config.topics);
this.nodecg.log.info("Successfully connected to the MQTT server.");
return success(client);
}

stopClient(client: MQTTClientServiceClient): void {
if (client.client.connected) {
client.close();
}
}

removeHandlers(client: MQTTClientServiceClient): void {
client.client.removeAllListeners();
}
}
24 changes: 24 additions & 0 deletions nodecg-io-mqtt-client/mqtt-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"additionalProperties": false,
"properties": {
"address": {
"type": "string",
"description": "The address of the server"
},
"password": {
"type": "string",
"description": "The password to connect to the server"
},
"username": {
"type": "string",
"description": "The username to connect to the server"
},
"topics": {
"type": "array",
"description": "Array of topic you want to subscribe to"
}
},
"required": ["address", "topics"]
}
47 changes: 47 additions & 0 deletions nodecg-io-mqtt-client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "nodecg-io-mqtt-client",
"version": "0.2.0",
"description": "Allows you to connect with an MQTT server.",
"homepage": "https://nodecg.io/RELEASE/samples/mqtt-client",
"author": {
"name": "Nils Witt",
"url": "https://github.com/Nils-witt"
},
"repository": {
"type": "git",
"url": "https://github.com/codeoverflow-org/nodecg-io.git",
"directory": "nodecg-io-mqtt"
},
"files": [
"**/*.js",
"**/*.js.map",
"**/*.d.ts",
"*.json"
],
"main": "extension/index",
"scripts": {
"build": "tsc -b",
"watch": "tsc -b -w",
"clean": "tsc -b --clean"
},
"keywords": [
"nodecg-io",
"nodecg-bundle"
],
"nodecg": {
"compatibleRange": "^1.1.1",
"bundleDependencies": {
"nodecg-io-core": "^0.2.0"
}
},
"license": "MIT",
"devDependencies": {
"@types/node": "^15.0.2",
"nodecg-types": "^1.8.2",
"typescript": "^4.2.4"
},
"dependencies": {
"nodecg-io-core": "^0.2.0",
"mqtt": "^4.2.8"
}
}
3 changes: 3 additions & 0 deletions nodecg-io-mqtt-client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../tsconfig.common.json"
}
21 changes: 21 additions & 0 deletions samples/mqtt-client/extension/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { NodeCG } from "nodecg-types/types/server";
import { requireService } from "nodecg-io-core";
import { MQTTClientServiceClient } from "nodecg-io-mqtt-client";

module.exports = function (nodecg: NodeCG) {
nodecg.log.info("Sample bundle for mqtt-client started");

const service = requireService<MQTTClientServiceClient>(nodecg, "mqtt-client");

service?.onAvailable((client) => {
nodecg.log.info("Client has been updated, waiting for messages.");

client.onMessage((topic: string, message: Buffer) => {
nodecg.log.info(`recieved message "${message.toString()}" "${topic}"`);
});
});

service?.onUnavailable(() => {
nodecg.log.info("Client has been unset.");
});
};
24 changes: 24 additions & 0 deletions samples/mqtt-client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "mqtt-client",
"version": "0.2.0",
"private": true,
"nodecg": {
"compatibleRange": "^1.1.1",
"bundleDependencies": {
"nodecg-io-mqtt-client": "^0.2.0"
}
},
"scripts": {
"build": "tsc -b",
"watch": "tsc -b -w",
"clean": "tsc -b --clean"
},
"license": "MIT",
"dependencies": {
"@types/node": "^15.0.2",
"nodecg-types": "^1.8.2",
"nodecg-io-core": "^0.2.0",
"nodecg-io-mqtt-client": "^0.2.0",
"typescript": "^4.2.4"
}
}
3 changes: 3 additions & 0 deletions samples/mqtt-client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../../tsconfig.common.json"
}