From 8d85314fc946180256f7c999039085bc11be8205 Mon Sep 17 00:00:00 2001 From: Wolfgang Hottgenroth Date: Tue, 9 Jan 2018 16:36:14 +0100 Subject: [PATCH] typescriptifying --- dispatcher_ng.conf | 2 +- {src => dist}/AHomematicItem.js | 13 ++--- {src => dist}/AItem.js | 18 +++--- {src => dist}/DimmerAdaptor.js | 29 +++++----- dist/HomematicFourButtonThing.js | 53 +++++++++++++++++ .../M433SwitchItem.js | 28 +++++---- dist/MqttDispatcher.js | 9 +-- dist/config.js | 3 +- dist/main.js | 34 ++++++----- package-lock.json | 40 ++++++------- src/AHomematicItem.ts | 17 ++++++ src/AItem.ts | 31 ++++++++++ src/DimmerAdaptor.ts | 56 ++++++++++++++++++ src/HomematicFourButtonSingleItem.js | 31 ---------- src/HomematicFourButtonThing.js | 31 ---------- src/HomematicFourButtonThing.ts | 58 +++++++++++++++++++ src/M433SwitchItem.ts | 40 +++++++++++++ src/MqttDispatcher.ts | 10 ++-- src/config.ts | 4 +- src/log.js | 9 --- src/main.ts | 38 +++++++----- 21 files changed, 372 insertions(+), 182 deletions(-) rename {src => dist}/AHomematicItem.js (56%) rename {src => dist}/AItem.js (58%) rename {src => dist}/DimmerAdaptor.js (67%) create mode 100644 dist/HomematicFourButtonThing.js rename src/m433SwitchItem.js => dist/M433SwitchItem.js (50%) create mode 100644 src/AHomematicItem.ts create mode 100644 src/AItem.ts create mode 100644 src/DimmerAdaptor.ts delete mode 100644 src/HomematicFourButtonSingleItem.js delete mode 100644 src/HomematicFourButtonThing.js create mode 100644 src/HomematicFourButtonThing.ts create mode 100644 src/M433SwitchItem.ts delete mode 100644 src/log.js diff --git a/dispatcher_ng.conf b/dispatcher_ng.conf index d0899b2..73eb273 100644 --- a/dispatcher_ng.conf +++ b/dispatcher_ng.conf @@ -1,5 +1,5 @@ { - "brokerUrl": "mqtt://172.16.2.15:1883", + "brokerUrl": "mqtt://127.0.0.1:1883", "brokerUser": "", "brokerPass": "", "brokerCa": "", diff --git a/src/AHomematicItem.js b/dist/AHomematicItem.js similarity index 56% rename from src/AHomematicItem.js rename to dist/AHomematicItem.js index a68b0e1..16607ab 100644 --- a/src/AHomematicItem.js +++ b/dist/AHomematicItem.js @@ -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 \ No newline at end of file diff --git a/src/AItem.js b/dist/AItem.js similarity index 58% rename from src/AItem.js rename to dist/AItem.js index b98fe40..2600772 100644 --- a/src/AItem.js +++ b/dist/AItem.js @@ -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 \ No newline at end of file diff --git a/src/DimmerAdaptor.js b/dist/DimmerAdaptor.js similarity index 67% rename from src/DimmerAdaptor.js rename to dist/DimmerAdaptor.js index cff83e5..de07e72 100644 --- a/src/DimmerAdaptor.js +++ b/dist/DimmerAdaptor.js @@ -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,17 +34,15 @@ 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; break; - } + } break; } } } - - -module.exports = DimmerAdaptor; - +exports.DimmerAdaptor = DimmerAdaptor; +//# sourceMappingURL=DimmerAdaptor.js.map \ No newline at end of file diff --git a/dist/HomematicFourButtonThing.js b/dist/HomematicFourButtonThing.js new file mode 100644 index 0000000..fcb755d --- /dev/null +++ b/dist/HomematicFourButtonThing.js @@ -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 \ No newline at end of file diff --git a/src/m433SwitchItem.js b/dist/M433SwitchItem.js similarity index 50% rename from src/m433SwitchItem.js rename to dist/M433SwitchItem.js index 0145268..2aad18c 100644 --- a/src/m433SwitchItem.js +++ b/dist/M433SwitchItem.js @@ -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); - if (this.state != this.oldState) { + 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 \ No newline at end of file diff --git a/dist/MqttDispatcher.js b/dist/MqttDispatcher.js index df54a9f..30f7f45 100644 --- a/dist/MqttDispatcher.js +++ b/dist/MqttDispatcher.js @@ -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); } }); diff --git a/dist/config.js b/dist/config.js index ec0ac99..71f5677 100644 --- a/dist/config.js +++ b/dist/config.js @@ -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 \ No newline at end of file diff --git a/dist/main.js b/dist/main.js index a1b1185..7d3ebd9 100644 --- a/dist/main.js +++ b/dist/main.js @@ -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 \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7eb327a..aafc8d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/src/AHomematicItem.ts b/src/AHomematicItem.ts new file mode 100644 index 0000000..efa2c8b --- /dev/null +++ b/src/AHomematicItem.ts @@ -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}`; + } +} + diff --git a/src/AItem.ts b/src/AItem.ts new file mode 100644 index 0000000..5b1b251 --- /dev/null +++ b/src/AItem.ts @@ -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) + }) + } +} + + diff --git a/src/DimmerAdaptor.ts b/src/DimmerAdaptor.ts new file mode 100644 index 0000000..2df6075 --- /dev/null +++ b/src/DimmerAdaptor.ts @@ -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 + } + } +} + + diff --git a/src/HomematicFourButtonSingleItem.js b/src/HomematicFourButtonSingleItem.js deleted file mode 100644 index 3d23e80..0000000 --- a/src/HomematicFourButtonSingleItem.js +++ /dev/null @@ -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; - - diff --git a/src/HomematicFourButtonThing.js b/src/HomematicFourButtonThing.js deleted file mode 100644 index a527220..0000000 --- a/src/HomematicFourButtonThing.js +++ /dev/null @@ -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; - diff --git a/src/HomematicFourButtonThing.ts b/src/HomematicFourButtonThing.ts new file mode 100644 index 0000000..1886fa8 --- /dev/null +++ b/src/HomematicFourButtonThing.ts @@ -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}`) + } + } +} + + diff --git a/src/M433SwitchItem.ts b/src/M433SwitchItem.ts new file mode 100644 index 0000000..657c106 --- /dev/null +++ b/src/M433SwitchItem.ts @@ -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; + } + } +} + diff --git a/src/MqttDispatcher.ts b/src/MqttDispatcher.ts index 5de2feb..5ff59b8 100644 --- a/src/MqttDispatcher.ts +++ b/src/MqttDispatcher.ts @@ -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) } }) diff --git a/src/config.ts b/src/config.ts index ad0e115..f3a0ad4 100644 --- a/src/config.ts +++ b/src/config.ts @@ -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() diff --git a/src/log.js b/src/log.js deleted file mode 100644 index dc3869a..0000000 --- a/src/log.js +++ /dev/null @@ -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 diff --git a/src/main.ts b/src/main.ts index 89a10ae..2d8faa0 100644 --- a/src/main.ts +++ b/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(); + +let deskLight = new M433SwitchItem('Gnd', 'Hallway', 'DeskLight', '83221 24 1', '83220 24 1'); +deskLight.start(); -class Dispatcher { - constructor() { - logger.info("Dispatcher starting") - } +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(); - exec() : void { - logger.info("Hello world") +let testDimmerAdaptor = new DimmerAdaptor('Gnd', 'Hallway', 'Testlight'); +testDimmerAdaptor.start(); - - // mqttHandler.exec() - } -} - -const dispatcher = new Dispatcher() -dispatcher.exec() +mqttHandler.exec() +logger.info("Dispatcher running")