typescriptifying
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
{
|
||||
"brokerUrl": "mqtt://172.16.2.15:1883",
|
||||
"brokerUrl": "mqtt://127.0.0.1:1883",
|
||||
"brokerUser": "",
|
||||
"brokerPass": "",
|
||||
"brokerCa": "",
|
||||
|
13
src/AHomematicItem.js → dist/AHomematicItem.js
vendored
13
src/AHomematicItem.js → dist/AHomematicItem.js
vendored
@ -1,7 +1,7 @@
|
||||
let AItem = require('./AItem')
|
||||
|
||||
|
||||
class AHomematicItem extends AItem {
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const AItem_1 = require("./AItem");
|
||||
class AHomematicItem extends AItem_1.AItem {
|
||||
constructor(floor, room, item, hmId) {
|
||||
super(floor, room, item);
|
||||
this.hmId = hmId;
|
||||
@ -10,6 +10,5 @@ class AHomematicItem extends AItem {
|
||||
this.deviceTopicPre = `${this.homegearTopicPre}/plain/${this.hmId}`;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AHomematicItem;
|
||||
|
||||
exports.AHomematicItem = AHomematicItem;
|
||||
//# sourceMappingURL=AHomematicItem.js.map
|
18
src/AItem.js → dist/AItem.js
vendored
18
src/AItem.js → dist/AItem.js
vendored
@ -1,7 +1,7 @@
|
||||
let mqtt = require('./mqttHandler');
|
||||
let logger = require('./log');
|
||||
|
||||
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const logger = require("./log");
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
class AItem {
|
||||
constructor(floor, room, item) {
|
||||
this.floor = floor;
|
||||
@ -10,14 +10,12 @@ class AItem {
|
||||
this.itemId = `${this.floor}.${this.room}.${this.item}`;
|
||||
this.topicFirstPart = `dispatcher_ng/items/${this.floor}/${this.room}/${this.item}`;
|
||||
}
|
||||
|
||||
start() {
|
||||
mqtt.register(this.subscribeTopics, (topic, payload) => {
|
||||
logger.info(`item ${this.itemId}: ${topic}, ${payload}`)
|
||||
MqttDispatcher_1.mqttHandler.register(this.subscribeTopics, (topic, payload) => {
|
||||
logger.info(`item ${this.itemId}: ${topic}, ${payload}`);
|
||||
this.processMessage(topic, payload);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AItem;
|
||||
|
||||
exports.AItem = AItem;
|
||||
//# sourceMappingURL=AItem.js.map
|
27
src/DimmerAdaptor.js → dist/DimmerAdaptor.js
vendored
27
src/DimmerAdaptor.js → dist/DimmerAdaptor.js
vendored
@ -1,20 +1,18 @@
|
||||
let AItem = require('./AItem')
|
||||
let logger = require('./log')
|
||||
let mqtt = require('./mqttHandler');
|
||||
|
||||
|
||||
class DimmerAdaptor extends AItem {
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const AItem_1 = require("./AItem");
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
class DimmerAdaptor extends AItem_1.AItem {
|
||||
constructor(floor, room, item) {
|
||||
super(floor, room, item);
|
||||
this.actionStateTopic = `${this.topicFirstPart}/state`;
|
||||
this.actionBrightTopic = `${this.topicFirstPart}/bright`;
|
||||
this.inTopic = `${this.topicFirstPart}/dimmerIn`;
|
||||
this.subscribeTopics = [ this.inTopic ];
|
||||
this.subscribeTopics = [this.inTopic];
|
||||
this.state = 'OFF';
|
||||
this.bright = 100;
|
||||
this.brightDirection = -1;
|
||||
}
|
||||
|
||||
processMessage(topic, payload) {
|
||||
switch (topic) {
|
||||
case this.inTopic:
|
||||
@ -22,10 +20,11 @@ class DimmerAdaptor extends AItem {
|
||||
case 'SHORT':
|
||||
if (this.state == 'OFF') {
|
||||
this.state = 'ON';
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this.state = 'OFF';
|
||||
}
|
||||
mqtt.send(this.actionStateTopic, this.state, true);
|
||||
MqttDispatcher_1.mqttHandler.send(this.actionStateTopic, this.state, true);
|
||||
break;
|
||||
case 'LONG_HOLD':
|
||||
this.bright += (5 * this.brightDirection);
|
||||
@ -35,7 +34,7 @@ class DimmerAdaptor extends AItem {
|
||||
if (this.bright < 0) {
|
||||
this.bright = 0;
|
||||
}
|
||||
mqtt.send(this.actionBrightTopic, this.bright, true);
|
||||
MqttDispatcher_1.mqttHandler.send(this.actionBrightTopic, this.bright.toString(), true);
|
||||
break;
|
||||
case 'LONG_END':
|
||||
this.brightDirection = this.brightDirection * -1;
|
||||
@ -45,7 +44,5 @@ class DimmerAdaptor extends AItem {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = DimmerAdaptor;
|
||||
|
||||
exports.DimmerAdaptor = DimmerAdaptor;
|
||||
//# sourceMappingURL=DimmerAdaptor.js.map
|
53
dist/HomematicFourButtonThing.js
vendored
Normal file
53
dist/HomematicFourButtonThing.js
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const logger = require("./log");
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AHomematicItem_1 = require("./AHomematicItem");
|
||||
class HomematicFourButtonSingleItem {
|
||||
constructor(actionTopic) {
|
||||
this.actionTopic = actionTopic;
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
switch (topic) {
|
||||
case 'PRESS_SHORT':
|
||||
MqttDispatcher_1.mqttHandler.send(this.actionTopic, 'SHORT', true);
|
||||
break;
|
||||
case 'PRESS_LONG':
|
||||
case 'PRESS_CONT':
|
||||
MqttDispatcher_1.mqttHandler.send(this.actionTopic, 'LONG_HOLD', true);
|
||||
break;
|
||||
case 'PRESS_LONG_RELEASE':
|
||||
MqttDispatcher_1.mqttHandler.send(this.actionTopic, 'LONG_END', true);
|
||||
break;
|
||||
default:
|
||||
logger.warn(`HM4BSI: no handling available for ${topic}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.HomematicFourButtonSingleItem = HomematicFourButtonSingleItem;
|
||||
class HomematicFourButtonThing extends AHomematicItem_1.AHomematicItem {
|
||||
constructor(floor, room, item, hmId, itemObjs) {
|
||||
super(floor, room, item, hmId);
|
||||
this.itemObjs = itemObjs;
|
||||
if (this.itemObjs.length != 4) {
|
||||
throw new Error('itemObjs for HomematicFourButtonThing must have four elements');
|
||||
}
|
||||
this.subscribeTopics = [
|
||||
`${this.deviceTopicPre}/#`
|
||||
];
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
logger.info(`HM4B: ${topic}, ${payload}`);
|
||||
let buttonRelatedPart = topic.substring(this.deviceTopicPre.length + 1);
|
||||
let buttonIdx = parseInt(buttonRelatedPart.substring(0, buttonRelatedPart.indexOf('/')));
|
||||
if (buttonIdx >= 1 && buttonIdx <= 4) {
|
||||
this.itemObjs[buttonIdx - 1].processMessage(buttonRelatedPart.substring(buttonRelatedPart.indexOf('/') + 1), payload);
|
||||
}
|
||||
else {
|
||||
logger.warn(`HM4B: no handling available for ${topic}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.HomematicFourButtonThing = HomematicFourButtonThing;
|
||||
//# sourceMappingURL=HomematicFourButtonThing.js.map
|
26
src/m433SwitchItem.js → dist/M433SwitchItem.js
vendored
26
src/m433SwitchItem.js → dist/M433SwitchItem.js
vendored
@ -1,9 +1,8 @@
|
||||
let logger = require('./log');
|
||||
let mqtt = require('./mqttHandler');
|
||||
let AItem = require('./AItem');
|
||||
|
||||
|
||||
class M433SwitchItem extends AItem {
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AItem_1 = require("./AItem");
|
||||
class M433SwitchItem extends AItem_1.AItem {
|
||||
constructor(floor, room, item, onCode, offCode) {
|
||||
super(floor, room, item);
|
||||
this.stateTopic = `${this.topicFirstPart}/state`;
|
||||
@ -15,20 +14,19 @@ class M433SwitchItem extends AItem {
|
||||
this.onCode = onCode;
|
||||
this.offCode = offCode;
|
||||
}
|
||||
|
||||
processMessage(topic, payload) {
|
||||
this.state = payload;
|
||||
mqtt.send(this.stateFeedbackTopic, this.state);
|
||||
MqttDispatcher_1.mqttHandler.send(this.stateFeedbackTopic, this.state);
|
||||
if (this.state != this.oldState) {
|
||||
if (this.state == 'ON') {
|
||||
mqtt.send(this.actionTopic, this.onCode);
|
||||
} else {
|
||||
mqtt.send(this.actionTopic, this.offCode);
|
||||
MqttDispatcher_1.mqttHandler.send(this.actionTopic, this.onCode);
|
||||
}
|
||||
else {
|
||||
MqttDispatcher_1.mqttHandler.send(this.actionTopic, this.offCode);
|
||||
}
|
||||
this.oldState = this.state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = M433SwitchItem;
|
||||
|
||||
exports.M433SwitchItem = M433SwitchItem;
|
||||
//# sourceMappingURL=M433SwitchItem.js.map
|
9
dist/MqttDispatcher.js
vendored
9
dist/MqttDispatcher.js
vendored
@ -17,15 +17,16 @@ class MqttHandler {
|
||||
this.mqttOptions.rejectUnauthorized = true;
|
||||
}
|
||||
this.topicHandlers = [];
|
||||
logger.info("MqttHandler constructed");
|
||||
}
|
||||
register(topics, cb) {
|
||||
topics.forEach((topic) => {
|
||||
this.topicHandlers.push({ topic: topic, callback: cb });
|
||||
logger.info(`additional callback registered for ${topic}`);
|
||||
logger.info(`Callback registered for ${topic}`);
|
||||
});
|
||||
}
|
||||
exec() {
|
||||
logger.info(`connecting to ${this.mqttBrokerUrl}`);
|
||||
logger.info(`Connecting to ${this.mqttBrokerUrl}`);
|
||||
this.mqttClient = Mqtt.connect(this.mqttBrokerUrl, this.mqttOptions);
|
||||
this.mqttClient.on('error', (err) => {
|
||||
logger.error(`Error in mqttHandler: ${err}`);
|
||||
@ -37,12 +38,12 @@ class MqttHandler {
|
||||
this.mqttClient.subscribe(topicHandler.topic);
|
||||
logger.info(`${topicHandler.topic} subscribed`);
|
||||
});
|
||||
logger.info('mqtt connection established');
|
||||
logger.info('MQTT connection established');
|
||||
});
|
||||
this.mqttClient.on('message', (topic, payload, packet) => {
|
||||
if (!packet.retain) {
|
||||
let payloadStr = payload.toString('UTF-8');
|
||||
logger.info(`message received on topic ${topic}: ${payload}`);
|
||||
logger.info(`Message received on topic ${topic}: ${payload}`);
|
||||
this.processMessage(topic, payloadStr);
|
||||
}
|
||||
});
|
||||
|
3
dist/config.js
vendored
3
dist/config.js
vendored
@ -2,7 +2,6 @@
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = require("fs");
|
||||
const cmdargs = require("command-line-args");
|
||||
const logger = require("./log");
|
||||
const OPTION_DEFINITIONS = [
|
||||
{ name: 'verbose', alias: 'v', type: Boolean },
|
||||
{ name: 'config', alias: 'c', type: String, defaultValue: '~/dispatcher_ng.conf' }
|
||||
@ -10,7 +9,7 @@ const OPTION_DEFINITIONS = [
|
||||
function readConfig() {
|
||||
let options = cmdargs(OPTION_DEFINITIONS);
|
||||
exports.dict = JSON.parse(fs.readFileSync(options.config, "utf8"));
|
||||
logger.info(JSON.stringify(exports.dict));
|
||||
}
|
||||
exports.readConfig = readConfig;
|
||||
readConfig();
|
||||
//# sourceMappingURL=config.js.map
|
34
dist/main.js
vendored
34
dist/main.js
vendored
@ -1,18 +1,24 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const logger = require("./log");
|
||||
const config = require("./config");
|
||||
// import { mqttHandler } from './MqttDispatcher'
|
||||
config.readConfig();
|
||||
class Dispatcher {
|
||||
constructor() {
|
||||
logger.info("Dispatcher starting");
|
||||
}
|
||||
exec() {
|
||||
logger.info("Hello world");
|
||||
// mqttHandler.exec()
|
||||
}
|
||||
}
|
||||
const dispatcher = new Dispatcher();
|
||||
dispatcher.exec();
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const M433SwitchItem_1 = require("./M433SwitchItem");
|
||||
const HomematicFourButtonThing_1 = require("./HomematicFourButtonThing");
|
||||
const DimmerAdaptor_1 = require("./DimmerAdaptor");
|
||||
logger.info("Dispatcher starting");
|
||||
let aquariumLight = new M433SwitchItem_1.M433SwitchItem('1st', 'Anna', 'AquariumLight', '14665044 24 1', '14665041 24 1');
|
||||
aquariumLight.start();
|
||||
let deskLight = new M433SwitchItem_1.M433SwitchItem('Gnd', 'Hallway', 'DeskLight', '83221 24 1', '83220 24 1');
|
||||
deskLight.start();
|
||||
let testFourButton = new HomematicFourButtonThing_1.HomematicFourButtonThing('Gnd', 'Hallway', 'TestButton', 9, [
|
||||
new HomematicFourButtonThing_1.HomematicFourButtonSingleItem('dispatcher_ng/items/Gnd/Hallway/Testlight/dimmerIn'),
|
||||
new HomematicFourButtonThing_1.HomematicFourButtonSingleItem('dispatcher_ng/items/Gnd/Hallway/DeskLight/timerIn'),
|
||||
new HomematicFourButtonThing_1.HomematicFourButtonSingleItem('test/button/3'),
|
||||
new HomematicFourButtonThing_1.HomematicFourButtonSingleItem('test/button/4')
|
||||
]);
|
||||
testFourButton.start();
|
||||
let testDimmerAdaptor = new DimmerAdaptor_1.DimmerAdaptor('Gnd', 'Hallway', 'Testlight');
|
||||
testDimmerAdaptor.start();
|
||||
MqttDispatcher_1.mqttHandler.exec();
|
||||
logger.info("Dispatcher running");
|
||||
//# sourceMappingURL=main.js.map
|
40
package-lock.json
generated
40
package-lock.json
generated
@ -71,7 +71,7 @@
|
||||
"async-limiter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
|
||||
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
|
||||
"integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
@ -169,7 +169,7 @@
|
||||
"duplexify": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz",
|
||||
"integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==",
|
||||
"integrity": "sha1-ThUWvmiDi8kKSZlPCzmm5ZYL780=",
|
||||
"requires": {
|
||||
"end-of-stream": "1.4.0",
|
||||
"inherits": "2.0.3",
|
||||
@ -222,7 +222,7 @@
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=",
|
||||
"requires": {
|
||||
"fs.realpath": "1.0.0",
|
||||
"inflight": "1.0.6",
|
||||
@ -291,7 +291,7 @@
|
||||
"is-absolute": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
|
||||
"integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
|
||||
"integrity": "sha1-OV4a6EsR8mrReV5zwXN45IowFXY=",
|
||||
"requires": {
|
||||
"is-relative": "1.0.0",
|
||||
"is-windows": "1.0.1"
|
||||
@ -318,7 +318,7 @@
|
||||
"is-relative": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
|
||||
"integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
|
||||
"integrity": "sha1-obtpNc6MXboei5dUubLcwCDiJg0=",
|
||||
"requires": {
|
||||
"is-unc-path": "1.0.0"
|
||||
}
|
||||
@ -326,7 +326,7 @@
|
||||
"is-unc-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
|
||||
"integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
|
||||
"integrity": "sha1-1zHoiY7QkKEsNSrS6u1Qla0yLJ0=",
|
||||
"requires": {
|
||||
"unc-path-regex": "0.1.2"
|
||||
}
|
||||
@ -367,7 +367,7 @@
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
|
||||
"requires": {
|
||||
"brace-expansion": "1.1.8"
|
||||
}
|
||||
@ -380,12 +380,12 @@
|
||||
"moment": {
|
||||
"version": "2.20.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz",
|
||||
"integrity": "sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg=="
|
||||
"integrity": "sha1-1usaRsvMFKKy+UNBEsH/iQfzE/0="
|
||||
},
|
||||
"mqtt": {
|
||||
"version": "2.15.0",
|
||||
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-2.15.0.tgz",
|
||||
"integrity": "sha512-Lanijk1/Olf9frbAFJi3L38h7SOw5nUQfdywVSIRqBAYdItsyFdflaz+Kk77ajY/O3yOwTfO/V6qC85i/OhodQ==",
|
||||
"integrity": "sha1-ZL0nt7dbIvqVlProPHHNraQL1GA=",
|
||||
"requires": {
|
||||
"commist": "1.0.0",
|
||||
"concat-stream": "1.6.0",
|
||||
@ -405,7 +405,7 @@
|
||||
"mqtt-packet": {
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-5.4.0.tgz",
|
||||
"integrity": "sha512-ziN7uVysLdn7fYbOhEaKOhcZC3yIRTTakY4TFd2w+UvZIx9dPr8NCqbBYoC4WYDlzWHTn5EqR5x20pC+K24Ymg==",
|
||||
"integrity": "sha1-OHEEwGqmj7ufgVnQxyLdXD5F3yI=",
|
||||
"requires": {
|
||||
"bl": "1.2.1",
|
||||
"inherits": "2.0.3",
|
||||
@ -452,7 +452,7 @@
|
||||
"pump": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-2.0.0.tgz",
|
||||
"integrity": "sha512-6MYypjOvtiXhBSTOD0Zs5eNjCGfnqi5mPsCsW+dgKTxrZzQMZQNpBo3XRkLx7id753f3EeyHLBqzqqUymIolgw==",
|
||||
"integrity": "sha1-eUbaHI1iKwmOLOstNHZYJHCCnJ0=",
|
||||
"requires": {
|
||||
"end-of-stream": "1.4.0",
|
||||
"once": "1.4.0"
|
||||
@ -471,7 +471,7 @@
|
||||
"pump": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
|
||||
"integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
|
||||
"integrity": "sha1-Xf6DEcM7v2/BgmH580cCxHwIqVQ=",
|
||||
"requires": {
|
||||
"end-of-stream": "1.4.0",
|
||||
"once": "1.4.0"
|
||||
@ -482,7 +482,7 @@
|
||||
"readable-stream": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
|
||||
"integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
|
||||
"integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=",
|
||||
"requires": {
|
||||
"core-util-is": "1.0.2",
|
||||
"inherits": "2.0.3",
|
||||
@ -506,12 +506,12 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
|
||||
"integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM="
|
||||
},
|
||||
"simple-node-logger": {
|
||||
"version": "0.93.33",
|
||||
"resolved": "https://registry.npmjs.org/simple-node-logger/-/simple-node-logger-0.93.33.tgz",
|
||||
"integrity": "sha512-ppFuaDeacR1Vu+cP17kwOWQsx5C1vbIRa54qm5WgZBzQ5eBue/GWsDd4sr++ITnWZIoIOvjx5kEm5AhP7IqU+Q==",
|
||||
"integrity": "sha1-Le2/GMQMwsdB3/3rpwLpeKXG5uc=",
|
||||
"requires": {
|
||||
"lodash": "4.17.4",
|
||||
"moment": "2.20.1"
|
||||
@ -520,7 +520,7 @@
|
||||
"split2": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz",
|
||||
"integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==",
|
||||
"integrity": "sha1-GGsldbz4PoW30YRldWI47k7kJJM=",
|
||||
"requires": {
|
||||
"through2": "2.0.3"
|
||||
}
|
||||
@ -533,7 +533,7 @@
|
||||
"string_decoder": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
||||
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
|
||||
"integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
@ -611,7 +611,7 @@
|
||||
"ultron": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
|
||||
"integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
|
||||
"integrity": "sha1-n+FTahCmZKZSZqHjzPhf02MCvJw="
|
||||
},
|
||||
"unc-path-regex": {
|
||||
"version": "0.1.2",
|
||||
@ -635,7 +635,7 @@
|
||||
"websocket-stream": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-5.1.1.tgz",
|
||||
"integrity": "sha512-ypQ50zVCnikSvJcRFWaZh7xeCufSje5+mbJRq3mdvdNx+06TD98C+bQsSKc7FkI6y1PVuNbzkenGywxlFiQeUQ==",
|
||||
"integrity": "sha1-aNI5Fs31NonP9z4hP6IXjbzqYWk=",
|
||||
"requires": {
|
||||
"duplexify": "3.5.1",
|
||||
"inherits": "2.0.3",
|
||||
@ -653,7 +653,7 @@
|
||||
"ws": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
|
||||
"integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
|
||||
"integrity": "sha1-8c+E/i1ekB686U767OeF8YeiKPI=",
|
||||
"requires": {
|
||||
"async-limiter": "1.0.0",
|
||||
"safe-buffer": "5.1.1",
|
||||
|
17
src/AHomematicItem.ts
Normal file
17
src/AHomematicItem.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { AItem } from './AItem'
|
||||
|
||||
|
||||
export abstract class AHomematicItem extends AItem {
|
||||
protected deviceTopicPre: string;
|
||||
protected actionTopicPre: string;
|
||||
protected homegearTopicPre: string;
|
||||
protected hmId: number;
|
||||
constructor(floor: string, room: string, item: string, hmId: number) {
|
||||
super(floor, room, item);
|
||||
this.hmId = hmId;
|
||||
this.homegearTopicPre = 'homegear/instance1';
|
||||
this.actionTopicPre = `${this.homegearTopicPre}/set/${this.hmId}`;
|
||||
this.deviceTopicPre = `${this.homegearTopicPre}/plain/${this.hmId}`;
|
||||
}
|
||||
}
|
||||
|
31
src/AItem.ts
Normal file
31
src/AItem.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
|
||||
|
||||
export abstract class AItem {
|
||||
protected topicFirstPart: string;
|
||||
private itemId: string;
|
||||
private item: string;
|
||||
private room: string;
|
||||
private floor: string
|
||||
protected subscribeTopics: string[]
|
||||
|
||||
constructor(floor: string, room: string, item: string) {
|
||||
this.floor = floor
|
||||
this.room = room
|
||||
this.item = item
|
||||
this.itemId = `${this.floor}.${this.room}.${this.item}`
|
||||
this.topicFirstPart = `dispatcher_ng/items/${this.floor}/${this.room}/${this.item}`
|
||||
}
|
||||
|
||||
abstract processMessage(topic: string, payload: string) : void
|
||||
|
||||
start() : void {
|
||||
mqttHandler.register(this.subscribeTopics, (topic: string, payload: string) : void => {
|
||||
logger.info(`item ${this.itemId}: ${topic}, ${payload}`)
|
||||
this.processMessage(topic, payload)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
56
src/DimmerAdaptor.ts
Normal file
56
src/DimmerAdaptor.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import { AItem } from './AItem'
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
|
||||
|
||||
export class DimmerAdaptor extends AItem {
|
||||
private brightDirection: number
|
||||
private bright: number
|
||||
private state: string
|
||||
private inTopic: string
|
||||
private actionBrightTopic: string
|
||||
private actionStateTopic: string
|
||||
|
||||
constructor(floor: string, room: string, item: string) {
|
||||
super(floor, room, item)
|
||||
this.actionStateTopic = `${this.topicFirstPart}/state`
|
||||
this.actionBrightTopic = `${this.topicFirstPart}/bright`
|
||||
this.inTopic = `${this.topicFirstPart}/dimmerIn`
|
||||
this.subscribeTopics = [ this.inTopic ]
|
||||
this.state = 'OFF'
|
||||
this.bright = 100
|
||||
this.brightDirection = -1
|
||||
}
|
||||
|
||||
processMessage(topic: string, payload: string) {
|
||||
switch (topic) {
|
||||
case this.inTopic:
|
||||
switch (payload) {
|
||||
case 'SHORT':
|
||||
if (this.state == 'OFF') {
|
||||
this.state = 'ON'
|
||||
} else {
|
||||
this.state = 'OFF'
|
||||
}
|
||||
mqttHandler.send(this.actionStateTopic, this.state, true)
|
||||
break
|
||||
case 'LONG_HOLD':
|
||||
this.bright += (5 * this.brightDirection)
|
||||
if (this.bright > 100) {
|
||||
this.bright = 100
|
||||
}
|
||||
if (this.bright < 0) {
|
||||
this.bright = 0
|
||||
}
|
||||
mqttHandler.send(this.actionBrightTopic, this.bright.toString(), true)
|
||||
break
|
||||
case 'LONG_END':
|
||||
this.brightDirection = this.brightDirection * -1
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
let logger = require('./log');
|
||||
let mqtt = require('./mqttHandler');
|
||||
|
||||
class HomematicFourButtonSingleItem {
|
||||
constructor(name, actionTopic) {
|
||||
this.name = name;
|
||||
this.actionTopic = actionTopic;
|
||||
}
|
||||
|
||||
processMessage(topic, payload) {
|
||||
switch(topic) {
|
||||
case 'PRESS_SHORT':
|
||||
mqtt.send(this.actionTopic, 'SHORT', true);
|
||||
break;
|
||||
case 'PRESS_LONG':
|
||||
case 'PRESS_CONT':
|
||||
mqtt.send(this.actionTopic, 'LONG_HOLD', true);
|
||||
break;
|
||||
case 'PRESS_LONG_RELEASE':
|
||||
mqtt.send(this.actionTopic, 'LONG_END', true);
|
||||
break;
|
||||
default:
|
||||
logger.warn(`HM4BSI: no handling available for ${topic}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HomematicFourButtonSingleItem;
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
let logger = require('./log');
|
||||
let mqtt = require('./mqttHandler');
|
||||
let AHomematicItem = require('./AHomematicItem')
|
||||
|
||||
class HomematicFourButtonThing extends AHomematicItem {
|
||||
constructor(floor, room, item, hmId, itemObjs) {
|
||||
super(floor, room, item, hmId);
|
||||
this.itemObjs = itemObjs;
|
||||
if (this.itemObjs.length != 4) {
|
||||
throw new Error('itemObjs for HomematicFourButtonThing must have four elements');
|
||||
}
|
||||
this.subscribeTopics = [
|
||||
`${this.deviceTopicPre}/#`
|
||||
];
|
||||
}
|
||||
|
||||
processMessage(topic, payload) {
|
||||
logger.info(`HM4B: ${topic}, ${payload}`);
|
||||
let buttonRelatedPart = topic.substring(this.deviceTopicPre.length+1);
|
||||
let buttonIdx = parseInt(buttonRelatedPart.substring(0, buttonRelatedPart.indexOf('/')));
|
||||
if (buttonIdx >= 1 && buttonIdx <= 4) {
|
||||
this.itemObjs[buttonIdx-1].processMessage(buttonRelatedPart.substring(buttonRelatedPart.indexOf('/')+1), payload);
|
||||
} else {
|
||||
logger.warn(`HM4B: no handling available for ${topic}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = HomematicFourButtonThing;
|
||||
|
58
src/HomematicFourButtonThing.ts
Normal file
58
src/HomematicFourButtonThing.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { AHomematicItem } from './AHomematicItem'
|
||||
|
||||
|
||||
export class HomematicFourButtonSingleItem {
|
||||
private actionTopic: string
|
||||
|
||||
constructor(actionTopic: string) {
|
||||
this.actionTopic = actionTopic
|
||||
}
|
||||
|
||||
processMessage(topic: string, payload: string) {
|
||||
switch(topic) {
|
||||
case 'PRESS_SHORT':
|
||||
mqttHandler.send(this.actionTopic, 'SHORT', true)
|
||||
break
|
||||
case 'PRESS_LONG':
|
||||
case 'PRESS_CONT':
|
||||
mqttHandler.send(this.actionTopic, 'LONG_HOLD', true)
|
||||
break
|
||||
case 'PRESS_LONG_RELEASE':
|
||||
mqttHandler.send(this.actionTopic, 'LONG_END', true)
|
||||
break
|
||||
default:
|
||||
logger.warn(`HM4BSI: no handling available for ${topic}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class HomematicFourButtonThing extends AHomematicItem {
|
||||
private itemObjs: HomematicFourButtonSingleItem[]
|
||||
|
||||
constructor(floor: string, room: string, item: string, hmId: number, itemObjs: HomematicFourButtonSingleItem[]) {
|
||||
super(floor, room, item, hmId)
|
||||
this.itemObjs = itemObjs
|
||||
if (this.itemObjs.length != 4) {
|
||||
throw new Error('itemObjs for HomematicFourButtonThing must have four elements')
|
||||
}
|
||||
this.subscribeTopics = [
|
||||
`${this.deviceTopicPre}/#`
|
||||
]
|
||||
}
|
||||
|
||||
processMessage(topic: string, payload: string) {
|
||||
logger.info(`HM4B: ${topic}, ${payload}`)
|
||||
let buttonRelatedPart = topic.substring(this.deviceTopicPre.length+1)
|
||||
let buttonIdx = parseInt(buttonRelatedPart.substring(0, buttonRelatedPart.indexOf('/')))
|
||||
if (buttonIdx >= 1 && buttonIdx <= 4) {
|
||||
this.itemObjs[buttonIdx-1].processMessage(buttonRelatedPart.substring(buttonRelatedPart.indexOf('/')+1), payload)
|
||||
} else {
|
||||
logger.warn(`HM4B: no handling available for ${topic}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
40
src/M433SwitchItem.ts
Normal file
40
src/M433SwitchItem.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { AItem } from './AItem'
|
||||
|
||||
|
||||
export class M433SwitchItem extends AItem {
|
||||
private offCode: string
|
||||
private onCode: string
|
||||
private oldState: string|undefined
|
||||
private state: string
|
||||
private actionTopic: string
|
||||
private stateFeedbackTopic: string
|
||||
private stateTopic: string
|
||||
|
||||
constructor(floor: string, room: string, item: string, onCode: string, offCode: string) {
|
||||
super(floor, room, item)
|
||||
this.stateTopic = `${this.topicFirstPart}/state`
|
||||
this.subscribeTopics = [this.stateTopic]
|
||||
this.stateFeedbackTopic = `${this.topicFirstPart}/state/feedback`
|
||||
this.actionTopic = 'IoT/Mqtt433Gateway/Message'
|
||||
this.state = 'OFF'
|
||||
this.oldState = undefined
|
||||
this.onCode = onCode
|
||||
this.offCode = offCode
|
||||
}
|
||||
|
||||
processMessage(topic: string, payload: string) {
|
||||
this.state = payload;
|
||||
mqttHandler.send(this.stateFeedbackTopic, this.state);
|
||||
if (this.state != this.oldState) {
|
||||
if (this.state == 'ON') {
|
||||
mqttHandler.send(this.actionTopic, this.onCode);
|
||||
} else {
|
||||
mqttHandler.send(this.actionTopic, this.offCode);
|
||||
}
|
||||
this.oldState = this.state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,17 +32,19 @@ class MqttHandler {
|
||||
}
|
||||
|
||||
this.topicHandlers = []
|
||||
|
||||
logger.info("MqttHandler constructed")
|
||||
}
|
||||
|
||||
register(topics: string[], cb: TopicCallbackFunc) : void {
|
||||
topics.forEach((topic) => {
|
||||
this.topicHandlers.push({topic: topic, callback: cb})
|
||||
logger.info(`additional callback registered for ${topic}`)
|
||||
logger.info(`Callback registered for ${topic}`)
|
||||
})
|
||||
}
|
||||
|
||||
exec() : void {
|
||||
logger.info(`connecting to ${this.mqttBrokerUrl}`)
|
||||
logger.info(`Connecting to ${this.mqttBrokerUrl}`)
|
||||
this.mqttClient = Mqtt.connect(this.mqttBrokerUrl, this.mqttOptions)
|
||||
|
||||
this.mqttClient.on('error', (err) => {
|
||||
@ -55,12 +57,12 @@ class MqttHandler {
|
||||
this.mqttClient.subscribe(topicHandler.topic)
|
||||
logger.info(`${topicHandler.topic} subscribed`)
|
||||
})
|
||||
logger.info('mqtt connection established')
|
||||
logger.info('MQTT connection established')
|
||||
})
|
||||
this.mqttClient.on('message', (topic: string, payload: Buffer, packet : Mqtt.IPublishPacket): void => {
|
||||
if (! packet.retain) {
|
||||
let payloadStr : string = payload.toString('UTF-8')
|
||||
logger.info(`message received on topic ${topic}: ${payload}`)
|
||||
logger.info(`Message received on topic ${topic}: ${payload}`)
|
||||
this.processMessage(topic, payloadStr)
|
||||
}
|
||||
})
|
||||
|
@ -1,6 +1,5 @@
|
||||
import * as fs from 'fs'
|
||||
import * as cmdargs from 'command-line-args'
|
||||
import * as logger from './log'
|
||||
|
||||
|
||||
|
||||
@ -15,5 +14,6 @@ export let dict : any
|
||||
export function readConfig() {
|
||||
let options = cmdargs(OPTION_DEFINITIONS)
|
||||
dict = JSON.parse(fs.readFileSync(options.config, "utf8"))
|
||||
logger.info(JSON.stringify(dict))
|
||||
}
|
||||
|
||||
readConfig()
|
||||
|
@ -1,9 +0,0 @@
|
||||
const SimpleNodeLogger = require('simple-node-logger');
|
||||
let opts = {
|
||||
logFilePath:'mylogfile.log',
|
||||
timestampFormat:'YYYY-MM-DD HH:mm:ss.SSS'
|
||||
};
|
||||
let log = SimpleNodeLogger.createSimpleLogger(opts);
|
||||
|
||||
|
||||
module.exports = log
|
38
src/main.ts
38
src/main.ts
@ -1,28 +1,34 @@
|
||||
import * as logger from './log'
|
||||
import * as config from './config'
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
|
||||
// import { mqttHandler } from './MqttDispatcher'
|
||||
import { M433SwitchItem } from './M433SwitchItem'
|
||||
import { HomematicFourButtonThing, HomematicFourButtonSingleItem } from './HomematicFourButtonThing'
|
||||
import { DimmerAdaptor } from './DimmerAdaptor'
|
||||
|
||||
|
||||
config.readConfig()
|
||||
logger.info("Dispatcher starting")
|
||||
|
||||
let aquariumLight = new M433SwitchItem('1st', 'Anna', 'AquariumLight', '14665044 24 1', '14665041 24 1');
|
||||
aquariumLight.start();
|
||||
|
||||
class Dispatcher {
|
||||
constructor() {
|
||||
logger.info("Dispatcher starting")
|
||||
}
|
||||
let deskLight = new M433SwitchItem('Gnd', 'Hallway', 'DeskLight', '83221 24 1', '83220 24 1');
|
||||
deskLight.start();
|
||||
|
||||
exec() : void {
|
||||
logger.info("Hello world")
|
||||
let testFourButton = new HomematicFourButtonThing('Gnd', 'Hallway', 'TestButton', 9, [
|
||||
new HomematicFourButtonSingleItem('dispatcher_ng/items/Gnd/Hallway/Testlight/dimmerIn'),
|
||||
new HomematicFourButtonSingleItem('dispatcher_ng/items/Gnd/Hallway/DeskLight/timerIn'),
|
||||
new HomematicFourButtonSingleItem('test/button/3'),
|
||||
new HomematicFourButtonSingleItem('test/button/4')
|
||||
]);
|
||||
testFourButton.start();
|
||||
|
||||
let testDimmerAdaptor = new DimmerAdaptor('Gnd', 'Hallway', 'Testlight');
|
||||
testDimmerAdaptor.start();
|
||||
|
||||
|
||||
|
||||
|
||||
// mqttHandler.exec()
|
||||
}
|
||||
}
|
||||
|
||||
const dispatcher = new Dispatcher()
|
||||
dispatcher.exec()
|
||||
mqttHandler.exec()
|
||||
logger.info("Dispatcher running")
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user