Compare commits
72 Commits
Typescript
...
GeoFences
Author | SHA1 | Date | |
---|---|---|---|
e6fe4a5ee9
|
|||
fca448a1ea
|
|||
82cb8d56cb
|
|||
f0d32b5a2b
|
|||
245002acad
|
|||
aad115f7b0
|
|||
b8dcece64e
|
|||
00ba130010
|
|||
dc28dc81b7
|
|||
a5c629e331
|
|||
c503e31ee5
|
|||
37acc620d5
|
|||
9db2aebf09 | |||
b9ac97f2df
|
|||
2e251fe3bc
|
|||
d6bde14e76
|
|||
8350b21161
|
|||
e883c9a791 | |||
d586ab6860 | |||
d0d7250d63 | |||
f444cb13e3 | |||
dfc4a04df0 | |||
cc930e6bbc
|
|||
4f2e74bddb
|
|||
656db81602
|
|||
166f958cac
|
|||
0d14933863
|
|||
ce78afaa55
|
|||
3179c84684
|
|||
0977223736
|
|||
bd4bced0c0
|
|||
71f00fdf31
|
|||
7992ccd7a1 | |||
e6a12e4215 | |||
9b4853501d | |||
6e35c1fe6c | |||
d27349833a | |||
bd0996b03b | |||
7ead49a67a | |||
a5d6791e88 | |||
f6db2369c3 | |||
a104b53509 | |||
48fe3be0e9 | |||
72516fac28 | |||
409ab71365 | |||
c4ab32a229 | |||
3002b01788 | |||
1e3823b2a5 | |||
3188efac5f | |||
b979969324 | |||
11c3def220 | |||
32a57408d9 | |||
1113924c57 | |||
4aa7335e54 | |||
c1242afd07 | |||
988840a947 | |||
8702cd8a40 | |||
1847db3934 | |||
72731b74b7 | |||
503790a73d | |||
f362c90b91 | |||
85cab38058 | |||
d87fceb73e | |||
9c0ac6dc3b | |||
09a63fe736 | |||
f88cf5ee0d | |||
677f9c807d | |||
e88f9d225c | |||
c474d22265 | |||
5eac6dfab6 | |||
402603c376 | |||
28eec19e53 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
node_modules
|
||||
*.map
|
||||
mylogfile.log
|
||||
dispatcher_ng.log
|
||||
|
@ -8,5 +8,12 @@
|
||||
"smtpSender": "dispatcher@hottis.de",
|
||||
"smtpReceiver": "woho@hottis.de",
|
||||
"homekitFile": "homekit.json",
|
||||
"openhabItemFile": "openhab.items"
|
||||
"openhabItemFile": "openhab.items",
|
||||
"geofencesPort": 8000,
|
||||
"occupants": {
|
||||
"386D105B-80D0-4708-95AB-77B4D1E36D0E": "Wolfgang",
|
||||
"E24E910A-ED0A-444E-8290-794339BC887C": "Matthias",
|
||||
"D7352171-FCF5-4E21-8FD3-8C34FF0F2F15": "Anna",
|
||||
"219117FF-B721-43E3-BE56-F77E8239705E": "Patty"
|
||||
}
|
||||
}
|
||||
|
14
dist/AHomegearItem.js
vendored
Normal file
14
dist/AHomegearItem.js
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const AItem_1 = require("./AItem");
|
||||
class AHomegearItem extends AItem_1.AItem {
|
||||
constructor(floor, room, item, label, hmId) {
|
||||
super(floor, room, item, label);
|
||||
this.hmId = hmId;
|
||||
this.homegearTopicPre = 'homegear/instance1';
|
||||
this.actionTopicPre = `${this.homegearTopicPre}/set/${this.hmId}`;
|
||||
this.deviceTopicPre = `${this.homegearTopicPre}/plain/${this.hmId}`;
|
||||
}
|
||||
}
|
||||
exports.AHomegearItem = AHomegearItem;
|
||||
//# sourceMappingURL=AHomegearItem.js.map
|
9
dist/AItem.js
vendored
9
dist/AItem.js
vendored
@ -1,13 +1,12 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const logger = require("./log");
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
class AItem {
|
||||
constructor(floor, room, item, label = '') {
|
||||
this.floor = floor;
|
||||
this.room = room;
|
||||
this.item = item;
|
||||
this.itemId = `${this.floor}.${this.room}.${this.item}`;
|
||||
this.itemId = `${this.floor}_${this.room}_${this.item}`;
|
||||
if (label == '') {
|
||||
this.label = this.itemId;
|
||||
}
|
||||
@ -16,14 +15,16 @@ class AItem {
|
||||
}
|
||||
this.topicFirstPart = `dispatcher_ng/items/${this.floor}/${this.room}/${this.item}`;
|
||||
}
|
||||
startFunc() {
|
||||
}
|
||||
exportItem() {
|
||||
return null;
|
||||
}
|
||||
start() {
|
||||
MqttDispatcher_1.mqttHandler.register(this.subscribeTopics, (topic, payload) => {
|
||||
logger.info(`item ${this.itemId}: ${topic}, ${payload}`);
|
||||
// logger.info(`item ${this.itemId}: ${topic}, ${payload}`)
|
||||
this.processMessage(topic, payload);
|
||||
});
|
||||
}, () => { this.startFunc(); });
|
||||
}
|
||||
}
|
||||
exports.AItem = AItem;
|
||||
|
23
dist/Cron.js
vendored
Normal file
23
dist/Cron.js
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const logger = require("./log");
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const cron = require("cron");
|
||||
class Cron {
|
||||
constructor(name, target, crontab) {
|
||||
this.name = name;
|
||||
this.targetTopic = target.getInTopic();
|
||||
this.crontab = crontab;
|
||||
}
|
||||
start() {
|
||||
this.crontab.forEach((cronEntry) => {
|
||||
logger.info(`Starting cronjob for: ${this.targetTopic}, ${cronEntry.output} at ${cronEntry.cronTime}`);
|
||||
cronEntry.cronJob = new cron.CronJob(cronEntry.cronTime, () => {
|
||||
logger.info(`Firing ${this.targetTopic}, ${cronEntry.output}`);
|
||||
MqttDispatcher_1.mqttHandler.send(this.targetTopic, cronEntry.output);
|
||||
}, undefined, true, 'Europe/Berlin');
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.Cron = Cron;
|
||||
//# sourceMappingURL=Cron.js.map
|
3
dist/DimmerAdaptor.js
vendored
3
dist/DimmerAdaptor.js
vendored
@ -13,6 +13,9 @@ class DimmerAdaptor extends AItem_1.AItem {
|
||||
this.bright = 100;
|
||||
this.brightDirection = -1;
|
||||
}
|
||||
getInTopic() {
|
||||
return this.inTopic;
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
switch (topic) {
|
||||
case this.inTopic:
|
||||
|
3
dist/Disabler.js
vendored
Normal file
3
dist/Disabler.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=Disabler.js.map
|
102
dist/Export.js
vendored
102
dist/Export.js
vendored
@ -16,6 +16,39 @@ function SwitchExport(itemId, label, stateTopic, stateFeedbackTopic, type) {
|
||||
return { 'homekit': homekitOut, 'openhab': openhabOut };
|
||||
}
|
||||
exports.SwitchExport = SwitchExport;
|
||||
function ThermostatExport(itemId, label, temperatureTopic, temperatureFeedbackTopic, presetTemperatureTopic, presetTemperatureFeedbackTopic) {
|
||||
return { 'homekit': ThermostatHomekitExport(itemId, label, temperatureTopic, temperatureFeedbackTopic), 'openhab': ThermostatOpenHAPExport(itemId, label, temperatureTopic, temperatureFeedbackTopic, presetTemperatureTopic, presetTemperatureFeedbackTopic) };
|
||||
}
|
||||
exports.ThermostatExport = ThermostatExport;
|
||||
function ContactExport(itemId, label, status) {
|
||||
return { 'homekit': ContactHomekitExport(itemId, label, status), 'openhab': ContactOpenHABExport(itemId, label, status) };
|
||||
}
|
||||
exports.ContactExport = ContactExport;
|
||||
function HueColorLightExport(itemId, label, stateTopic, stateFeedbackTopic, brightnessTopic, brightnessFeedbackTopic, hueTopic, hueFeedbackTopic, saturationTopic, saturationFeedbackTopic, colorTemperatureTopic, colorTemperatureFeedbackTopic) {
|
||||
return { 'homekit': HueColorLightHomekitExport(itemId, label, stateTopic, stateFeedbackTopic, brightnessTopic, brightnessFeedbackTopic, hueTopic, hueFeedbackTopic, saturationTopic, saturationFeedbackTopic, colorTemperatureTopic, colorTemperatureFeedbackTopic), 'openhab': '' };
|
||||
}
|
||||
exports.HueColorLightExport = HueColorLightExport;
|
||||
function RelayBoxExport(itemId, stateTopicPre, feedbackTopicPre, conflictTopicPre, itemNames) {
|
||||
return { 'homekit': RelayBoxHomekitExport(itemId, stateTopicPre, feedbackTopicPre, conflictTopicPre, itemNames),
|
||||
'openhab': RelayBoxOpenHABExport(itemId, stateTopicPre, feedbackTopicPre, conflictTopicPre, itemNames) };
|
||||
}
|
||||
exports.RelayBoxExport = RelayBoxExport;
|
||||
function HeatingMainSwitchExport(topic) {
|
||||
return { 'homekit': { 'id': '', 'object': {} },
|
||||
'openhab': `Switch HeatingMainSwitch "Heizung Hauptschalter" {mqtt=">[localbroker:${topic}:command:*:default],<[localbroker:${topic}:state:default]"}` };
|
||||
}
|
||||
exports.HeatingMainSwitchExport = HeatingMainSwitchExport;
|
||||
function RelayBoxHomekitExport(itemId, stateTopicPre, feedbackTopicPre, conflictTopicPre, itemNames) {
|
||||
return { 'id': '', 'object': {} };
|
||||
}
|
||||
function RelayBoxOpenHABExport(itemId, stateTopicPre, feedbackTopicPre, conflictTopicPre, itemNames) {
|
||||
let o = [];
|
||||
itemNames.forEach((label, index) => {
|
||||
o.push(`Switch ${itemId}${index} "${label}" {mqtt=">[localbroker:${stateTopicPre}/${index}:command:*:default],<[localbroker:${feedbackTopicPre}/${index}:state:default]"}`);
|
||||
o.push(`String ${itemId}${index}Conflict "${label} [%s]" {mqtt="<[localbroker:${conflictTopicPre}/${index}:state:default]"}`);
|
||||
});
|
||||
return o;
|
||||
}
|
||||
function SwitchHomekitBulbExport(id, label, setOn, statusOn) {
|
||||
let o = {
|
||||
"id": id,
|
||||
@ -53,8 +86,75 @@ function SwitchHomekitOutletExport(id, label, setOn, statusOn) {
|
||||
};
|
||||
return { 'id': id, 'object': o };
|
||||
}
|
||||
function ThermostatHomekitExport(id, label, setTemperature, statusTemperature) {
|
||||
let o = {
|
||||
"id": id,
|
||||
"name": label,
|
||||
"service": "Thermostat",
|
||||
"topic": {
|
||||
"setTargetTemperature": setTemperature,
|
||||
"statusTargetTemperature": statusTemperature,
|
||||
"statusCurrentTemperature": statusTemperature
|
||||
},
|
||||
"payload": {}
|
||||
};
|
||||
return { 'id': id, 'object': o };
|
||||
}
|
||||
function ContactHomekitExport(id, label, status) {
|
||||
let o = {
|
||||
"id": id,
|
||||
"name": label,
|
||||
"service": "ContactSensor",
|
||||
"topic": {
|
||||
"statusContactSensorState": status
|
||||
},
|
||||
"payload": {
|
||||
"onContactDetected": "CLOSED"
|
||||
}
|
||||
};
|
||||
return { 'id': id, 'object': o };
|
||||
}
|
||||
function SwitchOpenHABExport(id, label, setOn, statusOn) {
|
||||
// Switch windowLightKitchen {mqtt=">[localbroker:nodered/items/windowLightKitchen:command:*:default]", mqtt="<[localbroker:nodered/items/windowLightKitchen/feedback:state:default]"}
|
||||
return `Switch ${id} {mqtt=">[localbroker:${setOn}:command:*:default]", mqtt="<[localbroker:${statusOn}:state:default]"}`;
|
||||
return `Switch ${id} "${label}"{mqtt=">[localbroker:${setOn}:command:*:default],<[localbroker:${statusOn}:state:default]"}`;
|
||||
}
|
||||
function ContactOpenHABExport(id, label, status) {
|
||||
// Switch windowLightKitchen {mqtt=">[localbroker:nodered/items/windowLightKitchen:command:*:default]", mqtt="<[localbroker:nodered/items/windowLightKitchen/feedback:state:default]"}
|
||||
return `Contact ${id} "${label}" {mqtt="<[localbroker:${status}:state:default]"}`;
|
||||
}
|
||||
function ThermostatOpenHAPExport(id, label, setTemperature, statusTemperature, presetTemperature, presetStatusTemperature) {
|
||||
let o = [];
|
||||
o.push(`Number ${id} "${label} [%.1f °C]" {mqtt=">[localbroker:${setTemperature}:command:*:default],<[localbroker:${statusTemperature}:state:default]"}`);
|
||||
o.push(`Number Preset_${id} "Preset_${label} [%.1f °C]" {mqtt=">[localbroker:${presetTemperature}:command:*:default],<[localbroker:${presetStatusTemperature}:state:default]"}`);
|
||||
return o;
|
||||
}
|
||||
function HueColorLightHomekitExport(id, label, stateTopic, stateFeedbackTopic, brightnessTopic, brightnessFeedbackTopic, hueTopic, hueFeedbackTopic, saturationTopic, saturationFeedbackTopic, colorTemperatureTopic, colorTemperatureFeedbackTopic) {
|
||||
let o = {
|
||||
"id": id,
|
||||
"name": label,
|
||||
"service": "Lightbulb",
|
||||
"manufacturer": "hue2mqtt - Hue",
|
||||
"model": "color light",
|
||||
"topic": {
|
||||
"setOn": stateTopic,
|
||||
"statusOn": stateFeedbackTopic,
|
||||
"setBrightness": brightnessTopic,
|
||||
"statusBrightness": brightnessFeedbackTopic,
|
||||
"setHue": hueTopic,
|
||||
"statusHue": hueFeedbackTopic,
|
||||
"setSaturation": saturationTopic,
|
||||
"statusSaturation": saturationFeedbackTopic,
|
||||
"setColorTemperature": colorTemperatureTopic,
|
||||
"statusColorTemperature": colorTemperatureFeedbackTopic
|
||||
},
|
||||
"payload": {
|
||||
"onTrue": "ON",
|
||||
"onFalse": "OFF",
|
||||
"brightnessFactor": 1,
|
||||
"hueFactor": 1,
|
||||
"saturationFactor": 1
|
||||
}
|
||||
};
|
||||
return { 'id': id, 'object': o };
|
||||
}
|
||||
//# sourceMappingURL=Export.js.map
|
45
dist/GeoFences.js
vendored
Normal file
45
dist/GeoFences.js
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const express = require("express");
|
||||
const logger = require("./log");
|
||||
const bodyParser = require("body-parser");
|
||||
const config = require("./config");
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const events_1 = require("events");
|
||||
class GeoFences extends events_1.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
this.app = express();
|
||||
this.app.use(bodyParser.urlencoded({ extended: false }));
|
||||
this.app.use(bodyParser.json());
|
||||
this.attendanceSheet = {};
|
||||
}
|
||||
exec() {
|
||||
this.app.post('/', (req, res) => {
|
||||
const reqData = req.body;
|
||||
const deviceId = reqData.device;
|
||||
let occupantName = 'unknown';
|
||||
const location = reqData.name;
|
||||
if (deviceId in config.dict.occupants) {
|
||||
occupantName = config.dict.occupants[deviceId];
|
||||
}
|
||||
const presence = reqData.entry == '1';
|
||||
const direction = presence ? 'arrives at' : 'leaves from';
|
||||
logger.info(`${deviceId} (${occupantName}) ${direction} ${location}`);
|
||||
logger.info(JSON.stringify(reqData));
|
||||
res.send('OK');
|
||||
const state = presence ? 'present' : 'absent';
|
||||
MqttDispatcher_1.mqttHandler.send(`${GeoFences.geoFencesTopicPre}/${occupantName}`, state);
|
||||
this.attendanceSheet[occupantName] = presence;
|
||||
logger.info(`attendanceSheet is now ${JSON.stringify(this.attendanceSheet)}`);
|
||||
this.emit('change', this.attendanceSheet);
|
||||
});
|
||||
let port = parseInt(config.dict.geofencesPort);
|
||||
this.server = this.app.listen(port, '', () => {
|
||||
logger.info(`geofences server listening on ${port}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
GeoFences.geoFencesTopicPre = "dispatcher_ng/geofences";
|
||||
exports.GeoFences = GeoFences;
|
||||
//# sourceMappingURL=GeoFences.js.map
|
4
dist/HomematicDimmerItem.js
vendored
4
dist/HomematicDimmerItem.js
vendored
@ -2,8 +2,8 @@
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const logger = require("./log");
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AHomematicItem_1 = require("./AHomematicItem");
|
||||
class HomematicDimmerItem extends AHomematicItem_1.AHomematicItem {
|
||||
const AHomegearItem_1 = require("./AHomegearItem");
|
||||
class HomematicDimmerItem extends AHomegearItem_1.AHomegearItem {
|
||||
constructor(floor, room, item, label, hmId) {
|
||||
super(floor, room, item, label, hmId);
|
||||
this.stateTopic = `${this.topicFirstPart}/state`;
|
||||
|
4
dist/HomematicFourButtonThing.js
vendored
4
dist/HomematicFourButtonThing.js
vendored
@ -2,7 +2,7 @@
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const logger = require("./log");
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AHomematicItem_1 = require("./AHomematicItem");
|
||||
const AHomegearItem_1 = require("./AHomegearItem");
|
||||
class HomematicFourButtonSingleItem {
|
||||
constructor(actionTopic) {
|
||||
this.actionTopic = actionTopic;
|
||||
@ -26,7 +26,7 @@ class HomematicFourButtonSingleItem {
|
||||
}
|
||||
}
|
||||
exports.HomematicFourButtonSingleItem = HomematicFourButtonSingleItem;
|
||||
class HomematicFourButtonThing extends AHomematicItem_1.AHomematicItem {
|
||||
class HomematicFourButtonThing extends AHomegearItem_1.AHomegearItem {
|
||||
constructor(floor, room, item, hmId, itemObjs) {
|
||||
super(floor, room, item, '', hmId);
|
||||
this.itemObjs = itemObjs;
|
||||
|
10
dist/HomematicSwitchItem.js
vendored
10
dist/HomematicSwitchItem.js
vendored
@ -1,9 +1,15 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AHomematicItem_1 = require("./AHomematicItem");
|
||||
const AHomegearItem_1 = require("./AHomegearItem");
|
||||
const Export_1 = require("./Export");
|
||||
class HomematicSwitchItem extends AHomematicItem_1.AHomematicItem {
|
||||
class HomematicSwitchItem extends AHomegearItem_1.AHomegearItem {
|
||||
getStateTopic() {
|
||||
return this.stateTopic;
|
||||
}
|
||||
getStateFeedbackTopic() {
|
||||
return this.stateFeedbackTopic;
|
||||
}
|
||||
constructor(floor, room, item, label, hmId, type = 'bulb') {
|
||||
super(floor, room, item, label, hmId);
|
||||
this.stateTopic = `${this.topicFirstPart}/state`;
|
||||
|
124
dist/HueColorBulbItem.js
vendored
Normal file
124
dist/HueColorBulbItem.js
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AHomegearItem_1 = require("./AHomegearItem");
|
||||
const Export_1 = require("./Export");
|
||||
class HueColorBulbItem extends AHomegearItem_1.AHomegearItem {
|
||||
constructor(floor, room, item, label, hmId) {
|
||||
super(floor, room, item, label, hmId);
|
||||
this.BRIGHT_FACTOR = 2.54;
|
||||
this.HUE_FACTOR = (65535 / 360);
|
||||
this.SATURATION_FACTOR = 2.54;
|
||||
this.stateTopic = `${this.topicFirstPart}/state`;
|
||||
this.brightTopic = `${this.topicFirstPart}/bright`;
|
||||
this.colorTemperatureTopic = `${this.topicFirstPart}/colorTemperature`;
|
||||
this.hueTopic = `${this.topicFirstPart}/hue`;
|
||||
this.saturationTopic = `${this.topicFirstPart}/saturation`;
|
||||
this.stateFeedbackTopic = `${this.topicFirstPart}/state/feedback`;
|
||||
this.brightFeedbackTopic = `${this.topicFirstPart}/bright/feedback`;
|
||||
this.hueFeedbackTopic = `${this.topicFirstPart}/bright/hue`;
|
||||
this.saturationFeedbackTopic = `${this.topicFirstPart}/bright/saturation`;
|
||||
this.colorTemperatureFeedbackTopic = `${this.topicFirstPart}/colorTemperature/feedback`;
|
||||
this.stateActionTopic = `${this.actionTopicPre}/1/STATE`;
|
||||
this.brightActionTopic = `${this.actionTopicPre}/1/FAST_BRIGHTNESS`;
|
||||
this.hueActionTopic = `${this.actionTopicPre}/1/HUE`;
|
||||
this.saturationActionTopic = `${this.actionTopicPre}/1/SATURATION`;
|
||||
this.colorTemperatureActionTopic = `${this.actionTopicPre}/1/COLOR_TEMPERATURE`;
|
||||
this.stateDeviceTopic = `${this.deviceTopicPre}/1/STATE`;
|
||||
this.brightDeviceTopic = `${this.deviceTopicPre}/1/FAST_BRIGHTNESS`;
|
||||
this.hueDeviceTopic = `${this.deviceTopicPre}/1/HUE`;
|
||||
this.saturationDeviceTopic = `${this.deviceTopicPre}/1/SATURATION`;
|
||||
this.colorTemperatureDeviceTopic = `${this.deviceTopicPre}/1/COLOR_TEMPERATURE`;
|
||||
this.subscribeTopics = [
|
||||
this.stateTopic,
|
||||
this.brightTopic,
|
||||
this.colorTemperatureTopic,
|
||||
this.hueTopic,
|
||||
this.saturationTopic,
|
||||
this.stateDeviceTopic,
|
||||
this.brightDeviceTopic,
|
||||
this.colorTemperatureDeviceTopic,
|
||||
this.hueDeviceTopic,
|
||||
this.saturationDeviceTopic
|
||||
];
|
||||
this.state = 'OFF';
|
||||
this.bright = 0;
|
||||
this.colorTemperature = 0;
|
||||
this.hue = 0;
|
||||
this.saturation = 0;
|
||||
}
|
||||
getStateTopic() {
|
||||
return this.stateTopic;
|
||||
}
|
||||
getInTopic() {
|
||||
return this.stateTopic;
|
||||
}
|
||||
getStateFeedbackTopic() {
|
||||
return this.stateFeedbackTopic;
|
||||
}
|
||||
exportItem() {
|
||||
return Export_1.HueColorLightExport(this.itemId, this.label, this.stateTopic, this.stateFeedbackTopic, this.brightTopic, this.brightFeedbackTopic, this.hueTopic, this.hueFeedbackTopic, this.saturationTopic, this.saturationFeedbackTopic, this.colorTemperatureTopic, this.colorTemperatureFeedbackTopic);
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
switch (topic) {
|
||||
case this.stateTopic:
|
||||
this.state = payload;
|
||||
MqttDispatcher_1.mqttHandler.send(this.stateFeedbackTopic, this.state);
|
||||
if (this.state == "ON") {
|
||||
MqttDispatcher_1.mqttHandler.send(this.stateActionTopic, "true");
|
||||
}
|
||||
else {
|
||||
MqttDispatcher_1.mqttHandler.send(this.stateActionTopic, "false");
|
||||
}
|
||||
break;
|
||||
case this.stateDeviceTopic:
|
||||
this.state = payload;
|
||||
if (payload == "true") {
|
||||
this.state = "ON";
|
||||
}
|
||||
else {
|
||||
this.state = "OFF";
|
||||
}
|
||||
MqttDispatcher_1.mqttHandler.send(this.stateFeedbackTopic, this.state);
|
||||
break;
|
||||
case this.brightTopic:
|
||||
this.bright = parseFloat(payload);
|
||||
MqttDispatcher_1.mqttHandler.send(this.brightFeedbackTopic, `${this.bright}`);
|
||||
MqttDispatcher_1.mqttHandler.send(this.brightActionTopic, `${this.bright * this.BRIGHT_FACTOR}`);
|
||||
break;
|
||||
case this.brightDeviceTopic:
|
||||
this.bright = parseFloat(payload) / this.BRIGHT_FACTOR;
|
||||
MqttDispatcher_1.mqttHandler.send(this.brightFeedbackTopic, `${this.bright}`);
|
||||
break;
|
||||
case this.hueTopic:
|
||||
this.hue = parseFloat(payload);
|
||||
MqttDispatcher_1.mqttHandler.send(this.hueFeedbackTopic, `${this.hue}`);
|
||||
MqttDispatcher_1.mqttHandler.send(this.hueActionTopic, `${this.hue * this.HUE_FACTOR}`);
|
||||
break;
|
||||
case this.hueDeviceTopic:
|
||||
this.hue = parseFloat(payload) / this.HUE_FACTOR;
|
||||
MqttDispatcher_1.mqttHandler.send(this.hueFeedbackTopic, `${this.hue}`);
|
||||
break;
|
||||
case this.saturationTopic:
|
||||
this.saturation = parseFloat(payload);
|
||||
MqttDispatcher_1.mqttHandler.send(this.saturationFeedbackTopic, `${this.saturation}`);
|
||||
MqttDispatcher_1.mqttHandler.send(this.saturationActionTopic, `${this.saturation * this.SATURATION_FACTOR}`);
|
||||
break;
|
||||
case this.saturationDeviceTopic:
|
||||
this.saturation = parseFloat(payload) / this.SATURATION_FACTOR;
|
||||
MqttDispatcher_1.mqttHandler.send(this.saturationFeedbackTopic, `${this.saturation}`);
|
||||
break;
|
||||
case this.colorTemperatureTopic:
|
||||
this.colorTemperature = parseInt(payload);
|
||||
MqttDispatcher_1.mqttHandler.send(this.colorTemperatureFeedbackTopic, `${this.colorTemperature}`);
|
||||
MqttDispatcher_1.mqttHandler.send(this.colorTemperatureActionTopic, `${this.colorTemperature}`);
|
||||
break;
|
||||
case this.colorTemperatureDeviceTopic:
|
||||
this.colorTemperature = parseInt(payload);
|
||||
MqttDispatcher_1.mqttHandler.send(this.colorTemperatureFeedbackTopic, `${this.colorTemperature}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.HueColorBulbItem = HueColorBulbItem;
|
||||
//# sourceMappingURL=HueColorBulbItem.js.map
|
52
dist/HueColorTemperatureBulbItem.js
vendored
Normal file
52
dist/HueColorTemperatureBulbItem.js
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AHomegearItem_1 = require("./AHomegearItem");
|
||||
class HueColorTemperatureBulbItem extends AHomegearItem_1.AHomegearItem {
|
||||
constructor(floor, room, item, label, hmId) {
|
||||
super(floor, room, item, label, hmId);
|
||||
this.stateTopic = `${this.topicFirstPart}/state`;
|
||||
this.brightTopic = `${this.topicFirstPart}/bright`;
|
||||
this.colorTemperatureTopic = `${this.topicFirstPart}/colorTemperature`;
|
||||
this.stateFeedbackTopic = `${this.topicFirstPart}/state/feedback`;
|
||||
this.brightFeedbackTopic = `${this.topicFirstPart}/bright/feedback`;
|
||||
this.colorTemperatureFeedbackTopic = `${this.topicFirstPart}/colorTemperature/feedback`;
|
||||
this.stateActionTopic = `${this.actionTopicPre}/1/STATE`;
|
||||
this.brightActionTopic = `${this.actionTopicPre}/1/BRIGHTNESS`;
|
||||
this.colorTemperatureActionTopic = `${this.actionTopicPre}/1/COLOR_TEMPERATURE`;
|
||||
this.subscribeTopics = [
|
||||
this.stateTopic,
|
||||
this.brightTopic,
|
||||
this.colorTemperatureTopic
|
||||
];
|
||||
this.state = 'OFF';
|
||||
this.bright = 0;
|
||||
this.colorTemperature = 0;
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
switch (topic) {
|
||||
case this.stateTopic:
|
||||
this.state = payload;
|
||||
MqttDispatcher_1.mqttHandler.send(this.stateFeedbackTopic, this.state);
|
||||
if (this.state == "ON") {
|
||||
MqttDispatcher_1.mqttHandler.send(this.stateActionTopic, "true");
|
||||
}
|
||||
else {
|
||||
MqttDispatcher_1.mqttHandler.send(this.stateActionTopic, "false");
|
||||
}
|
||||
break;
|
||||
case this.brightTopic:
|
||||
this.bright = parseInt(payload);
|
||||
MqttDispatcher_1.mqttHandler.send(this.brightFeedbackTopic, `${this.bright}`);
|
||||
MqttDispatcher_1.mqttHandler.send(this.brightActionTopic, `${this.bright}`);
|
||||
break;
|
||||
case this.colorTemperatureTopic:
|
||||
this.colorTemperature = parseInt(payload);
|
||||
MqttDispatcher_1.mqttHandler.send(this.colorTemperatureFeedbackTopic, `${this.colorTemperature}`);
|
||||
MqttDispatcher_1.mqttHandler.send(this.colorTemperatureActionTopic, `${this.colorTemperature}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.HueColorTemperatureBulbItem = HueColorTemperatureBulbItem;
|
||||
//# sourceMappingURL=HueColorTemperatureBulbItem.js.map
|
9
dist/M433SwitchItem.js
vendored
9
dist/M433SwitchItem.js
vendored
@ -4,6 +4,15 @@ const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AItem_1 = require("./AItem");
|
||||
const Export_1 = require("./Export");
|
||||
class M433SwitchItem extends AItem_1.AItem {
|
||||
getStateTopic() {
|
||||
return this.stateTopic;
|
||||
}
|
||||
getInTopic() {
|
||||
return this.stateTopic;
|
||||
}
|
||||
getStateFeedbackTopic() {
|
||||
return this.stateFeedbackTopic;
|
||||
}
|
||||
constructor(floor, room, item, label, onCode, offCode, type = 'bulb') {
|
||||
super(floor, room, item, label);
|
||||
this.stateTopic = `${this.topicFirstPart}/state`;
|
||||
|
56
dist/MaxEcoSwitch.js
vendored
Normal file
56
dist/MaxEcoSwitch.js
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AHomegearItem_1 = require("./AHomegearItem");
|
||||
class MaxEcoSwitch extends AHomegearItem_1.AHomegearItem {
|
||||
constructor(floor, room, item, label, hmId, mainScene, ecoScene) {
|
||||
super(floor, room, item, label, hmId);
|
||||
this.mainButtonTopic = `${this.deviceTopicPre}/1/PRESS`;
|
||||
this.ecoButtonTopic = `${this.deviceTopicPre}/2/PRESS`;
|
||||
this.subscribeTopics = [this.mainButtonTopic, this.ecoButtonTopic];
|
||||
this.mainTopic = mainScene.getStateTopic();
|
||||
this.ecoTopic = ecoScene.getStateTopic();
|
||||
this.state = 'OFF';
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
switch (this.state) {
|
||||
case 'OFF':
|
||||
if (topic == this.mainButtonTopic) {
|
||||
this.state = 'ON';
|
||||
}
|
||||
else if (topic == this.ecoButtonTopic) {
|
||||
this.state = 'ECO';
|
||||
}
|
||||
break;
|
||||
case 'ON':
|
||||
if (topic == this.mainButtonTopic) {
|
||||
this.state = 'OFF';
|
||||
}
|
||||
else if (topic == this.ecoButtonTopic) {
|
||||
this.state = 'ECO';
|
||||
}
|
||||
break;
|
||||
case 'ECO':
|
||||
if (topic == this.mainButtonTopic) {
|
||||
this.state = 'ON';
|
||||
}
|
||||
else if (topic == this.ecoButtonTopic) {
|
||||
this.state = 'OFF';
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (this.state) {
|
||||
case 'OFF':
|
||||
MqttDispatcher_1.mqttHandler.send(this.mainTopic, 'OFF');
|
||||
break;
|
||||
case 'ON':
|
||||
MqttDispatcher_1.mqttHandler.send(this.mainTopic, 'ON');
|
||||
break;
|
||||
case 'ECO':
|
||||
MqttDispatcher_1.mqttHandler.send(this.ecoTopic, 'ON');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.MaxEcoSwitch = MaxEcoSwitch;
|
||||
//# sourceMappingURL=MaxEcoSwitch.js.map
|
107
dist/MaxThermostat.js
vendored
Normal file
107
dist/MaxThermostat.js
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const logger = require("./log");
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AHomegearItem_1 = require("./AHomegearItem");
|
||||
// import { MaxWindowContact } from './MaxWindowContact';
|
||||
const Export_1 = require("./Export");
|
||||
const DISABLED_TEMPERATURE = 5.0;
|
||||
class MaxThermostat extends AHomegearItem_1.AHomegearItem {
|
||||
constructor(floor, room, item, label, hmId, hardDisablers) {
|
||||
super(floor, room, item, label, hmId);
|
||||
this.heatingMainFlag = false;
|
||||
this.temperatureTopic = `${this.topicFirstPart}/temperature`;
|
||||
this.temperatureFeedbackTopic = `${this.topicFirstPart}/temperature/feedback`;
|
||||
this.presetTemperatureTopic = `${this.topicFirstPart}/presetTemperature`;
|
||||
this.presetTemperatureFeedbackTopic = `${this.topicFirstPart}/presetTemperature/feedback`;
|
||||
this.deviceFeedbackTopic = `${this.deviceTopicPre}/1/SET_TEMPERATURE`;
|
||||
this.actionTopic = `${this.actionTopicPre}/1/SET_TEMPERATURE`;
|
||||
this.commandTopic = `${this.topicFirstPart}/command`;
|
||||
this.subscribeTopics = [
|
||||
this.temperatureTopic,
|
||||
this.presetTemperatureTopic,
|
||||
this.deviceFeedbackTopic,
|
||||
this.commandTopic,
|
||||
MaxThermostat.heatingMainSwitchTopic
|
||||
];
|
||||
this.hardDisabled = false;
|
||||
this.hardDisablerMap = {};
|
||||
hardDisablers.forEach((hardDisabler) => {
|
||||
this.subscribeTopics.push(hardDisabler.getStateFeedbackTopic());
|
||||
this.hardDisablerMap[hardDisabler.getStateFeedbackTopic()] = { disabler: hardDisabler, state: 'unknown' };
|
||||
});
|
||||
}
|
||||
// Thermostat: homegear/instance1/set/3/1/SET_TEMPERATURE
|
||||
getInTopic() {
|
||||
return this.commandTopic;
|
||||
}
|
||||
exportItem() {
|
||||
return Export_1.ThermostatExport(this.itemId, this.label, this.temperatureTopic, this.temperatureFeedbackTopic, this.presetTemperatureTopic, this.presetTemperatureFeedbackTopic);
|
||||
}
|
||||
static exportHeatingMainSwitchItem() {
|
||||
return Export_1.HeatingMainSwitchExport(MaxThermostat.heatingMainSwitchTopic);
|
||||
}
|
||||
setPresetTemperature(presetTemperature) {
|
||||
this.presetTemperature = presetTemperature;
|
||||
}
|
||||
startFunc() {
|
||||
MqttDispatcher_1.mqttHandler.send(this.presetTemperatureTopic, `${this.presetTemperature}`);
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
let setTemperature = false;
|
||||
if (topic == this.temperatureTopic) {
|
||||
this.temperature = parseFloat(payload);
|
||||
setTemperature = true;
|
||||
}
|
||||
else if (topic == this.commandTopic) {
|
||||
if (this.heatingMainFlag) {
|
||||
if (payload == 'ON') {
|
||||
this.temperature = this.presetTemperature;
|
||||
}
|
||||
else if (payload == 'OFF') {
|
||||
this.temperature = DISABLED_TEMPERATURE;
|
||||
}
|
||||
setTemperature = true;
|
||||
}
|
||||
}
|
||||
else if (topic == MaxThermostat.heatingMainSwitchTopic) {
|
||||
this.heatingMainFlag = (payload == 'ON');
|
||||
logger.info(`${this.itemId} heating main: ${this.heatingMainFlag}`);
|
||||
if (!this.heatingMainFlag) {
|
||||
MqttDispatcher_1.mqttHandler.send(this.temperatureFeedbackTopic, `${DISABLED_TEMPERATURE}`);
|
||||
MqttDispatcher_1.mqttHandler.send(this.actionTopic, `${DISABLED_TEMPERATURE}`);
|
||||
}
|
||||
}
|
||||
else if (topic == this.presetTemperatureTopic) {
|
||||
this.presetTemperature = parseFloat(payload);
|
||||
MqttDispatcher_1.mqttHandler.send(this.presetTemperatureFeedbackTopic, `${this.presetTemperature}`);
|
||||
}
|
||||
else if (topic == this.deviceFeedbackTopic) {
|
||||
// this.temperature = parseFloat(payload)
|
||||
setTemperature = false;
|
||||
}
|
||||
else if (topic in this.hardDisablerMap) {
|
||||
this.hardDisablerMap[topic].state = this.hardDisablerMap[topic].disabler.transform(payload);
|
||||
this.hardDisabled = false;
|
||||
Object.values(this.hardDisablerMap).forEach((w) => {
|
||||
if (w.state == 'DISABLE') {
|
||||
this.hardDisabled = true;
|
||||
}
|
||||
});
|
||||
setTemperature = true;
|
||||
}
|
||||
if (setTemperature) {
|
||||
if (!this.hardDisabled) {
|
||||
MqttDispatcher_1.mqttHandler.send(this.temperatureFeedbackTopic, `${this.temperature}`);
|
||||
MqttDispatcher_1.mqttHandler.send(this.actionTopic, `${this.temperature}`);
|
||||
}
|
||||
else {
|
||||
MqttDispatcher_1.mqttHandler.send(this.temperatureFeedbackTopic, `${DISABLED_TEMPERATURE}`);
|
||||
MqttDispatcher_1.mqttHandler.send(this.actionTopic, `${DISABLED_TEMPERATURE}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MaxThermostat.heatingMainSwitchTopic = 'dispatcher_ng/items/heatingMainSwitch';
|
||||
exports.MaxThermostat = MaxThermostat;
|
||||
//# sourceMappingURL=MaxThermostat.js.map
|
47
dist/MaxWindowContact.js
vendored
Normal file
47
dist/MaxWindowContact.js
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AHomegearItem_1 = require("./AHomegearItem");
|
||||
const Export_1 = require("./Export");
|
||||
class MaxWindowContact extends AHomegearItem_1.AHomegearItem {
|
||||
getStateFeedbackTopic() {
|
||||
return this.stateFeedbackTopic;
|
||||
}
|
||||
transform(payload) {
|
||||
let res;
|
||||
if (payload == 'OPEN') {
|
||||
res = 'DISABLE';
|
||||
}
|
||||
else if (payload == 'CLOSED') {
|
||||
res = 'ENABLE';
|
||||
}
|
||||
else {
|
||||
res = 'UNKNOWN';
|
||||
}
|
||||
return res;
|
||||
}
|
||||
constructor(floor, room, item, label, hmId) {
|
||||
super(floor, room, item, label, hmId);
|
||||
this.stateTopic = `${this.topicFirstPart}/state`;
|
||||
this.stateFeedbackTopic = `${this.topicFirstPart}/state/feedback`;
|
||||
this.deviceFeedbackTopic = `${this.deviceTopicPre}/1/STATE`;
|
||||
this.subscribeTopics = [
|
||||
this.stateTopic,
|
||||
this.deviceFeedbackTopic
|
||||
];
|
||||
}
|
||||
exportItem() {
|
||||
return Export_1.ContactExport(this.itemId, this.label, this.stateFeedbackTopic);
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
if (payload == 'true') {
|
||||
this.state = 'OPEN';
|
||||
}
|
||||
else {
|
||||
this.state = 'CLOSED';
|
||||
}
|
||||
MqttDispatcher_1.mqttHandler.send(this.stateFeedbackTopic, this.state);
|
||||
}
|
||||
}
|
||||
exports.MaxWindowContact = MaxWindowContact;
|
||||
//# sourceMappingURL=MaxWindowContact.js.map
|
42
dist/MqttDispatcher.js
vendored
42
dist/MqttDispatcher.js
vendored
@ -17,13 +17,15 @@ class MqttHandler {
|
||||
this.mqttOptions.rejectUnauthorized = true;
|
||||
}
|
||||
this.topicHandlers = [];
|
||||
this.startCallbacks = [];
|
||||
logger.info("MqttHandler constructed");
|
||||
}
|
||||
register(topics, cb) {
|
||||
register(topics, cb, startCb) {
|
||||
topics.forEach((topic) => {
|
||||
this.topicHandlers.push({ topic: topic, callback: cb });
|
||||
logger.info(`Callback registered for ${topic}`);
|
||||
});
|
||||
this.startCallbacks.push(startCb);
|
||||
}
|
||||
exec() {
|
||||
logger.info(`Connecting to ${this.mqttBrokerUrl}`);
|
||||
@ -39,13 +41,17 @@ class MqttHandler {
|
||||
logger.info(`${topicHandler.topic} subscribed`);
|
||||
});
|
||||
logger.info('MQTT connection established');
|
||||
this.startCallbacks.forEach((cb) => {
|
||||
cb();
|
||||
logger.info("started");
|
||||
});
|
||||
});
|
||||
this.mqttClient.on('message', (topic, payload, packet) => {
|
||||
if (!packet.retain) {
|
||||
let payloadStr = payload.toString('UTF-8');
|
||||
logger.info(`Message received on topic ${topic}: ${payload}`);
|
||||
this.processMessage(topic, payloadStr);
|
||||
}
|
||||
// if (! packet.retain) {
|
||||
let payloadStr = payload.toString('UTF-8');
|
||||
// logger.info(`Message received on topic ${topic}: ${payload}`)
|
||||
this.processMessage(topic, payloadStr);
|
||||
// }
|
||||
});
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
@ -70,18 +76,18 @@ class MqttHandler {
|
||||
return found;
|
||||
}
|
||||
send(topic, payload, internalFirst = false) {
|
||||
let sent = false;
|
||||
if (internalFirst) {
|
||||
logger.info(`Try internal sending: ${topic}`);
|
||||
sent = this.processMessage(topic, payload);
|
||||
}
|
||||
if (!sent) {
|
||||
logger.info(`External sending required: ${topic}`);
|
||||
this.mqttClient.publish(topic, payload);
|
||||
}
|
||||
else {
|
||||
logger.info(`Internally delivered: ${topic}`);
|
||||
}
|
||||
//let sent = false
|
||||
//if (internalFirst) {
|
||||
// logger.info(`Try internal sending: ${topic}`)
|
||||
// sent = this.processMessage(topic, payload)
|
||||
//}
|
||||
//if (! sent) {
|
||||
logger.info(`External sending required: ${topic} ${payload}`);
|
||||
let options = { retain: true, qos: 0 };
|
||||
this.mqttClient.publish(topic, payload, options);
|
||||
//} else {
|
||||
// logger.info(`Internally delivered: ${topic}`)
|
||||
//}
|
||||
}
|
||||
}
|
||||
exports.mqttHandler = new MqttHandler();
|
||||
|
73
dist/RelayBox.js
vendored
Normal file
73
dist/RelayBox.js
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const logger = require("./log");
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AItem_1 = require("./AItem");
|
||||
const Export_1 = require("./Export");
|
||||
class RelayBoxThing extends AItem_1.AItem {
|
||||
constructor(floor, room, item, deviceCommandTopic, deviceStatusTopic, itemNames) {
|
||||
super(floor, room, item, '');
|
||||
this.itemNames = itemNames;
|
||||
this.deviceCommandTopic = deviceCommandTopic;
|
||||
this.deviceStatusTopic = deviceStatusTopic;
|
||||
this.stateTopicPre = `${this.topicFirstPart}/state`;
|
||||
this.feedbackTopicPre = `${this.topicFirstPart}/feedback`;
|
||||
this.conflictTopicPre = `${this.topicFirstPart}/conflict`;
|
||||
this.subscribeTopics = [
|
||||
`${this.deviceStatusTopic}`,
|
||||
`${this.stateTopicPre}/#`
|
||||
];
|
||||
this.oldSwitchStates = '';
|
||||
}
|
||||
exportItem() {
|
||||
return Export_1.RelayBoxExport(this.itemId, this.stateTopicPre, this.feedbackTopicPre, this.conflictTopicPre, this.itemNames);
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
// logger.info(`RT: ${topic}, ${payload}`)
|
||||
if (topic == this.deviceStatusTopic) {
|
||||
// logger.info(`RT: status received`)
|
||||
this.status = JSON.parse(payload);
|
||||
let statusParsed = JSON.stringify(this.status);
|
||||
this.switchStates = JSON.stringify(this.status.data.switchStates);
|
||||
if (this.switchStates != this.oldSwitchStates) {
|
||||
this.oldSwitchStates = this.switchStates;
|
||||
logger.info(`RT: status parsed: ${statusParsed}`);
|
||||
logger.info(`RT: device: ${this.status.metadata.device}`);
|
||||
logger.info(`RT: uptime: ${this.status.data.uptime}`);
|
||||
for (let i = 0; i < this.itemNames.length; i++) {
|
||||
if (this.status.data.switchStates[i].feedbackState == '0') {
|
||||
MqttDispatcher_1.mqttHandler.send(`${this.feedbackTopicPre}/${i}`, 'OFF');
|
||||
}
|
||||
else {
|
||||
MqttDispatcher_1.mqttHandler.send(`${this.feedbackTopicPre}/${i}`, 'ON');
|
||||
}
|
||||
if (this.status.data.switchStates[i].stateConflict == '0') {
|
||||
MqttDispatcher_1.mqttHandler.send(`${this.conflictTopicPre}/${i}`, 'CLEAR');
|
||||
}
|
||||
else {
|
||||
MqttDispatcher_1.mqttHandler.send(`${this.conflictTopicPre}/${i}`, 'CONFLICT');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger.info(`RT: ${topic}, ${payload}`);
|
||||
let thingRelatedPart = topic.substring(this.stateTopicPre.length + 1);
|
||||
let itemIdx = parseInt(thingRelatedPart);
|
||||
logger.info(`RT: pre: ${this.stateTopicPre}, thingRelatedPart: ${thingRelatedPart}, itemIdx: ${itemIdx}`);
|
||||
if (itemIdx >= 0 && itemIdx < this.itemNames.length) {
|
||||
if (payload == 'ON') {
|
||||
MqttDispatcher_1.mqttHandler.send(this.deviceCommandTopic, `switch ${itemIdx} on`);
|
||||
}
|
||||
else {
|
||||
MqttDispatcher_1.mqttHandler.send(this.deviceCommandTopic, `switch ${itemIdx} off`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger.warn(`RT: no handling available for ${topic}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.RelayBoxThing = RelayBoxThing;
|
||||
//# sourceMappingURL=RelayBox.js.map
|
91
dist/Scene.js
vendored
Normal file
91
dist/Scene.js
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const AItem_1 = require("./AItem");
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const Export_1 = require("./Export");
|
||||
class LightScene extends AItem_1.AItem {
|
||||
getStateTopic() {
|
||||
return this.stateTopic;
|
||||
}
|
||||
getStateFeedbackTopic() {
|
||||
return this.stateFeedbackTopic;
|
||||
}
|
||||
constructor(floor, room, item, label = '', onItems, offItems) {
|
||||
super(floor, room, item, label);
|
||||
this.onItems = onItems;
|
||||
this.offItems = offItems;
|
||||
this.stateTopic = `${this.topicFirstPart}/state`;
|
||||
this.stateFeedbackTopic = `${this.topicFirstPart}/state/feedback`;
|
||||
this.subscribeTopics = [];
|
||||
this.subscribeTopics.push(this.stateTopic);
|
||||
this.onFeedbackTopics = [];
|
||||
this.onTopics = [];
|
||||
this.onFeedbackMap = {};
|
||||
this.onItems.forEach((item) => {
|
||||
this.subscribeTopics.push(item.getStateFeedbackTopic());
|
||||
this.onFeedbackTopics.push(item.getStateFeedbackTopic());
|
||||
this.onTopics.push(item.getStateTopic());
|
||||
this.onFeedbackMap[item.getStateFeedbackTopic()] = '-';
|
||||
});
|
||||
this.offFeedbackTopics = [];
|
||||
this.offTopics = [];
|
||||
this.offFeedbackMap = {};
|
||||
this.offItems.forEach((item) => {
|
||||
this.subscribeTopics.push(item.getStateFeedbackTopic());
|
||||
this.offFeedbackTopics.push(item.getStateFeedbackTopic());
|
||||
this.offTopics.push(item.getStateTopic());
|
||||
this.offFeedbackMap[item.getStateFeedbackTopic()] = '-';
|
||||
});
|
||||
this.state = 'OFF';
|
||||
this.myLastFeedbackState = '-';
|
||||
}
|
||||
exportItem() {
|
||||
return Export_1.SwitchExport(this.itemId, this.label, this.stateTopic, this.stateFeedbackTopic, 'bulb');
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
if (topic == this.stateTopic) {
|
||||
this.state = payload;
|
||||
if (this.state == 'ON') {
|
||||
this.onTopics.forEach((topic2) => {
|
||||
MqttDispatcher_1.mqttHandler.send(topic2, 'ON');
|
||||
});
|
||||
this.offTopics.forEach((topic2) => {
|
||||
MqttDispatcher_1.mqttHandler.send(topic2, 'OFF');
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.onTopics.forEach((topic2) => {
|
||||
MqttDispatcher_1.mqttHandler.send(topic2, 'OFF');
|
||||
});
|
||||
this.offTopics.forEach((topic2) => {
|
||||
MqttDispatcher_1.mqttHandler.send(topic2, 'OFF');
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (this.onFeedbackTopics.some((x) => { return x == topic; })) {
|
||||
let feedbackState = payload;
|
||||
this.onFeedbackMap[topic] = feedbackState;
|
||||
}
|
||||
else if (this.offFeedbackTopics.some((x) => { return x == topic; })) {
|
||||
let feedbackState = payload;
|
||||
this.offFeedbackMap[topic] = feedbackState;
|
||||
}
|
||||
let myFeedbackState = 'ON';
|
||||
Object.values(this.onFeedbackMap).forEach((v) => {
|
||||
if (v != 'ON') {
|
||||
myFeedbackState = 'OFF';
|
||||
}
|
||||
});
|
||||
Object.values(this.offFeedbackMap).forEach((v) => {
|
||||
if (v != 'OFF') {
|
||||
myFeedbackState = 'OFF';
|
||||
}
|
||||
});
|
||||
if (myFeedbackState != this.myLastFeedbackState) {
|
||||
MqttDispatcher_1.mqttHandler.send(this.stateFeedbackTopic, myFeedbackState);
|
||||
this.myLastFeedbackState = myFeedbackState;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.LightScene = LightScene;
|
||||
//# sourceMappingURL=Scene.js.map
|
52
dist/TouchSwitchMultiButtonThing.js
vendored
Normal file
52
dist/TouchSwitchMultiButtonThing.js
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const logger = require("./log");
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AItem_1 = require("./AItem");
|
||||
class TouchSwitchButtonSingleItem {
|
||||
constructor(actionTopic) {
|
||||
this.actionTopic = actionTopic;
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
switch (payload) {
|
||||
case 'SHORT':
|
||||
MqttDispatcher_1.mqttHandler.send(this.actionTopic, 'SHORT', true);
|
||||
break;
|
||||
case 'LONG_BEGIN':
|
||||
case 'LONG_CONT':
|
||||
MqttDispatcher_1.mqttHandler.send(this.actionTopic, 'LONG_HOLD', true);
|
||||
break;
|
||||
case 'LONG_END':
|
||||
MqttDispatcher_1.mqttHandler.send(this.actionTopic, 'LONG_END', true);
|
||||
break;
|
||||
default:
|
||||
logger.warn(`TWBSI: no handling available for ${topic}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.TouchSwitchButtonSingleItem = TouchSwitchButtonSingleItem;
|
||||
class TouchSwitchMultiButtonThing extends AItem_1.AItem {
|
||||
constructor(floor, room, item, itemObjs) {
|
||||
super(floor, room, item, '');
|
||||
this.itemObjs = itemObjs;
|
||||
this.deviceTopicPre = `IoT/TouchSwitch/${this.floor}/${this.room}/${this.item}`;
|
||||
this.subscribeTopics = [
|
||||
`${this.deviceTopicPre}/#`
|
||||
];
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
logger.info(`TSMBT: ${topic}, ${payload}`);
|
||||
let buttonRelatedPart = topic.substring(this.deviceTopicPre.length + 1);
|
||||
let buttonIdx = parseInt(buttonRelatedPart);
|
||||
logger.info(`TSMBT: pre: ${this.deviceTopicPre}, buttonRelatedPart: ${buttonRelatedPart}, buttonIdx: ${buttonIdx}`);
|
||||
if (buttonIdx >= 1 && buttonIdx <= this.itemObjs.length) {
|
||||
this.itemObjs[buttonIdx - 1].processMessage('-', payload);
|
||||
}
|
||||
else {
|
||||
logger.warn(`TSMBT: no handling available for ${topic}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.TouchSwitchMultiButtonThing = TouchSwitchMultiButtonThing;
|
||||
//# sourceMappingURL=TouchSwitchMultiButtonThing.js.map
|
44
dist/UrlSwitchItem.js
vendored
Normal file
44
dist/UrlSwitchItem.js
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const MqttDispatcher_1 = require("./MqttDispatcher");
|
||||
const AItem_1 = require("./AItem");
|
||||
const Export_1 = require("./Export");
|
||||
const http = require("http");
|
||||
class UrlSwitchItem extends AItem_1.AItem {
|
||||
getStateTopic() {
|
||||
return this.stateTopic;
|
||||
}
|
||||
getStateFeedbackTopic() {
|
||||
return this.stateFeedbackTopic;
|
||||
}
|
||||
constructor(floor, room, item, label, onUrl, offUrl, type = 'bulb') {
|
||||
super(floor, room, item, label);
|
||||
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.onUrl = onUrl;
|
||||
this.offUrl = offUrl;
|
||||
this.type = type;
|
||||
}
|
||||
exportItem() {
|
||||
return Export_1.SwitchExport(this.itemId, this.label, this.stateTopic, this.stateFeedbackTopic, this.type);
|
||||
}
|
||||
processMessage(topic, payload) {
|
||||
this.state = payload;
|
||||
MqttDispatcher_1.mqttHandler.send(this.stateFeedbackTopic, this.state);
|
||||
if (this.state != this.oldState) {
|
||||
if (this.state == 'ON') {
|
||||
http.get(this.onUrl);
|
||||
}
|
||||
else {
|
||||
http.get(this.offUrl);
|
||||
}
|
||||
this.oldState = this.state;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.UrlSwitchItem = UrlSwitchItem;
|
||||
//# sourceMappingURL=UrlSwitchItem.js.map
|
223
dist/main.js
vendored
223
dist/main.js
vendored
@ -11,6 +11,16 @@ const TimerAdaptor_1 = require("./TimerAdaptor");
|
||||
const HomematicDimmerItem_1 = require("./HomematicDimmerItem");
|
||||
const HomematicSwitchItem_1 = require("./HomematicSwitchItem");
|
||||
const Forwarder_1 = require("./Forwarder");
|
||||
const Scene_1 = require("./Scene");
|
||||
const MaxEcoSwitch_1 = require("./MaxEcoSwitch");
|
||||
const MaxThermostat_1 = require("./MaxThermostat");
|
||||
const MaxWindowContact_1 = require("./MaxWindowContact");
|
||||
const UrlSwitchItem_1 = require("./UrlSwitchItem");
|
||||
const Cron_1 = require("./Cron");
|
||||
const HueColorBulbItem_1 = require("./HueColorBulbItem");
|
||||
const TouchSwitchMultiButtonThing_1 = require("./TouchSwitchMultiButtonThing");
|
||||
const RelayBox_1 = require("./RelayBox");
|
||||
const GeoFences_1 = require("./GeoFences");
|
||||
logger.info("Dispatcher starting");
|
||||
let allLabeledItems = new Array();
|
||||
// Anna -----------------------------------------------------------------------------------------------------
|
||||
@ -18,13 +28,39 @@ let allLabeledItems = new Array();
|
||||
let aquariumLight = new M433SwitchItem_1.M433SwitchItem('1st', 'Anna', 'AquariumLight', 'Aquariumlicht', '14665044 24 1', '14665041 24 1');
|
||||
aquariumLight.start();
|
||||
allLabeledItems.push(aquariumLight);
|
||||
let aquariumLightCron = new Cron_1.Cron('aquariumLightCron', aquariumLight, [
|
||||
{ cronTime: '00 00 07 * * 1-5', output: 'ON' },
|
||||
{ cronTime: '00 00 09 * * 6,0', output: 'ON' },
|
||||
{ cronTime: '00 00 13 * * *', output: 'OFF' },
|
||||
{ cronTime: '00 00 14 * * *', output: 'ON' },
|
||||
{ cronTime: '00 00 22 * * *', output: 'OFF' }
|
||||
]);
|
||||
aquariumLightCron.start();
|
||||
// Anna Bett 14668116 24 1 14668113 24 1
|
||||
let annaBedLight = new M433SwitchItem_1.M433SwitchItem('1st', 'Anna', 'BedLight', 'Bettlicht Anna', '14668116 24 1', '14668113 24 1');
|
||||
annaBedLight.start();
|
||||
allLabeledItems.push(annaBedLight);
|
||||
let windowContactAnna1st = new MaxWindowContact_1.MaxWindowContact('1st', 'Anna', 'WindowContact', 'Fenster Anna', 20);
|
||||
windowContactAnna1st.start();
|
||||
allLabeledItems.push(windowContactAnna1st);
|
||||
let thermostatAnna1st = new MaxThermostat_1.MaxThermostat('1st', 'Anna', 'Thermostat', 'Thermostat Anna', 21, [windowContactAnna1st]);
|
||||
thermostatAnna1st.start();
|
||||
thermostatAnna1st.setPresetTemperature(21.0);
|
||||
allLabeledItems.push(thermostatAnna1st);
|
||||
let thermostatAnna1stCron = new Cron_1.Cron('thermostatAnna1stCron', thermostatAnna1st, [
|
||||
{ cronTime: '00 05 06 * * *', output: 'ON' },
|
||||
{ cronTime: '00 05 08 * * 1-5', output: 'OFF' },
|
||||
{ cronTime: '00 05 16 * * 1', output: 'ON' },
|
||||
{ cronTime: '00 05 14 * * 2', output: 'ON' },
|
||||
{ cronTime: '00 05 14 * * 3', output: 'ON' },
|
||||
{ cronTime: '00 05 16 * * 4', output: 'ON' },
|
||||
{ cronTime: '00 05 14 * * 5', output: 'ON' },
|
||||
{ cronTime: '00 58 23 * * *', output: 'OFF' }
|
||||
]);
|
||||
thermostatAnna1stCron.start();
|
||||
// Matthias -------------------------------------------------------------------------------------------------
|
||||
// Matthias Stehlampen 7 24 1 6 24 1
|
||||
let matthiasStandLights = new M433SwitchItem_1.M433SwitchItem('1st', 'Matthias', 'Stehlampen Matthias', 'StandLight', '7 24 1', '6 24 1');
|
||||
let matthiasStandLights = new M433SwitchItem_1.M433SwitchItem('1st', 'Matthias', 'StandLight', 'Stehlampen Matthias', '7 24 1', '6 24 1');
|
||||
matthiasStandLights.start();
|
||||
allLabeledItems.push(matthiasStandLights);
|
||||
// Matthias Bett 15 24 1 14 24 1
|
||||
@ -48,6 +84,13 @@ allLabeledItems.push(diningRoomStandLight);
|
||||
let diningRoomCupboardLight = new M433SwitchItem_1.M433SwitchItem('Gnd', 'DiningRoom', 'CupboardLight', 'Schranklicht Esszimmer', '65813 24 1', '65812 24 1');
|
||||
diningRoomCupboardLight.start();
|
||||
allLabeledItems.push(diningRoomCupboardLight);
|
||||
// Esszimmer Regallicht
|
||||
let diningRoomShelfLight = new UrlSwitchItem_1.UrlSwitchItem('Gnd', 'DiningRoom', 'ShelfLight', 'Regallicht Esszimmer', 'http://regallampe/dv?dv=1023', 'http://regallampe/dv?dv=0');
|
||||
diningRoomShelfLight.start();
|
||||
allLabeledItems.push(diningRoomShelfLight);
|
||||
let diningRoomNaehkaestchenLight = new HueColorBulbItem_1.HueColorBulbItem('Gnd', 'DiningRoom', 'NaehkaestchenLight', 'Lampe Naehkaestchen', 15);
|
||||
diningRoomNaehkaestchenLight.start();
|
||||
allLabeledItems.push(diningRoomNaehkaestchenLight);
|
||||
// Wohnzimmer -----------------------------------------------------------------------------------------------
|
||||
// Wohnzimmer grosse Lampe 65557 24 1 65556 24 1
|
||||
let livingRoomLargeLight = new M433SwitchItem_1.M433SwitchItem('Gnd', 'LivingRoom', 'LargeLight', 'große Lampe Wohnzimmer', '65557 24 1', '65556 24 1');
|
||||
@ -92,6 +135,13 @@ allLabeledItems.push(kitchenCeilingLight);
|
||||
let bedRoomWolfgangsSide = new M433SwitchItem_1.M433SwitchItem('1st', 'BedRoom', 'WolfgangsSide', 'Wolfgangs Seite Schlafzimmer', '13976916 24 1', '13976913 24 1');
|
||||
bedRoomWolfgangsSide.start();
|
||||
allLabeledItems.push(bedRoomWolfgangsSide);
|
||||
let bedRoomWolfgangBedLight = new HueColorBulbItem_1.HueColorBulbItem('1st', 'BedRoom', 'WolfgangBedLight', 'Bettlicht', 16);
|
||||
bedRoomWolfgangBedLight.start();
|
||||
allLabeledItems.push(bedRoomWolfgangBedLight);
|
||||
let bedRoomWolfgangBedLightDimmerAdaptor = new DimmerAdaptor_1.DimmerAdaptor('1st', 'BedRoom', 'WolfgangBedLight');
|
||||
bedRoomWolfgangBedLightDimmerAdaptor.start();
|
||||
let touchSwitchMultiButtonThing = new TouchSwitchMultiButtonThing_1.TouchSwitchMultiButtonThing('1st', 'Bedroom', 'Wolfgang', [new TouchSwitchMultiButtonThing_1.TouchSwitchButtonSingleItem(bedRoomWolfgangBedLightDimmerAdaptor.getInTopic())]);
|
||||
touchSwitchMultiButtonThing.start();
|
||||
// Schlafzimmer Pattys Seite 13980756 24 1 13980753 24 1
|
||||
let bedRoomPattysSide = new M433SwitchItem_1.M433SwitchItem('1st', 'BedRoom', 'PattysSide', 'Pattys Seite Schlafzimmer', '13980756 24 1', '13980753 24 1');
|
||||
bedRoomPattysSide.start();
|
||||
@ -100,41 +150,130 @@ allLabeledItems.push(bedRoomPattysSide);
|
||||
let bedRoomWindowLight = new M433SwitchItem_1.M433SwitchItem('1st', 'BedRoom', 'WindowLight', 'Fensterbanklicht Schlafzimmer', '13979988 24 1', '13979985 24 1');
|
||||
bedRoomWindowLight.start();
|
||||
allLabeledItems.push(bedRoomWindowLight);
|
||||
let windowContactBedroomStreet1st = new MaxWindowContact_1.MaxWindowContact('1st', 'Bedroom', 'WindowContactStreet', 'Fenster Schlafzimmer Strasse', 17);
|
||||
windowContactBedroomStreet1st.start();
|
||||
allLabeledItems.push(windowContactBedroomStreet1st);
|
||||
let windowContact1BedroomGarden1st = new MaxWindowContact_1.MaxWindowContact('1st', 'Bedroom', 'WindowContact1Garden', 'Fenster Schlafzimmer 1 Garten', 18);
|
||||
windowContact1BedroomGarden1st.start();
|
||||
allLabeledItems.push(windowContact1BedroomGarden1st);
|
||||
let windowContact2BedroomGarden1st = new MaxWindowContact_1.MaxWindowContact('1st', 'Bedroom', 'WindowContact2Garden', 'Fenster Schlafzimmer 2 Garten', 22);
|
||||
windowContact2BedroomGarden1st.start();
|
||||
allLabeledItems.push(windowContact2BedroomGarden1st);
|
||||
let thermostatBedroom1st = new MaxThermostat_1.MaxThermostat('1st', 'Bedroom', 'Thermostat', 'Thermostat Schlafzimmer', 19, [windowContact1BedroomGarden1st, windowContact2BedroomGarden1st, windowContactBedroomStreet1st]);
|
||||
thermostatBedroom1st.start();
|
||||
thermostatBedroom1st.setPresetTemperature(20.0);
|
||||
allLabeledItems.push(thermostatBedroom1st);
|
||||
let thermostatBedroom1stCron = new Cron_1.Cron('thermostatBedroom1stCron', thermostatBedroom1st, [
|
||||
{ cronTime: '00 01 06 * * 1-5', output: 'ON' },
|
||||
{ cronTime: '00 01 09 * * 1-5', output: 'OFF' },
|
||||
{ cronTime: '00 01 08 * * 6,0', output: 'ON' },
|
||||
{ cronTime: '00 01 11 * * 6,0', output: 'OFF' },
|
||||
{ cronTime: '00 00 17 * * *', output: 'ON' },
|
||||
{ cronTime: '00 59 23 * * *', output: 'OFF' }
|
||||
]);
|
||||
thermostatBedroom1stCron.start();
|
||||
// ---------------------------------------------------------------------------------------------------------
|
||||
let morningLightForwarder = new Forwarder_1.Forwarder('Gnd', 'Hallway', 'MorningLight', 'state', 'MorningLight', [
|
||||
kitchenWindowLight.stateTopic,
|
||||
kitchenCeilingLight.stateTopic,
|
||||
hallwayDeskLight.stateTopic,
|
||||
hallwayStandLight.stateTopic,
|
||||
hallwayWardrobeLight.stateTopic
|
||||
let dayLightScene = new Scene_1.LightScene('Gnd', 'Hallway', 'DayLight', 'DayLight', [
|
||||
kitchenWindowLight, kitchenCeilingLight, hallwayDeskLight, hallwayStandLight, hallwayWardrobeLight,
|
||||
diningRoomSmallLight, diningRoomStandLight, diningRoomCupboardLight, diningRoomShelfLight,
|
||||
livingRoomLargeLight, livingRoomSmallLight, livingRoomStars, livingRoomStandLight, diningRoomNaehkaestchenLight
|
||||
], []);
|
||||
dayLightScene.start();
|
||||
allLabeledItems.push(dayLightScene);
|
||||
let ecoLightScene = new Scene_1.LightScene('Gnd', 'Hallway', 'EcoLight', 'EcoLight', [
|
||||
kitchenWindowLight, hallwayDeskLight, hallwayWardrobeLight,
|
||||
diningRoomSmallLight, diningRoomStandLight, diningRoomCupboardLight, diningRoomShelfLight,
|
||||
livingRoomStars, livingRoomStandLight, diningRoomNaehkaestchenLight
|
||||
], [
|
||||
kitchenCeilingLight, hallwayStandLight,
|
||||
livingRoomLargeLight, livingRoomSmallLight
|
||||
]);
|
||||
morningLightForwarder.start();
|
||||
let dayLightForwarder = new Forwarder_1.Forwarder('Gnd', 'Hallway', 'DayLight', 'state', 'DayLight', [
|
||||
kitchenWindowLight.stateTopic,
|
||||
kitchenCeilingLight.stateTopic,
|
||||
hallwayDeskLight.stateTopic,
|
||||
hallwayStandLight.stateTopic,
|
||||
hallwayWardrobeLight.stateTopic,
|
||||
diningRoomSmallLight.stateTopic,
|
||||
diningRoomStandLight.stateTopic,
|
||||
diningRoomCupboardLight.stateTopic,
|
||||
livingRoomLargeLight.stateTopic,
|
||||
livingRoomSmallLight.stateTopic,
|
||||
livingRoomStars.stateTopic,
|
||||
livingRoomStandLight.stateTopic
|
||||
ecoLightScene.start();
|
||||
allLabeledItems.push(ecoLightScene);
|
||||
let ecoSwitch = new MaxEcoSwitch_1.MaxEcoSwitch('Gnd', 'Hallway', 'EcoSwitch', 'EcoSwitch', 6, dayLightScene, ecoLightScene);
|
||||
ecoSwitch.start();
|
||||
let morningLightScene = new Scene_1.LightScene('Gnd', 'Hallway', 'MorningLight', 'MorningLight', [
|
||||
kitchenWindowLight, kitchenCeilingLight, hallwayDeskLight, hallwayWardrobeLight,
|
||||
hallwayStandLight
|
||||
], [
|
||||
diningRoomSmallLight, diningRoomStandLight, diningRoomCupboardLight, diningRoomShelfLight,
|
||||
livingRoomStars, livingRoomStandLight, livingRoomLargeLight, livingRoomSmallLight, diningRoomNaehkaestchenLight
|
||||
]);
|
||||
dayLightForwarder.start();
|
||||
let ecoLightForwarder = new Forwarder_1.Forwarder('Gnd', 'Hallway', 'EcoLight', 'state', 'EcoLight', [
|
||||
kitchenWindowLight.stateTopic,
|
||||
hallwayDeskLight.stateTopic,
|
||||
hallwayWardrobeLight.stateTopic,
|
||||
diningRoomSmallLight.stateTopic,
|
||||
diningRoomStandLight.stateTopic,
|
||||
diningRoomCupboardLight.stateTopic,
|
||||
livingRoomStars.stateTopic,
|
||||
livingRoomStandLight.stateTopic
|
||||
morningLightScene.start();
|
||||
allLabeledItems.push(morningLightScene);
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
let windowContactBathroomGnd = new MaxWindowContact_1.MaxWindowContact('Gnd', 'Bathroom', 'WindowContact', 'Fenster Bad unten', 7);
|
||||
windowContactBathroomGnd.start();
|
||||
allLabeledItems.push(windowContactBathroomGnd);
|
||||
let thermostatBathroomGnd = new MaxThermostat_1.MaxThermostat('Gnd', 'Bathroom', 'Thermostat', 'Thermostat Bad unten', 4, [windowContactBathroomGnd]);
|
||||
thermostatBathroomGnd.start();
|
||||
thermostatBathroomGnd.setPresetTemperature(20.0);
|
||||
allLabeledItems.push(thermostatBathroomGnd);
|
||||
let thermostatBathroomGndCron = new Cron_1.Cron('thermostatBathroomGndCron', thermostatBathroomGnd, [
|
||||
{ cronTime: '00 02 06 * * 1-5', output: 'ON' },
|
||||
{ cronTime: '00 02 08 * * 6,0', output: 'ON' },
|
||||
{ cronTime: '00 02 11 * * *', output: 'OFF' },
|
||||
{ cronTime: '00 02 19 * * *', output: 'ON' },
|
||||
{ cronTime: '00 00 23 * * *', output: 'OFF' }
|
||||
]);
|
||||
ecoLightForwarder.start();
|
||||
thermostatBathroomGndCron.start();
|
||||
let windowContactBathroom1st = new MaxWindowContact_1.MaxWindowContact('1st', 'Bathroom', 'WindowContact', 'Fenster Bad oben', 2);
|
||||
windowContactBathroom1st.start();
|
||||
allLabeledItems.push(windowContactBathroom1st);
|
||||
let thermostatBathroom1st = new MaxThermostat_1.MaxThermostat('1st', 'Bathroom', 'Thermostat', 'Thermostat Bad oben', 3, [windowContactBathroom1st]);
|
||||
thermostatBathroom1st.start();
|
||||
thermostatBathroom1st.setPresetTemperature(20.0);
|
||||
allLabeledItems.push(thermostatBathroom1st);
|
||||
let thermostatBathroom1stCron = new Cron_1.Cron('thermostatBathroom1stCron', thermostatBathroom1st, [
|
||||
{ cronTime: '00 00 06 * * 1-5', output: 'ON' },
|
||||
{ cronTime: '00 00 08 * * 6,0', output: 'ON' },
|
||||
{ cronTime: '00 00 11 * * *', output: 'OFF' },
|
||||
{ cronTime: '00 00 19 * * *', output: 'ON' },
|
||||
{ cronTime: '00 00 23 * * *', output: 'OFF' }
|
||||
]);
|
||||
thermostatBathroom1stCron.start();
|
||||
let windowContactKitchen1 = new MaxWindowContact_1.MaxWindowContact('Gnd', 'Kitchen', 'WindowContact1', 'Fenster Küche Garten', 11);
|
||||
windowContactKitchen1.start();
|
||||
allLabeledItems.push(windowContactKitchen1);
|
||||
let windowContactKitchen2 = new MaxWindowContact_1.MaxWindowContact('Gnd', 'Kitchen', 'WindowContact2', 'Fenster Küche Terassentür Garten', 10);
|
||||
windowContactKitchen2.start();
|
||||
allLabeledItems.push(windowContactKitchen2);
|
||||
let windowContactKitchen3 = new MaxWindowContact_1.MaxWindowContact('Gnd', 'Kitchen', 'WindowContact3', 'Fenster Küche Straße 1', 12);
|
||||
windowContactKitchen3.start();
|
||||
allLabeledItems.push(windowContactKitchen3);
|
||||
let windowContactKitchen4 = new MaxWindowContact_1.MaxWindowContact('Gnd', 'Kitchen', 'WindowContact4', 'Fenster Küche Straße 2', 13);
|
||||
windowContactKitchen4.start();
|
||||
allLabeledItems.push(windowContactKitchen4);
|
||||
let thermostatKitchen = new MaxThermostat_1.MaxThermostat('Gnd', 'Kitchen', 'Thermostat', 'Thermostat Küche', 14, [
|
||||
windowContactKitchen1, windowContactKitchen2, windowContactKitchen3, windowContactKitchen4
|
||||
]);
|
||||
thermostatKitchen.start();
|
||||
thermostatKitchen.setPresetTemperature(20.0);
|
||||
allLabeledItems.push(thermostatKitchen);
|
||||
let thermostatKitchenCron = new Cron_1.Cron('thermostatKitchenCron', thermostatKitchen, [
|
||||
{ cronTime: '00 00 06 * * 1-5', output: 'ON' },
|
||||
{ cronTime: '00 00 08 * * 6,0', output: 'ON' },
|
||||
{ cronTime: '00 00 10 * * 1-3', output: 'OFF' },
|
||||
{ cronTime: '00 30 13 * * 1-3', output: 'ON' },
|
||||
{ cronTime: '00 00 23 * * *', output: 'OFF' }
|
||||
]);
|
||||
thermostatKitchenCron.start();
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
let windowContactFrontdoor = new MaxWindowContact_1.MaxWindowContact('Gnd', 'Hallway', 'FrontdoorContact', 'Haustür', 23);
|
||||
windowContactFrontdoor.start();
|
||||
allLabeledItems.push(windowContactFrontdoor);
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
let relayBox = new RelayBox_1.RelayBoxThing('base', 'labor', 'relaybox', 'IoT/Command/RelayBox', 'IoT/Status/RelayBox', [
|
||||
"Küche", "Herd", "Waschküche"
|
||||
]);
|
||||
relayBox.start();
|
||||
allLabeledItems.push(relayBox);
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
let geoFences = new GeoFences_1.GeoFences();
|
||||
geoFences.exec();
|
||||
geoFences.on('change', (attendanceSheet) => {
|
||||
logger.info(`geoFences change event: ${JSON.stringify(attendanceSheet)}`);
|
||||
});
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
let testFourButton = new HomematicFourButtonThing_1.HomematicFourButtonThing('Gnd', 'Hallway', 'TestButton', 9, [
|
||||
new HomematicFourButtonThing_1.HomematicFourButtonSingleItem('dispatcher_ng/items/Gnd/Hallway/Testlight/dimmerIn'),
|
||||
@ -156,19 +295,37 @@ let testForwarder = new Forwarder_1.Forwarder('Gnd', 'Hallway', 'TestForwarder',
|
||||
'dispatcher_ng/items/Gnd/Hallway/DeskLight/state'
|
||||
]);
|
||||
testForwarder.start();
|
||||
let testScene = new Scene_1.LightScene('Gnd', 'Hallway', 'TestScene', 'TestScene', [aquariumLight, annaBedLight], [matthiasStandLights, matthiasBedLight]);
|
||||
testScene.start();
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
// Homekit export
|
||||
let homekitObject = {};
|
||||
let openhabList = [];
|
||||
// logger.info("allLabeledItems")
|
||||
// logger.info(JSON.stringify(allLabeledItems))
|
||||
allLabeledItems.forEach((item) => {
|
||||
let exportData = item.exportItem();
|
||||
if (exportData != null) {
|
||||
if ('id' in exportData['homekit']) {
|
||||
homekitObject[exportData['homekit']['id']] = exportData['homekit']['object'];
|
||||
}
|
||||
openhabList.push(exportData['openhab']);
|
||||
if (exportData['openhab'] instanceof Array) {
|
||||
let da = exportData['openhab'];
|
||||
da.forEach((o) => openhabList.push(o));
|
||||
}
|
||||
else {
|
||||
let da = exportData['openhab'];
|
||||
openhabList.push(da);
|
||||
}
|
||||
// logger.info("openHabList")
|
||||
// logger.info(JSON.stringify(openhabList))
|
||||
}
|
||||
});
|
||||
let heatingMainSwitchExport = MaxThermostat_1.MaxThermostat.exportHeatingMainSwitchItem();
|
||||
if (heatingMainSwitchExport != null) {
|
||||
let da = heatingMainSwitchExport['openhab'];
|
||||
openhabList.push(da);
|
||||
}
|
||||
fs.writeFileSync(config.dict.homekitFile, JSON.stringify(homekitObject, null, 4));
|
||||
fs.writeFileSync(config.dict.openhabItemFile, openhabList.join('\n'));
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
|
385
homekit.json
385
homekit.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"1st.Anna.AquariumLight": {
|
||||
"id": "1st.Anna.AquariumLight",
|
||||
"1st_Anna_AquariumLight": {
|
||||
"id": "1st_Anna_AquariumLight",
|
||||
"name": "Aquariumlicht",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -16,8 +16,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"1st.Anna.BedLight": {
|
||||
"id": "1st.Anna.BedLight",
|
||||
"1st_Anna_BedLight": {
|
||||
"id": "1st_Anna_BedLight",
|
||||
"name": "Bettlicht Anna",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -33,13 +33,35 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"1st.Matthias.Stehlampen Matthias": {
|
||||
"id": "1st.Matthias.Stehlampen Matthias",
|
||||
"name": "StandLight",
|
||||
"1st_Anna_WindowContact": {
|
||||
"id": "1st_Anna_WindowContact",
|
||||
"name": "Fenster Anna",
|
||||
"service": "ContactSensor",
|
||||
"topic": {
|
||||
"statusContactSensorState": "dispatcher_ng/items/1st/Anna/WindowContact/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onContactDetected": "CLOSED"
|
||||
}
|
||||
},
|
||||
"1st_Anna_Thermostat": {
|
||||
"id": "1st_Anna_Thermostat",
|
||||
"name": "Thermostat Anna",
|
||||
"service": "Thermostat",
|
||||
"topic": {
|
||||
"setTargetTemperature": "dispatcher_ng/items/1st/Anna/Thermostat/temperature",
|
||||
"statusTargetTemperature": "dispatcher_ng/items/1st/Anna/Thermostat/temperature/feedback",
|
||||
"statusCurrentTemperature": "dispatcher_ng/items/1st/Anna/Thermostat/temperature/feedback"
|
||||
},
|
||||
"payload": {}
|
||||
},
|
||||
"1st_Matthias_StandLight": {
|
||||
"id": "1st_Matthias_StandLight",
|
||||
"name": "Stehlampen Matthias",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
"setOn": "dispatcher_ng/items/1st/Matthias/Stehlampen Matthias/state",
|
||||
"statusOn": "dispatcher_ng/items/1st/Matthias/Stehlampen Matthias/state/feedback"
|
||||
"setOn": "dispatcher_ng/items/1st/Matthias/StandLight/state",
|
||||
"statusOn": "dispatcher_ng/items/1st/Matthias/StandLight/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onTrue": "ON",
|
||||
@ -50,8 +72,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"1st.Matthias.BedLight": {
|
||||
"id": "1st.Matthias.BedLight",
|
||||
"1st_Matthias_BedLight": {
|
||||
"id": "1st_Matthias_BedLight",
|
||||
"name": "Bettlicht Matthias",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -67,8 +89,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"1st.Matthias.Speaker": {
|
||||
"id": "1st.Matthias.Speaker",
|
||||
"1st_Matthias_Speaker": {
|
||||
"id": "1st_Matthias_Speaker",
|
||||
"name": "Lautsprecher Matthias",
|
||||
"service": "Outlet",
|
||||
"topic": {
|
||||
@ -81,8 +103,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd.DiningRoom.SmallLight": {
|
||||
"id": "Gnd.DiningRoom.SmallLight",
|
||||
"Gnd_DiningRoom_SmallLight": {
|
||||
"id": "Gnd_DiningRoom_SmallLight",
|
||||
"name": "kleine Lampe Esszimmer",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -98,8 +120,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd.DiningRoom.StandLight": {
|
||||
"id": "Gnd.DiningRoom.StandLight",
|
||||
"Gnd_DiningRoom_StandLight": {
|
||||
"id": "Gnd_DiningRoom_StandLight",
|
||||
"name": "Stehlampe Esszimmer",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -115,8 +137,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd.DiningRoom.CupboardLight": {
|
||||
"id": "Gnd.DiningRoom.CupboardLight",
|
||||
"Gnd_DiningRoom_CupboardLight": {
|
||||
"id": "Gnd_DiningRoom_CupboardLight",
|
||||
"name": "Schranklicht Esszimmer",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -132,8 +154,51 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd.LivingRoom.LargeLight": {
|
||||
"id": "Gnd.LivingRoom.LargeLight",
|
||||
"Gnd_DiningRoom_ShelfLight": {
|
||||
"id": "Gnd_DiningRoom_ShelfLight",
|
||||
"name": "Regallicht Esszimmer",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
"setOn": "dispatcher_ng/items/Gnd/DiningRoom/ShelfLight/state",
|
||||
"statusOn": "dispatcher_ng/items/Gnd/DiningRoom/ShelfLight/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onTrue": "ON",
|
||||
"onFalse": "OFF",
|
||||
"brightnessFactor": "",
|
||||
"hueFactor": "",
|
||||
"saturationFactor": ""
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd_DiningRoom_NaehkaestchenLight": {
|
||||
"id": "Gnd_DiningRoom_NaehkaestchenLight",
|
||||
"name": "Lampe Naehkaestchen",
|
||||
"service": "Lightbulb",
|
||||
"manufacturer": "hue2mqtt - Hue",
|
||||
"model": "color light",
|
||||
"topic": {
|
||||
"setOn": "dispatcher_ng/items/Gnd/DiningRoom/NaehkaestchenLight/state",
|
||||
"statusOn": "dispatcher_ng/items/Gnd/DiningRoom/NaehkaestchenLight/state/feedback",
|
||||
"setBrightness": "dispatcher_ng/items/Gnd/DiningRoom/NaehkaestchenLight/bright",
|
||||
"statusBrightness": "dispatcher_ng/items/Gnd/DiningRoom/NaehkaestchenLight/bright/feedback",
|
||||
"setHue": "dispatcher_ng/items/Gnd/DiningRoom/NaehkaestchenLight/hue",
|
||||
"statusHue": "dispatcher_ng/items/Gnd/DiningRoom/NaehkaestchenLight/bright/hue",
|
||||
"setSaturation": "dispatcher_ng/items/Gnd/DiningRoom/NaehkaestchenLight/saturation",
|
||||
"statusSaturation": "dispatcher_ng/items/Gnd/DiningRoom/NaehkaestchenLight/bright/saturation",
|
||||
"setColorTemperature": "dispatcher_ng/items/Gnd/DiningRoom/NaehkaestchenLight/colorTemperature",
|
||||
"statusColorTemperature": "dispatcher_ng/items/Gnd/DiningRoom/NaehkaestchenLight/colorTemperature/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onTrue": "ON",
|
||||
"onFalse": "OFF",
|
||||
"brightnessFactor": 1,
|
||||
"hueFactor": 1,
|
||||
"saturationFactor": 1
|
||||
}
|
||||
},
|
||||
"Gnd_LivingRoom_LargeLight": {
|
||||
"id": "Gnd_LivingRoom_LargeLight",
|
||||
"name": "große Lampe Wohnzimmer",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -149,8 +214,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd.LivingRoom.SmallLight": {
|
||||
"id": "Gnd.LivingRoom.SmallLight",
|
||||
"Gnd_LivingRoom_SmallLight": {
|
||||
"id": "Gnd_LivingRoom_SmallLight",
|
||||
"name": "kleine Lampe Wohnzimmer",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -166,8 +231,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd.LivingRoom.Stars": {
|
||||
"id": "Gnd.LivingRoom.Stars",
|
||||
"Gnd_LivingRoom_Stars": {
|
||||
"id": "Gnd_LivingRoom_Stars",
|
||||
"name": "Sterne Wohnzimmer",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -183,8 +248,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd.LivingRoom.StandLight": {
|
||||
"id": "Gnd.LivingRoom.StandLight",
|
||||
"Gnd_LivingRoom_StandLight": {
|
||||
"id": "Gnd_LivingRoom_StandLight",
|
||||
"name": "Stehlampe Wohnzimmer",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -200,8 +265,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd.Hallway.DeskLight": {
|
||||
"id": "Gnd.Hallway.DeskLight",
|
||||
"Gnd_Hallway_DeskLight": {
|
||||
"id": "Gnd_Hallway_DeskLight",
|
||||
"name": "Schreibtischlampe Flur",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -217,8 +282,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd.Hallway.StandLight": {
|
||||
"id": "Gnd.Hallway.StandLight",
|
||||
"Gnd_Hallway_StandLight": {
|
||||
"id": "Gnd_Hallway_StandLight",
|
||||
"name": "Stehlampe Flur",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -234,8 +299,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd.Hallway.WardrobeLight": {
|
||||
"id": "Gnd.Hallway.WardrobeLight",
|
||||
"Gnd_Hallway_WardrobeLight": {
|
||||
"id": "Gnd_Hallway_WardrobeLight",
|
||||
"name": "Schranklicht Flur",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -251,8 +316,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd.Kitchen.WindowLight": {
|
||||
"id": "Gnd.Kitchen.WindowLight",
|
||||
"Gnd_Kitchen_WindowLight": {
|
||||
"id": "Gnd_Kitchen_WindowLight",
|
||||
"name": "Fensterbanklicht Küche",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -268,8 +333,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd.Kitchen.CeilingLight": {
|
||||
"id": "Gnd.Kitchen.CeilingLight",
|
||||
"Gnd_Kitchen_CeilingLight": {
|
||||
"id": "Gnd_Kitchen_CeilingLight",
|
||||
"name": "Deckenlampe Küche",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -285,8 +350,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"1st.BedRoom.WolfgangsSide": {
|
||||
"id": "1st.BedRoom.WolfgangsSide",
|
||||
"1st_BedRoom_WolfgangsSide": {
|
||||
"id": "1st_BedRoom_WolfgangsSide",
|
||||
"name": "Wolfgangs Seite Schlafzimmer",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -302,8 +367,34 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"1st.BedRoom.PattysSide": {
|
||||
"id": "1st.BedRoom.PattysSide",
|
||||
"1st_BedRoom_WolfgangBedLight": {
|
||||
"id": "1st_BedRoom_WolfgangBedLight",
|
||||
"name": "Bettlicht",
|
||||
"service": "Lightbulb",
|
||||
"manufacturer": "hue2mqtt - Hue",
|
||||
"model": "color light",
|
||||
"topic": {
|
||||
"setOn": "dispatcher_ng/items/1st/BedRoom/WolfgangBedLight/state",
|
||||
"statusOn": "dispatcher_ng/items/1st/BedRoom/WolfgangBedLight/state/feedback",
|
||||
"setBrightness": "dispatcher_ng/items/1st/BedRoom/WolfgangBedLight/bright",
|
||||
"statusBrightness": "dispatcher_ng/items/1st/BedRoom/WolfgangBedLight/bright/feedback",
|
||||
"setHue": "dispatcher_ng/items/1st/BedRoom/WolfgangBedLight/hue",
|
||||
"statusHue": "dispatcher_ng/items/1st/BedRoom/WolfgangBedLight/bright/hue",
|
||||
"setSaturation": "dispatcher_ng/items/1st/BedRoom/WolfgangBedLight/saturation",
|
||||
"statusSaturation": "dispatcher_ng/items/1st/BedRoom/WolfgangBedLight/bright/saturation",
|
||||
"setColorTemperature": "dispatcher_ng/items/1st/BedRoom/WolfgangBedLight/colorTemperature",
|
||||
"statusColorTemperature": "dispatcher_ng/items/1st/BedRoom/WolfgangBedLight/colorTemperature/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onTrue": "ON",
|
||||
"onFalse": "OFF",
|
||||
"brightnessFactor": 1,
|
||||
"hueFactor": 1,
|
||||
"saturationFactor": 1
|
||||
}
|
||||
},
|
||||
"1st_BedRoom_PattysSide": {
|
||||
"id": "1st_BedRoom_PattysSide",
|
||||
"name": "Pattys Seite Schlafzimmer",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -319,8 +410,8 @@
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"1st.BedRoom.WindowLight": {
|
||||
"id": "1st.BedRoom.WindowLight",
|
||||
"1st_BedRoom_WindowLight": {
|
||||
"id": "1st_BedRoom_WindowLight",
|
||||
"name": "Fensterbanklicht Schlafzimmer",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
@ -335,5 +426,211 @@
|
||||
"saturationFactor": ""
|
||||
},
|
||||
"config": {}
|
||||
}
|
||||
},
|
||||
"1st_Bedroom_WindowContactStreet": {
|
||||
"id": "1st_Bedroom_WindowContactStreet",
|
||||
"name": "Fenster Schlafzimmer Strasse",
|
||||
"service": "ContactSensor",
|
||||
"topic": {
|
||||
"statusContactSensorState": "dispatcher_ng/items/1st/Bedroom/WindowContactStreet/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onContactDetected": "CLOSED"
|
||||
}
|
||||
},
|
||||
"1st_Bedroom_WindowContact1Garden": {
|
||||
"id": "1st_Bedroom_WindowContact1Garden",
|
||||
"name": "Fenster Schlafzimmer 1 Garten",
|
||||
"service": "ContactSensor",
|
||||
"topic": {
|
||||
"statusContactSensorState": "dispatcher_ng/items/1st/Bedroom/WindowContact1Garden/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onContactDetected": "CLOSED"
|
||||
}
|
||||
},
|
||||
"1st_Bedroom_WindowContact2Garden": {
|
||||
"id": "1st_Bedroom_WindowContact2Garden",
|
||||
"name": "Fenster Schlafzimmer 2 Garten",
|
||||
"service": "ContactSensor",
|
||||
"topic": {
|
||||
"statusContactSensorState": "dispatcher_ng/items/1st/Bedroom/WindowContact2Garden/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onContactDetected": "CLOSED"
|
||||
}
|
||||
},
|
||||
"1st_Bedroom_Thermostat": {
|
||||
"id": "1st_Bedroom_Thermostat",
|
||||
"name": "Thermostat Schlafzimmer",
|
||||
"service": "Thermostat",
|
||||
"topic": {
|
||||
"setTargetTemperature": "dispatcher_ng/items/1st/Bedroom/Thermostat/temperature",
|
||||
"statusTargetTemperature": "dispatcher_ng/items/1st/Bedroom/Thermostat/temperature/feedback",
|
||||
"statusCurrentTemperature": "dispatcher_ng/items/1st/Bedroom/Thermostat/temperature/feedback"
|
||||
},
|
||||
"payload": {}
|
||||
},
|
||||
"Gnd_Hallway_DayLight": {
|
||||
"id": "Gnd_Hallway_DayLight",
|
||||
"name": "DayLight",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
"setOn": "dispatcher_ng/items/Gnd/Hallway/DayLight/state",
|
||||
"statusOn": "dispatcher_ng/items/Gnd/Hallway/DayLight/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onTrue": "ON",
|
||||
"onFalse": "OFF",
|
||||
"brightnessFactor": "",
|
||||
"hueFactor": "",
|
||||
"saturationFactor": ""
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd_Hallway_EcoLight": {
|
||||
"id": "Gnd_Hallway_EcoLight",
|
||||
"name": "EcoLight",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
"setOn": "dispatcher_ng/items/Gnd/Hallway/EcoLight/state",
|
||||
"statusOn": "dispatcher_ng/items/Gnd/Hallway/EcoLight/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onTrue": "ON",
|
||||
"onFalse": "OFF",
|
||||
"brightnessFactor": "",
|
||||
"hueFactor": "",
|
||||
"saturationFactor": ""
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd_Hallway_MorningLight": {
|
||||
"id": "Gnd_Hallway_MorningLight",
|
||||
"name": "MorningLight",
|
||||
"service": "Lightbulb",
|
||||
"topic": {
|
||||
"setOn": "dispatcher_ng/items/Gnd/Hallway/MorningLight/state",
|
||||
"statusOn": "dispatcher_ng/items/Gnd/Hallway/MorningLight/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onTrue": "ON",
|
||||
"onFalse": "OFF",
|
||||
"brightnessFactor": "",
|
||||
"hueFactor": "",
|
||||
"saturationFactor": ""
|
||||
},
|
||||
"config": {}
|
||||
},
|
||||
"Gnd_Bathroom_WindowContact": {
|
||||
"id": "Gnd_Bathroom_WindowContact",
|
||||
"name": "Fenster Bad unten",
|
||||
"service": "ContactSensor",
|
||||
"topic": {
|
||||
"statusContactSensorState": "dispatcher_ng/items/Gnd/Bathroom/WindowContact/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onContactDetected": "CLOSED"
|
||||
}
|
||||
},
|
||||
"Gnd_Bathroom_Thermostat": {
|
||||
"id": "Gnd_Bathroom_Thermostat",
|
||||
"name": "Thermostat Bad unten",
|
||||
"service": "Thermostat",
|
||||
"topic": {
|
||||
"setTargetTemperature": "dispatcher_ng/items/Gnd/Bathroom/Thermostat/temperature",
|
||||
"statusTargetTemperature": "dispatcher_ng/items/Gnd/Bathroom/Thermostat/temperature/feedback",
|
||||
"statusCurrentTemperature": "dispatcher_ng/items/Gnd/Bathroom/Thermostat/temperature/feedback"
|
||||
},
|
||||
"payload": {}
|
||||
},
|
||||
"1st_Bathroom_WindowContact": {
|
||||
"id": "1st_Bathroom_WindowContact",
|
||||
"name": "Fenster Bad oben",
|
||||
"service": "ContactSensor",
|
||||
"topic": {
|
||||
"statusContactSensorState": "dispatcher_ng/items/1st/Bathroom/WindowContact/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onContactDetected": "CLOSED"
|
||||
}
|
||||
},
|
||||
"1st_Bathroom_Thermostat": {
|
||||
"id": "1st_Bathroom_Thermostat",
|
||||
"name": "Thermostat Bad oben",
|
||||
"service": "Thermostat",
|
||||
"topic": {
|
||||
"setTargetTemperature": "dispatcher_ng/items/1st/Bathroom/Thermostat/temperature",
|
||||
"statusTargetTemperature": "dispatcher_ng/items/1st/Bathroom/Thermostat/temperature/feedback",
|
||||
"statusCurrentTemperature": "dispatcher_ng/items/1st/Bathroom/Thermostat/temperature/feedback"
|
||||
},
|
||||
"payload": {}
|
||||
},
|
||||
"Gnd_Kitchen_WindowContact1": {
|
||||
"id": "Gnd_Kitchen_WindowContact1",
|
||||
"name": "Fenster Küche Garten",
|
||||
"service": "ContactSensor",
|
||||
"topic": {
|
||||
"statusContactSensorState": "dispatcher_ng/items/Gnd/Kitchen/WindowContact1/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onContactDetected": "CLOSED"
|
||||
}
|
||||
},
|
||||
"Gnd_Kitchen_WindowContact2": {
|
||||
"id": "Gnd_Kitchen_WindowContact2",
|
||||
"name": "Fenster Küche Terassentür Garten",
|
||||
"service": "ContactSensor",
|
||||
"topic": {
|
||||
"statusContactSensorState": "dispatcher_ng/items/Gnd/Kitchen/WindowContact2/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onContactDetected": "CLOSED"
|
||||
}
|
||||
},
|
||||
"Gnd_Kitchen_WindowContact3": {
|
||||
"id": "Gnd_Kitchen_WindowContact3",
|
||||
"name": "Fenster Küche Straße 1",
|
||||
"service": "ContactSensor",
|
||||
"topic": {
|
||||
"statusContactSensorState": "dispatcher_ng/items/Gnd/Kitchen/WindowContact3/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onContactDetected": "CLOSED"
|
||||
}
|
||||
},
|
||||
"Gnd_Kitchen_WindowContact4": {
|
||||
"id": "Gnd_Kitchen_WindowContact4",
|
||||
"name": "Fenster Küche Straße 2",
|
||||
"service": "ContactSensor",
|
||||
"topic": {
|
||||
"statusContactSensorState": "dispatcher_ng/items/Gnd/Kitchen/WindowContact4/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onContactDetected": "CLOSED"
|
||||
}
|
||||
},
|
||||
"Gnd_Kitchen_Thermostat": {
|
||||
"id": "Gnd_Kitchen_Thermostat",
|
||||
"name": "Thermostat Küche",
|
||||
"service": "Thermostat",
|
||||
"topic": {
|
||||
"setTargetTemperature": "dispatcher_ng/items/Gnd/Kitchen/Thermostat/temperature",
|
||||
"statusTargetTemperature": "dispatcher_ng/items/Gnd/Kitchen/Thermostat/temperature/feedback",
|
||||
"statusCurrentTemperature": "dispatcher_ng/items/Gnd/Kitchen/Thermostat/temperature/feedback"
|
||||
},
|
||||
"payload": {}
|
||||
},
|
||||
"Gnd_Hallway_FrontdoorContact": {
|
||||
"id": "Gnd_Hallway_FrontdoorContact",
|
||||
"name": "Haustür",
|
||||
"service": "ContactSensor",
|
||||
"topic": {
|
||||
"statusContactSensorState": "dispatcher_ng/items/Gnd/Hallway/FrontdoorContact/state/feedback"
|
||||
},
|
||||
"payload": {
|
||||
"onContactDetected": "CLOSED"
|
||||
}
|
||||
},
|
||||
"": {}
|
||||
}
|
@ -1,20 +1,54 @@
|
||||
Switch 1st.Anna.AquariumLight {mqtt=">[localbroker:dispatcher_ng/items/1st/Anna/AquariumLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/1st/Anna/AquariumLight/state/feedback:state:default]"}
|
||||
Switch 1st.Anna.BedLight {mqtt=">[localbroker:dispatcher_ng/items/1st/Anna/BedLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/1st/Anna/BedLight/state/feedback:state:default]"}
|
||||
Switch 1st.Matthias.Stehlampen Matthias {mqtt=">[localbroker:dispatcher_ng/items/1st/Matthias/Stehlampen Matthias/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/1st/Matthias/Stehlampen Matthias/state/feedback:state:default]"}
|
||||
Switch 1st.Matthias.BedLight {mqtt=">[localbroker:dispatcher_ng/items/1st/Matthias/BedLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/1st/Matthias/BedLight/state/feedback:state:default]"}
|
||||
Switch 1st.Matthias.Speaker {mqtt=">[localbroker:dispatcher_ng/items/1st/Matthias/Speaker/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/1st/Matthias/Speaker/state/feedback:state:default]"}
|
||||
Switch Gnd.DiningRoom.SmallLight {mqtt=">[localbroker:dispatcher_ng/items/Gnd/DiningRoom/SmallLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/Gnd/DiningRoom/SmallLight/state/feedback:state:default]"}
|
||||
Switch Gnd.DiningRoom.StandLight {mqtt=">[localbroker:dispatcher_ng/items/Gnd/DiningRoom/StandLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/Gnd/DiningRoom/StandLight/state/feedback:state:default]"}
|
||||
Switch Gnd.DiningRoom.CupboardLight {mqtt=">[localbroker:dispatcher_ng/items/Gnd/DiningRoom/CupboardLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/Gnd/DiningRoom/CupboardLight/state/feedback:state:default]"}
|
||||
Switch Gnd.LivingRoom.LargeLight {mqtt=">[localbroker:dispatcher_ng/items/Gnd/LivingRoom/LargeLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/Gnd/LivingRoom/LargeLight/state/feedback:state:default]"}
|
||||
Switch Gnd.LivingRoom.SmallLight {mqtt=">[localbroker:dispatcher_ng/items/Gnd/LivingRoom/SmallLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/Gnd/LivingRoom/SmallLight/state/feedback:state:default]"}
|
||||
Switch Gnd.LivingRoom.Stars {mqtt=">[localbroker:dispatcher_ng/items/Gnd/LivingRoom/Stars/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/Gnd/LivingRoom/Stars/state/feedback:state:default]"}
|
||||
Switch Gnd.LivingRoom.StandLight {mqtt=">[localbroker:dispatcher_ng/items/Gnd/LivingRoom/StandLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/Gnd/LivingRoom/StandLight/state/feedback:state:default]"}
|
||||
Switch Gnd.Hallway.DeskLight {mqtt=">[localbroker:dispatcher_ng/items/Gnd/Hallway/DeskLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/Gnd/Hallway/DeskLight/state/feedback:state:default]"}
|
||||
Switch Gnd.Hallway.StandLight {mqtt=">[localbroker:dispatcher_ng/items/Gnd/Hallway/StandLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/Gnd/Hallway/StandLight/state/feedback:state:default]"}
|
||||
Switch Gnd.Hallway.StandLight {mqtt=">[localbroker:dispatcher_ng/items/Gnd/Hallway/StandLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/Gnd/Hallway/StandLight/state/feedback:state:default]"}
|
||||
Switch Gnd.Kitchen.WindowLight {mqtt=">[localbroker:dispatcher_ng/items/Gnd/Kitchen/WindowLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/Gnd/Kitchen/WindowLight/state/feedback:state:default]"}
|
||||
Switch Gnd.Kitchen.CeilingLight {mqtt=">[localbroker:dispatcher_ng/items/Gnd/Kitchen/CeilingLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/Gnd/Kitchen/CeilingLight/state/feedback:state:default]"}
|
||||
Switch 1st.BedRoom.WolfgangsSide {mqtt=">[localbroker:dispatcher_ng/items/1st/BedRoom/WolfgangsSide/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/1st/BedRoom/WolfgangsSide/state/feedback:state:default]"}
|
||||
Switch 1st.BedRoom.PattysSide {mqtt=">[localbroker:dispatcher_ng/items/1st/BedRoom/PattysSide/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/1st/BedRoom/PattysSide/state/feedback:state:default]"}
|
||||
Switch 1st.BedRoom.WindowLight {mqtt=">[localbroker:dispatcher_ng/items/1st/BedRoom/WindowLight/state:command:*:default]", mqtt="<[localbroker:dispatcher_ng/items/1st/BedRoom/WindowLight/state/feedback:state:default]"}
|
||||
Switch 1st_Anna_AquariumLight "Aquariumlicht"{mqtt=">[localbroker:dispatcher_ng/items/1st/Anna/AquariumLight/state:command:*:default],<[localbroker:dispatcher_ng/items/1st/Anna/AquariumLight/state/feedback:state:default]"}
|
||||
Switch 1st_Anna_BedLight "Bettlicht Anna"{mqtt=">[localbroker:dispatcher_ng/items/1st/Anna/BedLight/state:command:*:default],<[localbroker:dispatcher_ng/items/1st/Anna/BedLight/state/feedback:state:default]"}
|
||||
Contact 1st_Anna_WindowContact "Fenster Anna" {mqtt="<[localbroker:dispatcher_ng/items/1st/Anna/WindowContact/state/feedback:state:default]"}
|
||||
Number 1st_Anna_Thermostat "Thermostat Anna [%.1f °C]" {mqtt=">[localbroker:dispatcher_ng/items/1st/Anna/Thermostat/temperature:command:*:default],<[localbroker:dispatcher_ng/items/1st/Anna/Thermostat/temperature/feedback:state:default]"}
|
||||
Number Preset_1st_Anna_Thermostat "Preset_Thermostat Anna [%.1f °C]" {mqtt=">[localbroker:dispatcher_ng/items/1st/Anna/Thermostat/presetTemperature:command:*:default],<[localbroker:dispatcher_ng/items/1st/Anna/Thermostat/presetTemperature/feedback:state:default]"}
|
||||
Switch 1st_Matthias_StandLight "Stehlampen Matthias"{mqtt=">[localbroker:dispatcher_ng/items/1st/Matthias/StandLight/state:command:*:default],<[localbroker:dispatcher_ng/items/1st/Matthias/StandLight/state/feedback:state:default]"}
|
||||
Switch 1st_Matthias_BedLight "Bettlicht Matthias"{mqtt=">[localbroker:dispatcher_ng/items/1st/Matthias/BedLight/state:command:*:default],<[localbroker:dispatcher_ng/items/1st/Matthias/BedLight/state/feedback:state:default]"}
|
||||
Switch 1st_Matthias_Speaker "Lautsprecher Matthias"{mqtt=">[localbroker:dispatcher_ng/items/1st/Matthias/Speaker/state:command:*:default],<[localbroker:dispatcher_ng/items/1st/Matthias/Speaker/state/feedback:state:default]"}
|
||||
Switch Gnd_DiningRoom_SmallLight "kleine Lampe Esszimmer"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/DiningRoom/SmallLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/DiningRoom/SmallLight/state/feedback:state:default]"}
|
||||
Switch Gnd_DiningRoom_StandLight "Stehlampe Esszimmer"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/DiningRoom/StandLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/DiningRoom/StandLight/state/feedback:state:default]"}
|
||||
Switch Gnd_DiningRoom_CupboardLight "Schranklicht Esszimmer"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/DiningRoom/CupboardLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/DiningRoom/CupboardLight/state/feedback:state:default]"}
|
||||
Switch Gnd_DiningRoom_ShelfLight "Regallicht Esszimmer"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/DiningRoom/ShelfLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/DiningRoom/ShelfLight/state/feedback:state:default]"}
|
||||
|
||||
Switch Gnd_LivingRoom_LargeLight "große Lampe Wohnzimmer"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/LivingRoom/LargeLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/LivingRoom/LargeLight/state/feedback:state:default]"}
|
||||
Switch Gnd_LivingRoom_SmallLight "kleine Lampe Wohnzimmer"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/LivingRoom/SmallLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/LivingRoom/SmallLight/state/feedback:state:default]"}
|
||||
Switch Gnd_LivingRoom_Stars "Sterne Wohnzimmer"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/LivingRoom/Stars/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/LivingRoom/Stars/state/feedback:state:default]"}
|
||||
Switch Gnd_LivingRoom_StandLight "Stehlampe Wohnzimmer"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/LivingRoom/StandLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/LivingRoom/StandLight/state/feedback:state:default]"}
|
||||
Switch Gnd_Hallway_DeskLight "Schreibtischlampe Flur"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/Hallway/DeskLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/Hallway/DeskLight/state/feedback:state:default]"}
|
||||
Switch Gnd_Hallway_StandLight "Stehlampe Flur"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/Hallway/StandLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/Hallway/StandLight/state/feedback:state:default]"}
|
||||
Switch Gnd_Hallway_WardrobeLight "Schranklicht Flur"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/Hallway/WardrobeLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/Hallway/WardrobeLight/state/feedback:state:default]"}
|
||||
Switch Gnd_Kitchen_WindowLight "Fensterbanklicht Küche"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/Kitchen/WindowLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/Kitchen/WindowLight/state/feedback:state:default]"}
|
||||
Switch Gnd_Kitchen_CeilingLight "Deckenlampe Küche"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/Kitchen/CeilingLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/Kitchen/CeilingLight/state/feedback:state:default]"}
|
||||
Switch 1st_BedRoom_WolfgangsSide "Wolfgangs Seite Schlafzimmer"{mqtt=">[localbroker:dispatcher_ng/items/1st/BedRoom/WolfgangsSide/state:command:*:default],<[localbroker:dispatcher_ng/items/1st/BedRoom/WolfgangsSide/state/feedback:state:default]"}
|
||||
|
||||
Switch 1st_BedRoom_PattysSide "Pattys Seite Schlafzimmer"{mqtt=">[localbroker:dispatcher_ng/items/1st/BedRoom/PattysSide/state:command:*:default],<[localbroker:dispatcher_ng/items/1st/BedRoom/PattysSide/state/feedback:state:default]"}
|
||||
Switch 1st_BedRoom_WindowLight "Fensterbanklicht Schlafzimmer"{mqtt=">[localbroker:dispatcher_ng/items/1st/BedRoom/WindowLight/state:command:*:default],<[localbroker:dispatcher_ng/items/1st/BedRoom/WindowLight/state/feedback:state:default]"}
|
||||
Contact 1st_Bedroom_WindowContactStreet "Fenster Schlafzimmer Strasse" {mqtt="<[localbroker:dispatcher_ng/items/1st/Bedroom/WindowContactStreet/state/feedback:state:default]"}
|
||||
Contact 1st_Bedroom_WindowContact1Garden "Fenster Schlafzimmer 1 Garten" {mqtt="<[localbroker:dispatcher_ng/items/1st/Bedroom/WindowContact1Garden/state/feedback:state:default]"}
|
||||
Contact 1st_Bedroom_WindowContact2Garden "Fenster Schlafzimmer 2 Garten" {mqtt="<[localbroker:dispatcher_ng/items/1st/Bedroom/WindowContact2Garden/state/feedback:state:default]"}
|
||||
Number 1st_Bedroom_Thermostat "Thermostat Schlafzimmer [%.1f °C]" {mqtt=">[localbroker:dispatcher_ng/items/1st/Bedroom/Thermostat/temperature:command:*:default],<[localbroker:dispatcher_ng/items/1st/Bedroom/Thermostat/temperature/feedback:state:default]"}
|
||||
Number Preset_1st_Bedroom_Thermostat "Preset_Thermostat Schlafzimmer [%.1f °C]" {mqtt=">[localbroker:dispatcher_ng/items/1st/Bedroom/Thermostat/presetTemperature:command:*:default],<[localbroker:dispatcher_ng/items/1st/Bedroom/Thermostat/presetTemperature/feedback:state:default]"}
|
||||
Switch Gnd_Hallway_DayLight "DayLight"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/Hallway/DayLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/Hallway/DayLight/state/feedback:state:default]"}
|
||||
Switch Gnd_Hallway_EcoLight "EcoLight"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/Hallway/EcoLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/Hallway/EcoLight/state/feedback:state:default]"}
|
||||
Switch Gnd_Hallway_MorningLight "MorningLight"{mqtt=">[localbroker:dispatcher_ng/items/Gnd/Hallway/MorningLight/state:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/Hallway/MorningLight/state/feedback:state:default]"}
|
||||
Contact Gnd_Bathroom_WindowContact "Fenster Bad unten" {mqtt="<[localbroker:dispatcher_ng/items/Gnd/Bathroom/WindowContact/state/feedback:state:default]"}
|
||||
Number Gnd_Bathroom_Thermostat "Thermostat Bad unten [%.1f °C]" {mqtt=">[localbroker:dispatcher_ng/items/Gnd/Bathroom/Thermostat/temperature:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/Bathroom/Thermostat/temperature/feedback:state:default]"}
|
||||
Number Preset_Gnd_Bathroom_Thermostat "Preset_Thermostat Bad unten [%.1f °C]" {mqtt=">[localbroker:dispatcher_ng/items/Gnd/Bathroom/Thermostat/presetTemperature:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/Bathroom/Thermostat/presetTemperature/feedback:state:default]"}
|
||||
Contact 1st_Bathroom_WindowContact "Fenster Bad oben" {mqtt="<[localbroker:dispatcher_ng/items/1st/Bathroom/WindowContact/state/feedback:state:default]"}
|
||||
Number 1st_Bathroom_Thermostat "Thermostat Bad oben [%.1f °C]" {mqtt=">[localbroker:dispatcher_ng/items/1st/Bathroom/Thermostat/temperature:command:*:default],<[localbroker:dispatcher_ng/items/1st/Bathroom/Thermostat/temperature/feedback:state:default]"}
|
||||
Number Preset_1st_Bathroom_Thermostat "Preset_Thermostat Bad oben [%.1f °C]" {mqtt=">[localbroker:dispatcher_ng/items/1st/Bathroom/Thermostat/presetTemperature:command:*:default],<[localbroker:dispatcher_ng/items/1st/Bathroom/Thermostat/presetTemperature/feedback:state:default]"}
|
||||
Contact Gnd_Kitchen_WindowContact1 "Fenster Küche Garten" {mqtt="<[localbroker:dispatcher_ng/items/Gnd/Kitchen/WindowContact1/state/feedback:state:default]"}
|
||||
Contact Gnd_Kitchen_WindowContact2 "Fenster Küche Terassentür Garten" {mqtt="<[localbroker:dispatcher_ng/items/Gnd/Kitchen/WindowContact2/state/feedback:state:default]"}
|
||||
Contact Gnd_Kitchen_WindowContact3 "Fenster Küche Straße 1" {mqtt="<[localbroker:dispatcher_ng/items/Gnd/Kitchen/WindowContact3/state/feedback:state:default]"}
|
||||
Contact Gnd_Kitchen_WindowContact4 "Fenster Küche Straße 2" {mqtt="<[localbroker:dispatcher_ng/items/Gnd/Kitchen/WindowContact4/state/feedback:state:default]"}
|
||||
Number Gnd_Kitchen_Thermostat "Thermostat Küche [%.1f °C]" {mqtt=">[localbroker:dispatcher_ng/items/Gnd/Kitchen/Thermostat/temperature:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/Kitchen/Thermostat/temperature/feedback:state:default]"}
|
||||
Number Preset_Gnd_Kitchen_Thermostat "Preset_Thermostat Küche [%.1f °C]" {mqtt=">[localbroker:dispatcher_ng/items/Gnd/Kitchen/Thermostat/presetTemperature:command:*:default],<[localbroker:dispatcher_ng/items/Gnd/Kitchen/Thermostat/presetTemperature/feedback:state:default]"}
|
||||
Contact Gnd_Hallway_FrontdoorContact "Haustür" {mqtt="<[localbroker:dispatcher_ng/items/Gnd/Hallway/FrontdoorContact/state/feedback:state:default]"}
|
||||
Switch base_labor_relaybox0 "Küche" {mqtt=">[localbroker:dispatcher_ng/items/base/labor/relaybox/state/0:command:*:default],<[localbroker:dispatcher_ng/items/base/labor/relaybox/feedback/0:state:default]"}
|
||||
String base_labor_relaybox0Conflict "Küche [%s]" {mqtt="<[localbroker:dispatcher_ng/items/base/labor/relaybox/conflict/0:state:default]"}
|
||||
Switch base_labor_relaybox1 "Herd" {mqtt=">[localbroker:dispatcher_ng/items/base/labor/relaybox/state/1:command:*:default],<[localbroker:dispatcher_ng/items/base/labor/relaybox/feedback/1:state:default]"}
|
||||
String base_labor_relaybox1Conflict "Herd [%s]" {mqtt="<[localbroker:dispatcher_ng/items/base/labor/relaybox/conflict/1:state:default]"}
|
||||
Switch base_labor_relaybox2 "Waschküche" {mqtt=">[localbroker:dispatcher_ng/items/base/labor/relaybox/state/2:command:*:default],<[localbroker:dispatcher_ng/items/base/labor/relaybox/feedback/2:state:default]"}
|
||||
String base_labor_relaybox2Conflict "Waschküche [%s]" {mqtt="<[localbroker:dispatcher_ng/items/base/labor/relaybox/conflict/2:state:default]"}
|
||||
Switch HeatingMainSwitch "Heizung Hauptschalter" {mqtt=">[localbroker:dispatcher_ng/items/heatingMainSwitch:command:*:default],<[localbroker:dispatcher_ng/items/heatingMainSwitch:state:default]"}
|
430
package-lock.json
generated
430
package-lock.json
generated
@ -4,6 +4,16 @@
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/body-parser": {
|
||||
"version": "1.16.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.16.8.tgz",
|
||||
"integrity": "sha512-BdN2PXxOFnTXFcyONPW6t0fHjz2fvRZHVMFpaS0wYr+Y8fWEaNOs4V8LEu/fpzQlMx+ahdndgTaGTwPC+J/EeA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/express": "4.11.1",
|
||||
"@types/node": "8.5.8"
|
||||
}
|
||||
},
|
||||
"@types/chalk": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/chalk/-/chalk-2.2.0.tgz",
|
||||
@ -19,6 +29,45 @@
|
||||
"integrity": "sha512-lLN/Rtud+SONdclROGc8CnZeZ/ujQ69U4otFMtoCfCdLfs2x2R2lJFSy583uI9dnnsd6I9Pdy/Mw3efqxO/2bg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/cron": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/cron/-/cron-1.2.1.tgz",
|
||||
"integrity": "sha1-lcHkMtYQbKNMkvB0Nji8eGwHP6o=",
|
||||
"dev": true
|
||||
},
|
||||
"@types/events": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz",
|
||||
"integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/express": {
|
||||
"version": "4.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.11.1.tgz",
|
||||
"integrity": "sha512-ttWle8cnPA5rAelauSWeWJimtY2RsUf2aspYZs7xPHiWgOlPn6nnUfBMtrkcnjFJuIHJF4gNOdVvpLK2Zmvh6g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/body-parser": "1.16.8",
|
||||
"@types/express-serve-static-core": "4.11.1",
|
||||
"@types/serve-static": "1.13.1"
|
||||
}
|
||||
},
|
||||
"@types/express-serve-static-core": {
|
||||
"version": "4.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.11.1.tgz",
|
||||
"integrity": "sha512-EehCl3tpuqiM8RUb+0255M8PhhSwTtLfmO7zBBdv0ay/VTd/zmrqDfQdZFsa5z/PVMbH2yCMZPXsnrImpATyIw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/events": "1.2.0",
|
||||
"@types/node": "8.5.8"
|
||||
}
|
||||
},
|
||||
"@types/mime": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz",
|
||||
"integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/moment": {
|
||||
"version": "2.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/moment/-/moment-2.13.0.tgz",
|
||||
@ -52,6 +101,25 @@
|
||||
"@types/node": "8.5.8"
|
||||
}
|
||||
},
|
||||
"@types/serve-static": {
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.1.tgz",
|
||||
"integrity": "sha512-jDMH+3BQPtvqZVIcsH700Dfi8Q3MIcEx16g/VdxjoqiGR/NntekB10xdBpirMKnPe9z2C5cBmL0vte0YttOr3Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/express-serve-static-core": "4.11.1",
|
||||
"@types/mime": "2.0.0"
|
||||
}
|
||||
},
|
||||
"accepts": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
|
||||
"integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
|
||||
"requires": {
|
||||
"mime-types": "2.1.18",
|
||||
"negotiator": "0.6.1"
|
||||
}
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
|
||||
@ -68,6 +136,11 @@
|
||||
"typical": "2.6.1"
|
||||
}
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
|
||||
@ -86,6 +159,23 @@
|
||||
"readable-stream": "2.3.3"
|
||||
}
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.18.2",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
|
||||
"integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
|
||||
"requires": {
|
||||
"bytes": "3.0.0",
|
||||
"content-type": "1.0.4",
|
||||
"debug": "2.6.9",
|
||||
"depd": "1.1.2",
|
||||
"http-errors": "1.6.3",
|
||||
"iconv-lite": "0.4.19",
|
||||
"on-finished": "2.3.0",
|
||||
"qs": "6.5.1",
|
||||
"raw-body": "2.3.2",
|
||||
"type-is": "1.6.16"
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
|
||||
@ -95,6 +185,11 @@
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"bytes": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
|
||||
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
|
||||
},
|
||||
"callback-stream": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/callback-stream/-/callback-stream-1.1.0.tgz",
|
||||
@ -161,11 +256,57 @@
|
||||
"typedarray": "0.0.6"
|
||||
}
|
||||
},
|
||||
"content-disposition": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
|
||||
"integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
|
||||
},
|
||||
"content-type": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
|
||||
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"cron": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/cron/-/cron-1.3.0.tgz",
|
||||
"integrity": "sha512-K/SF7JlgMmNjcThWxkKvsHhey2EDB4CeOEWJ9aXWj3fbQJppsvTPIeyLdHfNq5IbbsMUUjRW1nr5dSO95f2E4w==",
|
||||
"requires": {
|
||||
"moment-timezone": "0.5.14"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"depd": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
|
||||
},
|
||||
"destroy": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||
},
|
||||
"duplexify": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz",
|
||||
@ -177,6 +318,16 @@
|
||||
"stream-shift": "1.0.0"
|
||||
}
|
||||
},
|
||||
"ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz",
|
||||
@ -185,16 +336,77 @@
|
||||
"once": "1.4.0"
|
||||
}
|
||||
},
|
||||
"escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
},
|
||||
"etag": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
||||
},
|
||||
"express": {
|
||||
"version": "4.16.3",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz",
|
||||
"integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
|
||||
"requires": {
|
||||
"accepts": "1.3.5",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.18.2",
|
||||
"content-disposition": "0.5.2",
|
||||
"content-type": "1.0.4",
|
||||
"cookie": "0.3.1",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "1.1.2",
|
||||
"encodeurl": "1.0.2",
|
||||
"escape-html": "1.0.3",
|
||||
"etag": "1.8.1",
|
||||
"finalhandler": "1.1.1",
|
||||
"fresh": "0.5.2",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "1.1.2",
|
||||
"on-finished": "2.3.0",
|
||||
"parseurl": "1.3.2",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "2.0.3",
|
||||
"qs": "6.5.1",
|
||||
"range-parser": "1.2.0",
|
||||
"safe-buffer": "5.1.1",
|
||||
"send": "0.16.2",
|
||||
"serve-static": "1.13.2",
|
||||
"setprototypeof": "1.1.0",
|
||||
"statuses": "1.4.0",
|
||||
"type-is": "1.6.16",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "1.1.2"
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
|
||||
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
|
||||
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "1.0.2",
|
||||
"escape-html": "1.0.3",
|
||||
"on-finished": "2.3.0",
|
||||
"parseurl": "1.3.2",
|
||||
"statuses": "1.4.0",
|
||||
"unpipe": "1.0.0"
|
||||
}
|
||||
},
|
||||
"find-replace": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz",
|
||||
@ -214,6 +426,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
|
||||
},
|
||||
"fresh": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
@ -274,6 +496,22 @@
|
||||
"xtend": "4.0.1"
|
||||
}
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.6.3",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
|
||||
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
|
||||
"requires": {
|
||||
"depd": "1.1.2",
|
||||
"inherits": "2.0.3",
|
||||
"setprototypeof": "1.1.0",
|
||||
"statuses": "1.4.0"
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.19",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
|
||||
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
@ -288,6 +526,11 @@
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz",
|
||||
"integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs="
|
||||
},
|
||||
"is-absolute": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
|
||||
@ -364,6 +607,39 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||
},
|
||||
"merge-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
|
||||
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.33.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
|
||||
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.18",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
|
||||
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
|
||||
"requires": {
|
||||
"mime-db": "1.33.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
@ -382,6 +658,14 @@
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz",
|
||||
"integrity": "sha1-1usaRsvMFKKy+UNBEsH/iQfzE/0="
|
||||
},
|
||||
"moment-timezone": {
|
||||
"version": "0.5.14",
|
||||
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.14.tgz",
|
||||
"integrity": "sha1-TrOP+VOLgBCLpGekWPPtQmjM/LE=",
|
||||
"requires": {
|
||||
"moment": "2.20.1"
|
||||
}
|
||||
},
|
||||
"mqtt": {
|
||||
"version": "2.15.0",
|
||||
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-2.15.0.tgz",
|
||||
@ -413,11 +697,29 @@
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
|
||||
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
|
||||
},
|
||||
"nodemailer": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-4.4.1.tgz",
|
||||
"integrity": "sha512-1bnszJJXatcHJhLpxQ1XMkLDjCjPKvGKMtRQ73FOsoNln3UQjddEQmz6fAwM3aj0GtQ3dQX9qtMHPelz63GU7A=="
|
||||
},
|
||||
"on-finished": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
||||
"requires": {
|
||||
"ee-first": "1.1.1"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
@ -434,6 +736,11 @@
|
||||
"readable-stream": "2.3.3"
|
||||
}
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
|
||||
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
|
||||
},
|
||||
"path-dirname": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
|
||||
@ -444,11 +751,25 @@
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
||||
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz",
|
||||
"integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==",
|
||||
"requires": {
|
||||
"forwarded": "0.1.2",
|
||||
"ipaddr.js": "1.6.0"
|
||||
}
|
||||
},
|
||||
"pump": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-2.0.0.tgz",
|
||||
@ -479,6 +800,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
|
||||
"integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
|
||||
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
|
||||
"integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
|
||||
"requires": {
|
||||
"bytes": "3.0.0",
|
||||
"http-errors": "1.6.2",
|
||||
"iconv-lite": "0.4.19",
|
||||
"unpipe": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"depd": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
|
||||
"integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
|
||||
"integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
|
||||
"requires": {
|
||||
"depd": "1.1.1",
|
||||
"inherits": "2.0.3",
|
||||
"setprototypeof": "1.0.3",
|
||||
"statuses": "1.4.0"
|
||||
}
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
|
||||
"integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
|
||||
}
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
|
||||
@ -508,6 +873,42 @@
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
"integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM="
|
||||
},
|
||||
"send": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
|
||||
"integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"depd": "1.1.2",
|
||||
"destroy": "1.0.4",
|
||||
"encodeurl": "1.0.2",
|
||||
"escape-html": "1.0.3",
|
||||
"etag": "1.8.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "1.6.3",
|
||||
"mime": "1.4.1",
|
||||
"ms": "2.0.0",
|
||||
"on-finished": "2.3.0",
|
||||
"range-parser": "1.2.0",
|
||||
"statuses": "1.4.0"
|
||||
}
|
||||
},
|
||||
"serve-static": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
|
||||
"integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
|
||||
"requires": {
|
||||
"encodeurl": "1.0.2",
|
||||
"escape-html": "1.0.3",
|
||||
"parseurl": "1.3.2",
|
||||
"send": "0.16.2"
|
||||
}
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
|
||||
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
|
||||
},
|
||||
"simple-node-logger": {
|
||||
"version": "0.93.33",
|
||||
"resolved": "https://registry.npmjs.org/simple-node-logger/-/simple-node-logger-0.93.33.tgz",
|
||||
@ -525,6 +926,11 @@
|
||||
"through2": "2.0.3"
|
||||
}
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
|
||||
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
|
||||
},
|
||||
"stream-shift": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
|
||||
@ -592,6 +998,15 @@
|
||||
"is-negated-glob": "1.0.0"
|
||||
}
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.6.16",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
|
||||
"integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
|
||||
"requires": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "2.1.18"
|
||||
}
|
||||
},
|
||||
"typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
@ -627,11 +1042,26 @@
|
||||
"through2-filter": "2.0.0"
|
||||
}
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||
},
|
||||
"websocket-stream": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-5.1.1.tgz",
|
||||
|
@ -19,16 +19,22 @@
|
||||
},
|
||||
"homepage": "https://gitlab.com/wolutator/dispatcher_ng#README",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.18.2",
|
||||
"chalk": "^2.3.0",
|
||||
"command-line-args": "^4.0.7",
|
||||
"cron": "^1.3.0",
|
||||
"express": "^4.16.3",
|
||||
"moment": "^2.20.1",
|
||||
"mqtt": "^2.15.0",
|
||||
"nodemailer": "^4.4.1",
|
||||
"simple-node-logger": "^0.93.33"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/body-parser": "^1.16.8",
|
||||
"@types/express": "^4.11.1",
|
||||
"@types/chalk": "^2.2.0",
|
||||
"@types/command-line-args": "^4.0.2",
|
||||
"@types/cron": "^1.2.1",
|
||||
"@types/moment": "^2.13.0",
|
||||
"@types/mqtt": "^2.5.0",
|
||||
"@types/node": "^8.5.8",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { AItem } from './AItem'
|
||||
|
||||
|
||||
export abstract class AHomematicItem extends AItem {
|
||||
export abstract class AHomegearItem extends AItem {
|
||||
protected deviceTopicPre: string;
|
||||
protected actionTopicPre: string;
|
||||
protected homegearTopicPre: string;
|
29
src/AItem.ts
29
src/AItem.ts
@ -3,13 +3,26 @@ import { mqttHandler } from './MqttDispatcher'
|
||||
import { ExportType } from './Export'
|
||||
|
||||
|
||||
|
||||
export interface HasStateTopic {
|
||||
getStateTopic() : string
|
||||
}
|
||||
|
||||
export interface HasStateAndFeedbackTopic extends HasStateTopic {
|
||||
getStateFeedbackTopic() : string
|
||||
}
|
||||
|
||||
export interface HasInTopic {
|
||||
getInTopic() : string
|
||||
}
|
||||
|
||||
export abstract class AItem {
|
||||
protected topicFirstPart: string
|
||||
protected itemId: string
|
||||
protected label: string
|
||||
private item: string
|
||||
private room: string
|
||||
private floor: string
|
||||
protected item: string
|
||||
protected room: string
|
||||
protected floor: string
|
||||
protected subscribeTopics: string[]
|
||||
|
||||
|
||||
@ -17,7 +30,7 @@ export abstract class AItem {
|
||||
this.floor = floor
|
||||
this.room = room
|
||||
this.item = item
|
||||
this.itemId = `${this.floor}.${this.room}.${this.item}`
|
||||
this.itemId = `${this.floor}_${this.room}_${this.item}`
|
||||
if (label == '') {
|
||||
this.label = this.itemId
|
||||
} else {
|
||||
@ -28,14 +41,18 @@ export abstract class AItem {
|
||||
|
||||
abstract processMessage(topic: string, payload: string) : void
|
||||
|
||||
startFunc() : void {
|
||||
|
||||
}
|
||||
|
||||
exportItem() : ExportType|null {
|
||||
return null
|
||||
}
|
||||
|
||||
start() : void {
|
||||
mqttHandler.register(this.subscribeTopics, (topic: string, payload: string) : void => {
|
||||
logger.info(`item ${this.itemId}: ${topic}, ${payload}`)
|
||||
// logger.info(`item ${this.itemId}: ${topic}, ${payload}`)
|
||||
this.processMessage(topic, payload)
|
||||
})
|
||||
}, () => { this.startFunc() })
|
||||
}
|
||||
}
|
||||
|
33
src/Cron.ts
Normal file
33
src/Cron.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { HasInTopic } from './AItem'
|
||||
import * as cron from 'cron'
|
||||
|
||||
|
||||
type CronEntry = {
|
||||
output: string
|
||||
cronTime: string
|
||||
cronJob?: cron.CronJob
|
||||
}
|
||||
|
||||
export class Cron {
|
||||
private crontab: CronEntry[]
|
||||
private targetTopic: string
|
||||
private name: string
|
||||
|
||||
constructor(name: string, target: HasInTopic, crontab: CronEntry[]) {
|
||||
this.name = name
|
||||
this.targetTopic = target.getInTopic()
|
||||
this.crontab = crontab
|
||||
}
|
||||
|
||||
start() : void {
|
||||
this.crontab.forEach((cronEntry) => {
|
||||
logger.info(`Starting cronjob for: ${this.targetTopic}, ${cronEntry.output} at ${cronEntry.cronTime}`)
|
||||
cronEntry.cronJob = new cron.CronJob(cronEntry.cronTime, () => {
|
||||
logger.info(`Firing ${this.targetTopic}, ${cronEntry.output}`)
|
||||
mqttHandler.send(this.targetTopic, cronEntry.output)
|
||||
}, undefined, true, 'Europe/Berlin')
|
||||
})
|
||||
}
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
import { AItem } from './AItem'
|
||||
import { AItem, HasInTopic } from './AItem'
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
|
||||
|
||||
export class DimmerAdaptor extends AItem {
|
||||
export class DimmerAdaptor extends AItem implements HasInTopic {
|
||||
private brightDirection: number
|
||||
private bright: number
|
||||
private state: string
|
||||
@ -22,6 +21,11 @@ export class DimmerAdaptor extends AItem {
|
||||
this.brightDirection = -1
|
||||
}
|
||||
|
||||
getInTopic() : string {
|
||||
return this.inTopic
|
||||
}
|
||||
|
||||
|
||||
processMessage(topic: string, payload: string) : void {
|
||||
switch (topic) {
|
||||
case this.inTopic:
|
||||
|
4
src/Disabler.ts
Normal file
4
src/Disabler.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export interface Disabler {
|
||||
transform(payload: string) : string
|
||||
getStateFeedbackTopic(): string
|
||||
}
|
125
src/Export.ts
125
src/Export.ts
@ -1,6 +1,6 @@
|
||||
export type ExportType = {
|
||||
'homekit': HomekitExportType,
|
||||
'openhab': string
|
||||
'openhab': string | string[]
|
||||
}
|
||||
|
||||
export type HomekitExportType = {
|
||||
@ -27,6 +27,48 @@ export function SwitchExport(itemId: string, label: string, stateTopic: string,
|
||||
return { 'homekit': homekitOut, 'openhab': openhabOut }
|
||||
}
|
||||
|
||||
export function ThermostatExport(itemId: string, label: string, temperatureTopic: string, temperatureFeedbackTopic: string, presetTemperatureTopic: string, presetTemperatureFeedbackTopic: string) : ExportType {
|
||||
return {'homekit': ThermostatHomekitExport(itemId, label, temperatureTopic, temperatureFeedbackTopic), 'openhab': ThermostatOpenHAPExport(itemId, label, temperatureTopic, temperatureFeedbackTopic, presetTemperatureTopic, presetTemperatureFeedbackTopic)}
|
||||
}
|
||||
|
||||
export function ContactExport(itemId: string, label: string, status: string) : ExportType {
|
||||
return {'homekit': ContactHomekitExport(itemId, label, status), 'openhab': ContactOpenHABExport(itemId, label, status)}
|
||||
}
|
||||
|
||||
export function HueColorLightExport(itemId: string, label: string,
|
||||
stateTopic: string, stateFeedbackTopic: string,
|
||||
brightnessTopic: string, brightnessFeedbackTopic: string,
|
||||
hueTopic: string, hueFeedbackTopic: string,
|
||||
saturationTopic: string, saturationFeedbackTopic: string,
|
||||
colorTemperatureTopic: string, colorTemperatureFeedbackTopic: string) {
|
||||
return {'homekit': HueColorLightHomekitExport(itemId, label, stateTopic, stateFeedbackTopic,
|
||||
brightnessTopic, brightnessFeedbackTopic, hueTopic, hueFeedbackTopic,
|
||||
saturationTopic, saturationFeedbackTopic, colorTemperatureTopic, colorTemperatureFeedbackTopic), 'openhab': ''}
|
||||
}
|
||||
|
||||
export function RelayBoxExport(itemId: string, stateTopicPre: string, feedbackTopicPre: string, conflictTopicPre: string, itemNames: string[]) : ExportType {
|
||||
return {'homekit': RelayBoxHomekitExport(itemId, stateTopicPre, feedbackTopicPre, conflictTopicPre, itemNames),
|
||||
'openhab': RelayBoxOpenHABExport(itemId, stateTopicPre, feedbackTopicPre, conflictTopicPre, itemNames)}
|
||||
}
|
||||
|
||||
export function HeatingMainSwitchExport(topic: string) : ExportType {
|
||||
return {'homekit': {'id':'', 'object': {}},
|
||||
'openhab': `Switch HeatingMainSwitch "Heizung Hauptschalter" {mqtt=">[localbroker:${topic}:command:*:default],<[localbroker:${topic}:state:default]"}`}
|
||||
}
|
||||
|
||||
function RelayBoxHomekitExport(itemId: string, stateTopicPre: string, feedbackTopicPre: string, conflictTopicPre: string, itemNames: string[]) : HomekitExportType{
|
||||
return {'id': '', 'object': {}}
|
||||
}
|
||||
|
||||
function RelayBoxOpenHABExport(itemId: string, stateTopicPre: string, feedbackTopicPre: string, conflictTopicPre: string, itemNames: string[]) : string[] {
|
||||
let o : string[] = []
|
||||
itemNames.forEach((label: string, index: number) => {
|
||||
o.push(`Switch ${itemId}${index} "${label}" {mqtt=">[localbroker:${stateTopicPre}/${index}:command:*:default],<[localbroker:${feedbackTopicPre}/${index}:state:default]"}`)
|
||||
o.push(`String ${itemId}${index}Conflict "${label} [%s]" {mqtt="<[localbroker:${conflictTopicPre}/${index}:state:default]"}`)
|
||||
})
|
||||
return o
|
||||
}
|
||||
|
||||
|
||||
function SwitchHomekitBulbExport(id: string, label: string, setOn: string, statusOn: string) : HomekitExportType {
|
||||
let o : any = {
|
||||
@ -67,8 +109,85 @@ function SwitchHomekitOutletExport(id: string, label: string, setOn: string, sta
|
||||
return { 'id': id, 'object': o }
|
||||
}
|
||||
|
||||
function ThermostatHomekitExport(id: string, label: string, setTemperature: string, statusTemperature: string) : HomekitExportType {
|
||||
let o : any = {
|
||||
"id": id,
|
||||
"name": label,
|
||||
"service": "Thermostat",
|
||||
"topic": {
|
||||
"setTargetTemperature": setTemperature,
|
||||
"statusTargetTemperature": statusTemperature,
|
||||
"statusCurrentTemperature": statusTemperature
|
||||
},
|
||||
"payload": {}
|
||||
}
|
||||
return { 'id': id, 'object': o }
|
||||
}
|
||||
|
||||
function ContactHomekitExport(id: string, label: string, status: string) : HomekitExportType {
|
||||
let o : any = {
|
||||
"id": id,
|
||||
"name": label,
|
||||
"service": "ContactSensor",
|
||||
"topic": {
|
||||
"statusContactSensorState": status
|
||||
},
|
||||
"payload": {
|
||||
"onContactDetected": "CLOSED"
|
||||
}
|
||||
}
|
||||
|
||||
return { 'id': id, 'object': o }
|
||||
}
|
||||
|
||||
function SwitchOpenHABExport(id: string, label: string, setOn: string, statusOn: string): string {
|
||||
// Switch windowLightKitchen {mqtt=">[localbroker:nodered/items/windowLightKitchen:command:*:default]", mqtt="<[localbroker:nodered/items/windowLightKitchen/feedback:state:default]"}
|
||||
return `Switch ${id} {mqtt=">[localbroker:${setOn}:command:*:default]", mqtt="<[localbroker:${statusOn}:state:default]"}`
|
||||
}
|
||||
return `Switch ${id} "${label}"{mqtt=">[localbroker:${setOn}:command:*:default],<[localbroker:${statusOn}:state:default]"}`
|
||||
}
|
||||
|
||||
function ContactOpenHABExport(id: string, label: string, status: string): string {
|
||||
// Switch windowLightKitchen {mqtt=">[localbroker:nodered/items/windowLightKitchen:command:*:default]", mqtt="<[localbroker:nodered/items/windowLightKitchen/feedback:state:default]"}
|
||||
return `Contact ${id} "${label}" {mqtt="<[localbroker:${status}:state:default]"}`
|
||||
}
|
||||
|
||||
function ThermostatOpenHAPExport(id: string, label: string, setTemperature: string, statusTemperature: string, presetTemperature: string, presetStatusTemperature: string) : string[] {
|
||||
let o : string[] = []
|
||||
o.push(`Number ${id} "${label} [%.1f °C]" {mqtt=">[localbroker:${setTemperature}:command:*:default],<[localbroker:${statusTemperature}:state:default]"}`)
|
||||
o.push(`Number Preset_${id} "Preset_${label} [%.1f °C]" {mqtt=">[localbroker:${presetTemperature}:command:*:default],<[localbroker:${presetStatusTemperature}:state:default]"}`)
|
||||
return o
|
||||
}
|
||||
|
||||
function HueColorLightHomekitExport(id: string, label: string,
|
||||
stateTopic: string, stateFeedbackTopic: string,
|
||||
brightnessTopic: string, brightnessFeedbackTopic: string,
|
||||
hueTopic: string, hueFeedbackTopic: string,
|
||||
saturationTopic: string, saturationFeedbackTopic: string,
|
||||
colorTemperatureTopic: string, colorTemperatureFeedbackTopic: string) {
|
||||
let o: any = {
|
||||
"id": id,
|
||||
"name": label,
|
||||
"service": "Lightbulb",
|
||||
"manufacturer": "hue2mqtt - Hue",
|
||||
"model": "color light",
|
||||
"topic": {
|
||||
"setOn": stateTopic,
|
||||
"statusOn": stateFeedbackTopic,
|
||||
"setBrightness": brightnessTopic,
|
||||
"statusBrightness": brightnessFeedbackTopic,
|
||||
"setHue": hueTopic,
|
||||
"statusHue": hueFeedbackTopic,
|
||||
"setSaturation": saturationTopic,
|
||||
"statusSaturation": saturationFeedbackTopic,
|
||||
"setColorTemperature": colorTemperatureTopic,
|
||||
"statusColorTemperature": colorTemperatureFeedbackTopic
|
||||
},
|
||||
"payload": {
|
||||
"onTrue": "ON",
|
||||
"onFalse": "OFF",
|
||||
"brightnessFactor": 1,
|
||||
"hueFactor": 1,
|
||||
"saturationFactor": 1
|
||||
}
|
||||
}
|
||||
return { 'id': id, 'object': o}
|
||||
}
|
||||
|
64
src/GeoFences.ts
Normal file
64
src/GeoFences.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import * as http from 'http'
|
||||
import * as express from 'express'
|
||||
import * as logger from './log'
|
||||
import * as bodyParser from 'body-parser'
|
||||
import * as config from './config'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
|
||||
|
||||
export type AttendanceSheetType = { [index: string]: boolean }
|
||||
|
||||
export class GeoFences extends EventEmitter {
|
||||
private app: express.Express
|
||||
private server: http.Server
|
||||
public attendanceSheet : AttendanceSheetType
|
||||
|
||||
static geoFencesTopicPre : string = "dispatcher_ng/geofences"
|
||||
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.app = express()
|
||||
this.app.use(bodyParser.urlencoded({ extended: false }));
|
||||
this.app.use(bodyParser.json());
|
||||
|
||||
this.attendanceSheet = {}
|
||||
}
|
||||
|
||||
exec() : void {
|
||||
this.app.post('/', (req: express.Request , res: express.Response) => {
|
||||
const reqData = req.body
|
||||
const deviceId = reqData.device
|
||||
let occupantName : string = 'unknown'
|
||||
const location = reqData.name
|
||||
if (deviceId in config.dict.occupants) {
|
||||
occupantName = config.dict.occupants[deviceId]
|
||||
}
|
||||
const presence : boolean = reqData.entry == '1'
|
||||
const direction : string = presence ? 'arrives at' : 'leaves from'
|
||||
logger.info(`${deviceId} (${occupantName}) ${direction} ${location}`)
|
||||
logger.info(JSON.stringify(reqData))
|
||||
res.send('OK')
|
||||
|
||||
const state : string = presence ? 'present' : 'absent'
|
||||
mqttHandler.send(`${GeoFences.geoFencesTopicPre}/${occupantName}`, state)
|
||||
|
||||
this.attendanceSheet[occupantName] = presence
|
||||
//logger.info(`attendanceSheet is now ${JSON.stringify(this.attendanceSheet)}`)
|
||||
|
||||
this.emit('change', this.attendanceSheet)
|
||||
})
|
||||
|
||||
let port = parseInt(config.dict.geofencesPort)
|
||||
this.server = this.app.listen(port, '', () => {
|
||||
logger.info(`geofences server listening on ${port}`)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { AHomematicItem } from './AHomematicItem'
|
||||
import { AHomegearItem } from './AHomegearItem'
|
||||
|
||||
|
||||
export class HomematicDimmerItem extends AHomematicItem {
|
||||
export class HomematicDimmerItem extends AHomegearItem {
|
||||
private oldBright: number|undefined
|
||||
private bright: number
|
||||
private oldState: string|undefined
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { AHomematicItem } from './AHomematicItem'
|
||||
import { AHomegearItem } from './AHomegearItem'
|
||||
|
||||
|
||||
export class HomematicFourButtonSingleItem {
|
||||
@ -29,7 +29,7 @@ export class HomematicFourButtonSingleItem {
|
||||
}
|
||||
}
|
||||
|
||||
export class HomematicFourButtonThing extends AHomematicItem {
|
||||
export class HomematicFourButtonThing extends AHomegearItem {
|
||||
private itemObjs: HomematicFourButtonSingleItem[]
|
||||
|
||||
constructor(floor: string, room: string, item: string, hmId: number, itemObjs: HomematicFourButtonSingleItem[]) {
|
||||
|
@ -1,9 +1,10 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { AHomematicItem } from './AHomematicItem'
|
||||
import { AHomegearItem } from './AHomegearItem'
|
||||
import { SwitchExport, ExportType } from './Export'
|
||||
import { HasStateAndFeedbackTopic } from './AItem';
|
||||
|
||||
export class HomematicSwitchItem extends AHomematicItem {
|
||||
export class HomematicSwitchItem extends AHomegearItem implements HasStateAndFeedbackTopic {
|
||||
private oldState: string|undefined
|
||||
private state: string
|
||||
private actionTopic: string
|
||||
@ -12,6 +13,14 @@ export class HomematicSwitchItem extends AHomematicItem {
|
||||
private stateTopic: string
|
||||
private type: string
|
||||
|
||||
getStateTopic() : string {
|
||||
return this.stateTopic
|
||||
}
|
||||
|
||||
getStateFeedbackTopic() : string {
|
||||
return this.stateFeedbackTopic
|
||||
}
|
||||
|
||||
constructor(floor: string, room: string, item: string, label: string, hmId: number, type: string = 'bulb') {
|
||||
super(floor, room, item, label, hmId)
|
||||
this.stateTopic = `${this.topicFirstPart}/state`
|
||||
|
158
src/HueColorBulbItem.ts
Normal file
158
src/HueColorBulbItem.ts
Normal file
@ -0,0 +1,158 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { AHomegearItem } from './AHomegearItem'
|
||||
import { HueColorLightExport, ExportType } from './Export'
|
||||
import { HasStateAndFeedbackTopic, HasInTopic } from './AItem'
|
||||
|
||||
export class HueColorBulbItem extends AHomegearItem implements HasStateAndFeedbackTopic{
|
||||
private readonly BRIGHT_FACTOR: number = 2.54
|
||||
private readonly HUE_FACTOR: number = (65535 / 360)
|
||||
private readonly SATURATION_FACTOR: number = 2.54
|
||||
private bright: number
|
||||
private colorTemperature: number
|
||||
private hue: number
|
||||
private saturation: number
|
||||
private state: string
|
||||
private stateActionTopic: string
|
||||
private brightActionTopic: string
|
||||
private colorTemperatureActionTopic: string
|
||||
private hueActionTopic: string
|
||||
private saturationActionTopic: string
|
||||
private brightFeedbackTopic: string
|
||||
private stateFeedbackTopic: string
|
||||
private colorTemperatureFeedbackTopic: string
|
||||
private hueFeedbackTopic: string
|
||||
private saturationFeedbackTopic: string
|
||||
private brightTopic: string
|
||||
private stateTopic: string
|
||||
private hueTopic: string
|
||||
private saturationTopic: string
|
||||
private colorTemperatureTopic: string
|
||||
private stateDeviceTopic: string
|
||||
private brightDeviceTopic: string
|
||||
private colorTemperatureDeviceTopic: string
|
||||
private hueDeviceTopic: string
|
||||
private saturationDeviceTopic: string
|
||||
|
||||
getStateTopic() : string {
|
||||
return this.stateTopic
|
||||
}
|
||||
|
||||
getInTopic() : string {
|
||||
return this.stateTopic
|
||||
}
|
||||
|
||||
getStateFeedbackTopic() : string {
|
||||
return this.stateFeedbackTopic
|
||||
}
|
||||
|
||||
constructor(floor: string, room: string, item: string, label: string, hmId: number) {
|
||||
super(floor, room, item, label, hmId)
|
||||
this.stateTopic = `${this.topicFirstPart}/state`
|
||||
this.brightTopic = `${this.topicFirstPart}/bright`
|
||||
this.colorTemperatureTopic = `${this.topicFirstPart}/colorTemperature`
|
||||
this.hueTopic = `${this.topicFirstPart}/hue`
|
||||
this.saturationTopic = `${this.topicFirstPart}/saturation`
|
||||
this.stateFeedbackTopic = `${this.topicFirstPart}/state/feedback`
|
||||
this.brightFeedbackTopic = `${this.topicFirstPart}/bright/feedback`
|
||||
this.hueFeedbackTopic = `${this.topicFirstPart}/bright/hue`
|
||||
this.saturationFeedbackTopic = `${this.topicFirstPart}/bright/saturation`
|
||||
this.colorTemperatureFeedbackTopic = `${this.topicFirstPart}/colorTemperature/feedback`
|
||||
this.stateActionTopic = `${this.actionTopicPre}/1/STATE`
|
||||
this.brightActionTopic = `${this.actionTopicPre}/1/FAST_BRIGHTNESS`
|
||||
this.hueActionTopic = `${this.actionTopicPre}/1/HUE`
|
||||
this.saturationActionTopic = `${this.actionTopicPre}/1/SATURATION`
|
||||
this.colorTemperatureActionTopic = `${this.actionTopicPre}/1/COLOR_TEMPERATURE`
|
||||
this.stateDeviceTopic = `${this.deviceTopicPre}/1/STATE`
|
||||
this.brightDeviceTopic = `${this.deviceTopicPre}/1/FAST_BRIGHTNESS`
|
||||
this.hueDeviceTopic = `${this.deviceTopicPre}/1/HUE`
|
||||
this.saturationDeviceTopic = `${this.deviceTopicPre}/1/SATURATION`
|
||||
this.colorTemperatureDeviceTopic = `${this.deviceTopicPre}/1/COLOR_TEMPERATURE`
|
||||
this.subscribeTopics = [
|
||||
this.stateTopic,
|
||||
this.brightTopic,
|
||||
this.colorTemperatureTopic,
|
||||
this.hueTopic,
|
||||
this.saturationTopic,
|
||||
this.stateDeviceTopic,
|
||||
this.brightDeviceTopic,
|
||||
this.colorTemperatureDeviceTopic,
|
||||
this.hueDeviceTopic,
|
||||
this.saturationDeviceTopic
|
||||
]
|
||||
this.state = 'OFF'
|
||||
this.bright = 0
|
||||
this.colorTemperature = 0
|
||||
this.hue = 0
|
||||
this.saturation = 0
|
||||
}
|
||||
|
||||
exportItem() : ExportType|null {
|
||||
return HueColorLightExport(this.itemId, this.label,
|
||||
this.stateTopic, this.stateFeedbackTopic,
|
||||
this.brightTopic, this.brightFeedbackTopic,
|
||||
this.hueTopic, this.hueFeedbackTopic,
|
||||
this.saturationTopic, this.saturationFeedbackTopic,
|
||||
this.colorTemperatureTopic, this.colorTemperatureFeedbackTopic)
|
||||
}
|
||||
|
||||
|
||||
processMessage(topic: string, payload: string) : void {
|
||||
switch (topic) {
|
||||
case this.stateTopic:
|
||||
this.state = payload
|
||||
mqttHandler.send(this.stateFeedbackTopic, this.state)
|
||||
if (this.state == "ON") {
|
||||
mqttHandler.send(this.stateActionTopic, "true")
|
||||
} else {
|
||||
mqttHandler.send(this.stateActionTopic, "false")
|
||||
}
|
||||
break
|
||||
case this.stateDeviceTopic:
|
||||
this.state = payload
|
||||
if (payload == "true") {
|
||||
this.state = "ON"
|
||||
} else {
|
||||
this.state = "OFF"
|
||||
}
|
||||
mqttHandler.send(this.stateFeedbackTopic, this.state)
|
||||
break
|
||||
case this.brightTopic:
|
||||
this.bright = parseFloat(payload)
|
||||
mqttHandler.send(this.brightFeedbackTopic, `${this.bright}`)
|
||||
mqttHandler.send(this.brightActionTopic, `${this.bright * this.BRIGHT_FACTOR}`)
|
||||
break
|
||||
case this.brightDeviceTopic:
|
||||
this.bright = parseFloat(payload) / this.BRIGHT_FACTOR
|
||||
mqttHandler.send(this.brightFeedbackTopic, `${this.bright}`)
|
||||
break
|
||||
case this.hueTopic:
|
||||
this.hue = parseFloat(payload)
|
||||
mqttHandler.send(this.hueFeedbackTopic, `${this.hue}`)
|
||||
mqttHandler.send(this.hueActionTopic, `${this.hue * this.HUE_FACTOR}`)
|
||||
break
|
||||
case this.hueDeviceTopic:
|
||||
this.hue = parseFloat(payload) / this.HUE_FACTOR
|
||||
mqttHandler.send(this.hueFeedbackTopic, `${this.hue}`)
|
||||
break
|
||||
case this.saturationTopic:
|
||||
this.saturation = parseFloat(payload)
|
||||
mqttHandler.send(this.saturationFeedbackTopic, `${this.saturation}`)
|
||||
mqttHandler.send(this.saturationActionTopic, `${this.saturation * this.SATURATION_FACTOR}`)
|
||||
break
|
||||
case this.saturationDeviceTopic:
|
||||
this.saturation = parseFloat(payload) / this.SATURATION_FACTOR
|
||||
mqttHandler.send(this.saturationFeedbackTopic, `${this.saturation}`)
|
||||
break
|
||||
case this.colorTemperatureTopic:
|
||||
this.colorTemperature = parseInt(payload)
|
||||
mqttHandler.send(this.colorTemperatureFeedbackTopic, `${this.colorTemperature}`)
|
||||
mqttHandler.send(this.colorTemperatureActionTopic, `${this.colorTemperature}`)
|
||||
break
|
||||
case this.colorTemperatureDeviceTopic:
|
||||
this.colorTemperature = parseInt(payload)
|
||||
mqttHandler.send(this.colorTemperatureFeedbackTopic, `${this.colorTemperature}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +1,31 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { AItem } from './AItem'
|
||||
import { AItem, HasStateAndFeedbackTopic, HasInTopic } from './AItem'
|
||||
import { SwitchExport, ExportType } from './Export'
|
||||
|
||||
|
||||
export class M433SwitchItem extends AItem {
|
||||
export class M433SwitchItem extends AItem implements HasStateAndFeedbackTopic {
|
||||
private offCode: string
|
||||
private onCode: string
|
||||
private oldState: string|undefined
|
||||
private state: string
|
||||
private actionTopic: string
|
||||
private stateFeedbackTopic: string
|
||||
public stateTopic: string
|
||||
private stateTopic: string
|
||||
private type: string
|
||||
|
||||
getStateTopic() : string {
|
||||
return this.stateTopic
|
||||
}
|
||||
|
||||
getInTopic() : string {
|
||||
return this.stateTopic
|
||||
}
|
||||
|
||||
getStateFeedbackTopic() : string {
|
||||
return this.stateFeedbackTopic
|
||||
}
|
||||
|
||||
constructor(floor: string, room: string, item: string, label: string, onCode: string, offCode: string, type: string = 'bulb') {
|
||||
super(floor, room, item, label)
|
||||
this.stateTopic = `${this.topicFirstPart}/state`
|
||||
|
66
src/MaxEcoSwitch.ts
Normal file
66
src/MaxEcoSwitch.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { AHomegearItem } from './AHomegearItem'
|
||||
import { LightScene } from './Scene'
|
||||
|
||||
export class MaxEcoSwitch extends AHomegearItem {
|
||||
private ecoTopic: string
|
||||
private mainTopic: string
|
||||
private mainButtonTopic: string
|
||||
private ecoButtonTopic: string
|
||||
private state: string
|
||||
|
||||
constructor(floor: string, room: string, item: string, label: string, hmId: number,
|
||||
mainScene: LightScene, ecoScene: LightScene) {
|
||||
super(floor, room, item, label, hmId)
|
||||
|
||||
this.mainButtonTopic = `${this.deviceTopicPre}/1/PRESS`
|
||||
this.ecoButtonTopic = `${this.deviceTopicPre}/2/PRESS`
|
||||
|
||||
this.subscribeTopics = [ this.mainButtonTopic, this.ecoButtonTopic ]
|
||||
|
||||
this.mainTopic = mainScene.getStateTopic()
|
||||
this.ecoTopic = ecoScene.getStateTopic()
|
||||
|
||||
this.state = 'OFF'
|
||||
}
|
||||
|
||||
|
||||
|
||||
processMessage(topic: string, payload: string) : void {
|
||||
switch(this.state) {
|
||||
case 'OFF':
|
||||
if (topic == this.mainButtonTopic) {
|
||||
this.state = 'ON'
|
||||
} else if (topic == this.ecoButtonTopic) {
|
||||
this.state = 'ECO'
|
||||
}
|
||||
break
|
||||
case 'ON':
|
||||
if (topic == this.mainButtonTopic) {
|
||||
this.state = 'OFF'
|
||||
} else if (topic == this.ecoButtonTopic) {
|
||||
this.state = 'ECO'
|
||||
}
|
||||
break
|
||||
case 'ECO':
|
||||
if (topic == this.mainButtonTopic) {
|
||||
this.state = 'ON'
|
||||
} else if (topic == this.ecoButtonTopic) {
|
||||
this.state = 'OFF'
|
||||
}
|
||||
break
|
||||
}
|
||||
switch(this.state) {
|
||||
case 'OFF':
|
||||
mqttHandler.send(this.mainTopic, 'OFF')
|
||||
break
|
||||
case 'ON':
|
||||
mqttHandler.send(this.mainTopic, 'ON')
|
||||
break
|
||||
case 'ECO':
|
||||
mqttHandler.send(this.ecoTopic, 'ON')
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
128
src/MaxThermostat.ts
Normal file
128
src/MaxThermostat.ts
Normal file
@ -0,0 +1,128 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { HasInTopic } from './AItem'
|
||||
import { AHomegearItem } from './AHomegearItem'
|
||||
// import { MaxWindowContact } from './MaxWindowContact';
|
||||
import { ThermostatExport, HeatingMainSwitchExport, ExportType } from './Export'
|
||||
import { Disabler } from './Disabler'
|
||||
|
||||
const DISABLED_TEMPERATURE: number = 5.0
|
||||
|
||||
type DisabledHolder = {
|
||||
disabler : Disabler
|
||||
state : string
|
||||
}
|
||||
|
||||
export class MaxThermostat extends AHomegearItem implements HasInTopic {
|
||||
private actionTopic: string
|
||||
private deviceFeedbackTopic: string
|
||||
private temperatureFeedbackTopic: string
|
||||
private temperatureTopic: string
|
||||
private temperature: number
|
||||
private presetTemperatureFeedbackTopic: string
|
||||
private presetTemperatureTopic: string
|
||||
private presetTemperature: number
|
||||
private hardDisablerMap: { [key:string]: DisabledHolder }
|
||||
private hardDisabled: boolean
|
||||
private commandTopic: string
|
||||
|
||||
static heatingMainSwitchTopic : string = 'dispatcher_ng/items/heatingMainSwitch'
|
||||
private heatingMainFlag: boolean = false
|
||||
|
||||
// Thermostat: homegear/instance1/set/3/1/SET_TEMPERATURE
|
||||
|
||||
getInTopic() : string {
|
||||
return this.commandTopic
|
||||
}
|
||||
|
||||
exportItem() : ExportType|null {
|
||||
return ThermostatExport(this.itemId, this.label, this.temperatureTopic, this.temperatureFeedbackTopic, this.presetTemperatureTopic, this.presetTemperatureFeedbackTopic)
|
||||
}
|
||||
|
||||
static exportHeatingMainSwitchItem() : ExportType|null {
|
||||
return HeatingMainSwitchExport(MaxThermostat.heatingMainSwitchTopic)
|
||||
}
|
||||
|
||||
constructor(floor: string, room: string, item: string, label: string, hmId: number, hardDisablers: Disabler[]) {
|
||||
super(floor, room, item, label, hmId)
|
||||
this.temperatureTopic = `${this.topicFirstPart}/temperature`
|
||||
this.temperatureFeedbackTopic = `${this.topicFirstPart}/temperature/feedback`
|
||||
this.presetTemperatureTopic = `${this.topicFirstPart}/presetTemperature`
|
||||
this.presetTemperatureFeedbackTopic = `${this.topicFirstPart}/presetTemperature/feedback`
|
||||
this.deviceFeedbackTopic = `${this.deviceTopicPre}/1/SET_TEMPERATURE`
|
||||
this.actionTopic = `${this.actionTopicPre}/1/SET_TEMPERATURE`
|
||||
this.commandTopic = `${this.topicFirstPart}/command`
|
||||
this.subscribeTopics = [
|
||||
this.temperatureTopic,
|
||||
this.presetTemperatureTopic,
|
||||
this.deviceFeedbackTopic,
|
||||
this.commandTopic,
|
||||
MaxThermostat.heatingMainSwitchTopic
|
||||
]
|
||||
this.hardDisabled = false
|
||||
this.hardDisablerMap = {}
|
||||
hardDisablers.forEach((hardDisabler) => {
|
||||
this.subscribeTopics.push(hardDisabler.getStateFeedbackTopic())
|
||||
this.hardDisablerMap[hardDisabler.getStateFeedbackTopic()] = { disabler: hardDisabler, state: 'unknown' }
|
||||
})
|
||||
}
|
||||
|
||||
setPresetTemperature(presetTemperature: number) {
|
||||
this.presetTemperature = presetTemperature
|
||||
}
|
||||
|
||||
startFunc() : void {
|
||||
mqttHandler.send(this.presetTemperatureTopic, `${this.presetTemperature}`)
|
||||
}
|
||||
|
||||
processMessage(topic: string, payload: string) : void {
|
||||
let setTemperature : boolean = false
|
||||
if (topic == this.temperatureTopic) {
|
||||
this.temperature = parseFloat(payload)
|
||||
setTemperature = true
|
||||
} else if (topic == this.commandTopic) {
|
||||
if (this.heatingMainFlag) {
|
||||
if (payload == 'ON') {
|
||||
this.temperature = this.presetTemperature
|
||||
} else if (payload == 'OFF') {
|
||||
this.temperature = DISABLED_TEMPERATURE
|
||||
}
|
||||
setTemperature = true
|
||||
}
|
||||
} else if (topic == MaxThermostat.heatingMainSwitchTopic) {
|
||||
this.heatingMainFlag = (payload == 'ON')
|
||||
logger.info(`${this.itemId} heating main: ${this.heatingMainFlag}`)
|
||||
if (! this.heatingMainFlag) {
|
||||
mqttHandler.send(this.temperatureFeedbackTopic, `${DISABLED_TEMPERATURE}`)
|
||||
mqttHandler.send(this.actionTopic, `${DISABLED_TEMPERATURE}`)
|
||||
}
|
||||
} else if (topic == this.presetTemperatureTopic) {
|
||||
this.presetTemperature = parseFloat(payload)
|
||||
mqttHandler.send(this.presetTemperatureFeedbackTopic, `${this.presetTemperature}`)
|
||||
} else if (topic == this.deviceFeedbackTopic) {
|
||||
// this.temperature = parseFloat(payload)
|
||||
setTemperature = false
|
||||
} else if (topic in this.hardDisablerMap) {
|
||||
this.hardDisablerMap[topic].state = this.hardDisablerMap[topic].disabler.transform(payload)
|
||||
this.hardDisabled = false
|
||||
Object.values(this.hardDisablerMap).forEach((w) => {
|
||||
if (w.state == 'DISABLE') {
|
||||
this.hardDisabled = true
|
||||
}
|
||||
})
|
||||
setTemperature = true
|
||||
}
|
||||
|
||||
if (setTemperature) {
|
||||
if (! this.hardDisabled) {
|
||||
mqttHandler.send(this.temperatureFeedbackTopic, `${this.temperature}`)
|
||||
mqttHandler.send(this.actionTopic, `${this.temperature}`)
|
||||
} else {
|
||||
mqttHandler.send(this.temperatureFeedbackTopic, `${DISABLED_TEMPERATURE}`)
|
||||
mqttHandler.send(this.actionTopic, `${DISABLED_TEMPERATURE}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
53
src/MaxWindowContact.ts
Normal file
53
src/MaxWindowContact.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { AHomegearItem } from './AHomegearItem'
|
||||
import { ContactExport, ExportType } from './Export'
|
||||
import { Disabler } from './Disabler'
|
||||
|
||||
export class MaxWindowContact extends AHomegearItem implements Disabler {
|
||||
private deviceFeedbackTopic: string
|
||||
private stateFeedbackTopic: string
|
||||
private stateTopic: string
|
||||
private state: string
|
||||
|
||||
getStateFeedbackTopic(): string {
|
||||
return this.stateFeedbackTopic
|
||||
}
|
||||
|
||||
transform(payload: string) : string {
|
||||
let res: string
|
||||
if (payload == 'OPEN') {
|
||||
res = 'DISABLE'
|
||||
} else if (payload == 'CLOSED') {
|
||||
res = 'ENABLE'
|
||||
} else {
|
||||
res = 'UNKNOWN'
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
constructor(floor: string, room: string, item: string, label: string, hmId: number) {
|
||||
super(floor, room, item, label, hmId)
|
||||
this.stateTopic = `${this.topicFirstPart}/state`
|
||||
this.stateFeedbackTopic = `${this.topicFirstPart}/state/feedback`
|
||||
this.deviceFeedbackTopic = `${this.deviceTopicPre}/1/STATE`
|
||||
this.subscribeTopics = [
|
||||
this.stateTopic,
|
||||
this.deviceFeedbackTopic
|
||||
]
|
||||
}
|
||||
|
||||
exportItem() : ExportType|null {
|
||||
return ContactExport(this.itemId, this.label, this.stateFeedbackTopic)
|
||||
}
|
||||
|
||||
processMessage(topic: string, payload: string) : void {
|
||||
if (payload == 'true') {
|
||||
this.state = 'OPEN'
|
||||
} else {
|
||||
this.state = 'CLOSED'
|
||||
}
|
||||
mqttHandler.send(this.stateFeedbackTopic, this.state)
|
||||
}
|
||||
|
||||
}
|
@ -2,10 +2,12 @@ import * as logger from './log'
|
||||
import * as Mqtt from 'mqtt'
|
||||
import * as fs from 'fs'
|
||||
import * as config from './config'
|
||||
import { IClientPublishOptions } from 'mqtt';
|
||||
|
||||
|
||||
|
||||
export type TopicCallbackFunc = (topic: string, payload: string) => void
|
||||
export type StartCallbackFunc = () => void
|
||||
|
||||
export interface TopicHandler {
|
||||
topic: string,
|
||||
@ -13,11 +15,13 @@ export interface TopicHandler {
|
||||
}
|
||||
|
||||
|
||||
|
||||
class MqttHandler {
|
||||
private mqttClient: Mqtt.Client
|
||||
private mqttOptions: Mqtt.IClientOptions = {}
|
||||
private mqttBrokerUrl: string
|
||||
private topicHandlers: TopicHandler[]
|
||||
private startCallbacks: StartCallbackFunc[]
|
||||
|
||||
constructor() {
|
||||
this.mqttBrokerUrl = config.dict.brokerUrl
|
||||
@ -32,15 +36,17 @@ class MqttHandler {
|
||||
}
|
||||
|
||||
this.topicHandlers = []
|
||||
this.startCallbacks = []
|
||||
|
||||
logger.info("MqttHandler constructed")
|
||||
}
|
||||
|
||||
register(topics: string[], cb: TopicCallbackFunc) : void {
|
||||
register(topics: string[], cb: TopicCallbackFunc, startCb: StartCallbackFunc) : void {
|
||||
topics.forEach((topic) => {
|
||||
this.topicHandlers.push({topic: topic, callback: cb})
|
||||
logger.info(`Callback registered for ${topic}`)
|
||||
})
|
||||
this.startCallbacks.push(startCb)
|
||||
}
|
||||
|
||||
exec() : void {
|
||||
@ -58,13 +64,17 @@ class MqttHandler {
|
||||
logger.info(`${topicHandler.topic} subscribed`)
|
||||
})
|
||||
logger.info('MQTT connection established')
|
||||
this.startCallbacks.forEach((cb) => {
|
||||
cb()
|
||||
logger.info("started")
|
||||
})
|
||||
})
|
||||
this.mqttClient.on('message', (topic: string, payload: Buffer, packet : Mqtt.IPublishPacket): void => {
|
||||
if (! packet.retain) {
|
||||
// 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)
|
||||
}
|
||||
// }
|
||||
})
|
||||
}
|
||||
|
||||
@ -90,17 +100,18 @@ class MqttHandler {
|
||||
}
|
||||
|
||||
send(topic: string, payload: string, internalFirst: boolean = false) : void {
|
||||
let sent = false
|
||||
if (internalFirst) {
|
||||
logger.info(`Try internal sending: ${topic}`)
|
||||
sent = this.processMessage(topic, payload)
|
||||
}
|
||||
if (! sent) {
|
||||
logger.info(`External sending required: ${topic}`)
|
||||
this.mqttClient.publish(topic, payload)
|
||||
} else {
|
||||
logger.info(`Internally delivered: ${topic}`)
|
||||
}
|
||||
//let sent = false
|
||||
//if (internalFirst) {
|
||||
// logger.info(`Try internal sending: ${topic}`)
|
||||
// sent = this.processMessage(topic, payload)
|
||||
//}
|
||||
//if (! sent) {
|
||||
logger.info(`External sending required: ${topic} ${payload}`)
|
||||
let options : IClientPublishOptions = { retain: true, qos: 0 }
|
||||
this.mqttClient.publish(topic, payload, options)
|
||||
//} else {
|
||||
// logger.info(`Internally delivered: ${topic}`)
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
let mqtt = require('./mqttHandler');
|
||||
let logger = require('./log');
|
||||
|
||||
|
||||
|
||||
class Switch {
|
||||
|
||||
}
|
||||
|
||||
class RelayBox {
|
||||
constructor(switches) {
|
||||
this.switches = switches;
|
||||
|
||||
}
|
||||
|
||||
start() {
|
||||
mqtt.register(this.subscribeTopics, (topic, payload) => {
|
||||
logger.info(`item ${this.itemId}: ${topic}, ${payload}`)
|
||||
this.processMessage(topic, payload);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
RelayBox,
|
||||
Switch
|
||||
};
|
||||
|
82
src/RelayBox.ts
Normal file
82
src/RelayBox.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { AItem } from './AItem'
|
||||
import { RelayBoxExport, ExportType } from './Export'
|
||||
|
||||
|
||||
|
||||
export class RelayBoxThing extends AItem {
|
||||
private itemNames: string[]
|
||||
private readonly deviceCommandTopic: string
|
||||
private readonly deviceStatusTopic: string
|
||||
private readonly stateTopicPre: string
|
||||
private readonly feedbackTopicPre: string
|
||||
private readonly conflictTopicPre: string
|
||||
private status : any
|
||||
private switchStates : string
|
||||
private oldSwitchStates : string
|
||||
|
||||
constructor(floor: string, room: string, item: string, deviceCommandTopic: string,
|
||||
deviceStatusTopic: string, itemNames: string[]) {
|
||||
super(floor, room, item, '')
|
||||
this.itemNames = itemNames
|
||||
this.deviceCommandTopic = deviceCommandTopic
|
||||
this.deviceStatusTopic = deviceStatusTopic
|
||||
this.stateTopicPre = `${this.topicFirstPart}/state`
|
||||
this.feedbackTopicPre = `${this.topicFirstPart}/feedback`
|
||||
this.conflictTopicPre = `${this.topicFirstPart}/conflict`
|
||||
this.subscribeTopics = [
|
||||
`${this.deviceStatusTopic}`,
|
||||
`${this.stateTopicPre}/#`
|
||||
]
|
||||
this.oldSwitchStates = ''
|
||||
}
|
||||
|
||||
exportItem() : ExportType|null {
|
||||
return RelayBoxExport(this.itemId, this.stateTopicPre, this.feedbackTopicPre, this.conflictTopicPre, this.itemNames)
|
||||
}
|
||||
|
||||
processMessage(topic: string, payload: string) {
|
||||
// logger.info(`RT: ${topic}, ${payload}`)
|
||||
if (topic == this.deviceStatusTopic) {
|
||||
// logger.info(`RT: status received`)
|
||||
this.status = JSON.parse(payload)
|
||||
let statusParsed = JSON.stringify(this.status)
|
||||
this.switchStates = JSON.stringify(this.status.data.switchStates)
|
||||
if (this.switchStates != this.oldSwitchStates) {
|
||||
this.oldSwitchStates = this.switchStates
|
||||
logger.info(`RT: status parsed: ${statusParsed}`)
|
||||
logger.info(`RT: device: ${this.status.metadata.device}`)
|
||||
logger.info(`RT: uptime: ${this.status.data.uptime}`)
|
||||
for (let i : number = 0; i < this.itemNames.length; i ++) {
|
||||
if (this.status.data.switchStates[i].feedbackState == '0') {
|
||||
mqttHandler.send(`${this.feedbackTopicPre}/${i}`, 'OFF')
|
||||
} else {
|
||||
mqttHandler.send(`${this.feedbackTopicPre}/${i}`, 'ON')
|
||||
}
|
||||
if (this.status.data.switchStates[i].stateConflict == '0') {
|
||||
mqttHandler.send(`${this.conflictTopicPre}/${i}`, 'CLEAR')
|
||||
} else {
|
||||
mqttHandler.send(`${this.conflictTopicPre}/${i}`, 'CONFLICT')
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.info(`RT: ${topic}, ${payload}`)
|
||||
let thingRelatedPart = topic.substring(this.stateTopicPre.length+1)
|
||||
let itemIdx = parseInt(thingRelatedPart)
|
||||
logger.info(`RT: pre: ${this.stateTopicPre}, thingRelatedPart: ${thingRelatedPart}, itemIdx: ${itemIdx}`)
|
||||
if (itemIdx >= 0 && itemIdx < this.itemNames.length) {
|
||||
if (payload == 'ON') {
|
||||
mqttHandler.send(this.deviceCommandTopic, `switch ${itemIdx} on`)
|
||||
} else {
|
||||
mqttHandler.send(this.deviceCommandTopic, `switch ${itemIdx} off`)
|
||||
}
|
||||
} else {
|
||||
logger.warn(`RT: no handling available for ${topic}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
105
src/Scene.ts
Normal file
105
src/Scene.ts
Normal file
@ -0,0 +1,105 @@
|
||||
import { AItem, HasStateAndFeedbackTopic } from './AItem'
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { ExportType, SwitchExport } from './Export'
|
||||
|
||||
export class LightScene extends AItem implements HasStateAndFeedbackTopic {
|
||||
private onFeedbackTopics: string[]
|
||||
private offFeedbackTopics: string[]
|
||||
private onTopics: string[]
|
||||
private offTopics: string[]
|
||||
private onFeedbackMap: { [key:string]:string }
|
||||
private offFeedbackMap: { [key:string]:string }
|
||||
private state: string
|
||||
private stateFeedbackTopic: string
|
||||
private stateTopic: string
|
||||
private offItems: HasStateAndFeedbackTopic[]
|
||||
private onItems: HasStateAndFeedbackTopic[]
|
||||
private myLastFeedbackState: string
|
||||
|
||||
getStateTopic() {
|
||||
return this.stateTopic
|
||||
}
|
||||
getStateFeedbackTopic() {
|
||||
return this.stateFeedbackTopic
|
||||
}
|
||||
|
||||
constructor(floor: string, room: string, item: string, label: string = '',
|
||||
onItems: HasStateAndFeedbackTopic[], offItems: HasStateAndFeedbackTopic[]) {
|
||||
super(floor, room, item, label)
|
||||
this.onItems = onItems
|
||||
this.offItems = offItems
|
||||
this.stateTopic = `${this.topicFirstPart}/state`
|
||||
this.stateFeedbackTopic = `${this.topicFirstPart}/state/feedback`
|
||||
this.subscribeTopics = []
|
||||
this.subscribeTopics.push(this.stateTopic)
|
||||
this.onFeedbackTopics = []
|
||||
this.onTopics = []
|
||||
this.onFeedbackMap = {}
|
||||
this.onItems.forEach((item: HasStateAndFeedbackTopic) => {
|
||||
this.subscribeTopics.push(item.getStateFeedbackTopic())
|
||||
this.onFeedbackTopics.push(item.getStateFeedbackTopic())
|
||||
this.onTopics.push(item.getStateTopic())
|
||||
this.onFeedbackMap[item.getStateFeedbackTopic()] = '-'
|
||||
})
|
||||
this.offFeedbackTopics = []
|
||||
this.offTopics = []
|
||||
this.offFeedbackMap = {}
|
||||
this.offItems.forEach((item: HasStateAndFeedbackTopic) => {
|
||||
this.subscribeTopics.push(item.getStateFeedbackTopic())
|
||||
this.offFeedbackTopics.push(item.getStateFeedbackTopic())
|
||||
this.offTopics.push(item.getStateTopic())
|
||||
this.offFeedbackMap[item.getStateFeedbackTopic()] = '-'
|
||||
})
|
||||
this.state = 'OFF'
|
||||
this.myLastFeedbackState = '-'
|
||||
}
|
||||
|
||||
exportItem() : ExportType|null {
|
||||
return SwitchExport(this.itemId, this.label, this.stateTopic, this.stateFeedbackTopic, 'bulb')
|
||||
}
|
||||
|
||||
processMessage(topic: string, payload: string) : void {
|
||||
if (topic == this.stateTopic) {
|
||||
this.state = payload
|
||||
if (this.state == 'ON') {
|
||||
this.onTopics.forEach((topic2: string) => {
|
||||
mqttHandler.send(topic2, 'ON')
|
||||
})
|
||||
this.offTopics.forEach((topic2: string) => {
|
||||
mqttHandler.send(topic2, 'OFF')
|
||||
})
|
||||
} else {
|
||||
this.onTopics.forEach((topic2: string) => {
|
||||
mqttHandler.send(topic2, 'OFF')
|
||||
})
|
||||
this.offTopics.forEach((topic2: string) => {
|
||||
mqttHandler.send(topic2, 'OFF')
|
||||
})
|
||||
}
|
||||
} else if (this.onFeedbackTopics.some((x) => { return x == topic })) {
|
||||
let feedbackState = payload
|
||||
this.onFeedbackMap[topic] = feedbackState
|
||||
} else if (this.offFeedbackTopics.some((x) => { return x == topic })) {
|
||||
let feedbackState = payload
|
||||
this.offFeedbackMap[topic] = feedbackState
|
||||
}
|
||||
|
||||
let myFeedbackState = 'ON'
|
||||
Object.values(this.onFeedbackMap).forEach((v: string) => {
|
||||
if (v != 'ON') {
|
||||
myFeedbackState = 'OFF'
|
||||
}
|
||||
})
|
||||
Object.values(this.offFeedbackMap).forEach((v: string) => {
|
||||
if (v != 'OFF') {
|
||||
myFeedbackState = 'OFF'
|
||||
}
|
||||
})
|
||||
if (myFeedbackState != this.myLastFeedbackState) {
|
||||
mqttHandler.send(this.stateFeedbackTopic, myFeedbackState)
|
||||
this.myLastFeedbackState = myFeedbackState
|
||||
}
|
||||
}
|
||||
|
||||
}
|
58
src/TouchSwitchMultiButtonThing.ts
Normal file
58
src/TouchSwitchMultiButtonThing.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { AItem } from './AItem'
|
||||
|
||||
|
||||
export class TouchSwitchButtonSingleItem {
|
||||
private actionTopic: string
|
||||
|
||||
constructor(actionTopic: string) {
|
||||
this.actionTopic = actionTopic
|
||||
}
|
||||
|
||||
processMessage(topic: string, payload: string) {
|
||||
switch(payload) {
|
||||
case 'SHORT':
|
||||
mqttHandler.send(this.actionTopic, 'SHORT', true)
|
||||
break
|
||||
case 'LONG_BEGIN':
|
||||
case 'LONG_CONT':
|
||||
mqttHandler.send(this.actionTopic, 'LONG_HOLD', true)
|
||||
break
|
||||
case 'LONG_END':
|
||||
mqttHandler.send(this.actionTopic, 'LONG_END', true)
|
||||
break
|
||||
default:
|
||||
logger.warn(`TWBSI: no handling available for ${topic}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class TouchSwitchMultiButtonThing extends AItem {
|
||||
private itemObjs: TouchSwitchButtonSingleItem[]
|
||||
private readonly deviceTopicPre: string
|
||||
|
||||
constructor(floor: string, room: string, item: string, itemObjs: TouchSwitchButtonSingleItem[]) {
|
||||
super(floor, room, item, '')
|
||||
this.itemObjs = itemObjs
|
||||
this.deviceTopicPre = `IoT/TouchSwitch/${this.floor}/${this.room}/${this.item}`
|
||||
this.subscribeTopics = [
|
||||
`${this.deviceTopicPre}/#`
|
||||
]
|
||||
}
|
||||
|
||||
processMessage(topic: string, payload: string) {
|
||||
logger.info(`TSMBT: ${topic}, ${payload}`)
|
||||
let buttonRelatedPart = topic.substring(this.deviceTopicPre.length+1)
|
||||
let buttonIdx = parseInt(buttonRelatedPart)
|
||||
logger.info(`TSMBT: pre: ${this.deviceTopicPre}, buttonRelatedPart: ${buttonRelatedPart}, buttonIdx: ${buttonIdx}`)
|
||||
if (buttonIdx >= 1 && buttonIdx <= this.itemObjs.length) {
|
||||
this.itemObjs[buttonIdx-1].processMessage('-', payload)
|
||||
} else {
|
||||
logger.warn(`TSMBT: no handling available for ${topic}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
56
src/UrlSwitchItem.ts
Normal file
56
src/UrlSwitchItem.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import * as logger from './log'
|
||||
import { mqttHandler } from './MqttDispatcher'
|
||||
import { AItem, HasStateAndFeedbackTopic } from './AItem'
|
||||
import { SwitchExport, ExportType } from './Export'
|
||||
import * as http from 'http'
|
||||
|
||||
|
||||
export class UrlSwitchItem extends AItem implements HasStateAndFeedbackTopic {
|
||||
private offUrl: string
|
||||
private onUrl: string
|
||||
private oldState: string|undefined
|
||||
private state: string
|
||||
private actionTopic: string
|
||||
private stateFeedbackTopic: string
|
||||
private stateTopic: string
|
||||
private type: string
|
||||
|
||||
getStateTopic() : string {
|
||||
return this.stateTopic
|
||||
}
|
||||
|
||||
getStateFeedbackTopic() : string {
|
||||
return this.stateFeedbackTopic
|
||||
}
|
||||
|
||||
constructor(floor: string, room: string, item: string, label: string, onUrl: string, offUrl: string, type: string = 'bulb') {
|
||||
super(floor, room, item, label)
|
||||
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.onUrl = onUrl
|
||||
this.offUrl = offUrl
|
||||
this.type = type
|
||||
}
|
||||
|
||||
exportItem() : ExportType|null {
|
||||
return SwitchExport(this.itemId, this.label, this.stateTopic, this.stateFeedbackTopic, this.type)
|
||||
}
|
||||
|
||||
processMessage(topic: string, payload: string) {
|
||||
this.state = payload;
|
||||
mqttHandler.send(this.stateFeedbackTopic, this.state);
|
||||
if (this.state != this.oldState) {
|
||||
if (this.state == 'ON') {
|
||||
http.get(this.onUrl)
|
||||
} else {
|
||||
http.get(this.offUrl)
|
||||
}
|
||||
this.oldState = this.state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
282
src/main.ts
282
src/main.ts
@ -13,12 +13,21 @@ import { TimerAdaptor } from './TimerAdaptor'
|
||||
import { HomematicDimmerItem } from './HomematicDimmerItem'
|
||||
import { HomematicSwitchItem } from './HomematicSwitchItem'
|
||||
import { Forwarder } from './Forwarder'
|
||||
|
||||
import { LightScene } from './Scene'
|
||||
import { MaxEcoSwitch } from './MaxEcoSwitch'
|
||||
import { MaxThermostat } from './MaxThermostat'
|
||||
import { MaxWindowContact } from './MaxWindowContact'
|
||||
import { UrlSwitchItem } from './UrlSwitchItem'
|
||||
import { Cron } from './Cron'
|
||||
import { HueColorBulbItem } from './HueColorBulbItem'
|
||||
import { TouchSwitchMultiButtonThing, TouchSwitchButtonSingleItem } from './TouchSwitchMultiButtonThing'
|
||||
import { RelayBoxThing } from './RelayBox'
|
||||
import { GeoFences, AttendanceSheetType } from './GeoFences'
|
||||
|
||||
|
||||
logger.info("Dispatcher starting")
|
||||
|
||||
let allLabeledItems : Array<AItem> = new Array<AItem>()
|
||||
let allLabeledItems : Array<AItem> = new Array()
|
||||
|
||||
|
||||
// Anna -----------------------------------------------------------------------------------------------------
|
||||
@ -27,14 +36,47 @@ let aquariumLight = new M433SwitchItem('1st', 'Anna', 'AquariumLight', 'Aquarium
|
||||
aquariumLight.start()
|
||||
allLabeledItems.push(aquariumLight)
|
||||
|
||||
|
||||
let aquariumLightCron = new Cron('aquariumLightCron', aquariumLight, [
|
||||
{cronTime: '00 00 07 * * 1-5', output: 'ON'},
|
||||
{cronTime: '00 00 09 * * 6,0', output: 'ON'},
|
||||
{cronTime: '00 00 13 * * *', output: 'OFF'},
|
||||
{cronTime: '00 00 14 * * *', output: 'ON'},
|
||||
{cronTime: '00 00 22 * * *', output: 'OFF'}
|
||||
])
|
||||
aquariumLightCron.start()
|
||||
|
||||
|
||||
// Anna Bett 14668116 24 1 14668113 24 1
|
||||
let annaBedLight = new M433SwitchItem('1st', 'Anna', 'BedLight', 'Bettlicht Anna', '14668116 24 1', '14668113 24 1')
|
||||
annaBedLight.start()
|
||||
allLabeledItems.push(annaBedLight)
|
||||
|
||||
|
||||
let windowContactAnna1st = new MaxWindowContact('1st', 'Anna', 'WindowContact', 'Fenster Anna', 20)
|
||||
windowContactAnna1st.start()
|
||||
allLabeledItems.push(windowContactAnna1st)
|
||||
|
||||
let thermostatAnna1st = new MaxThermostat('1st', 'Anna', 'Thermostat', 'Thermostat Anna', 21, [windowContactAnna1st])
|
||||
thermostatAnna1st.start()
|
||||
thermostatAnna1st.setPresetTemperature(21.0)
|
||||
allLabeledItems.push(thermostatAnna1st)
|
||||
|
||||
let thermostatAnna1stCron = new Cron('thermostatAnna1stCron', thermostatAnna1st, [
|
||||
{cronTime: '00 05 06 * * *', output: 'ON'},
|
||||
{cronTime: '00 05 08 * * 1-5', output: 'OFF'},
|
||||
{cronTime: '00 05 16 * * 1', output: 'ON'},
|
||||
{cronTime: '00 05 14 * * 2', output: 'ON'},
|
||||
{cronTime: '00 05 14 * * 3', output: 'ON'},
|
||||
{cronTime: '00 05 16 * * 4', output: 'ON'},
|
||||
{cronTime: '00 05 14 * * 5', output: 'ON'},
|
||||
{cronTime: '00 58 23 * * *', output: 'OFF'}
|
||||
])
|
||||
thermostatAnna1stCron.start()
|
||||
|
||||
// Matthias -------------------------------------------------------------------------------------------------
|
||||
// Matthias Stehlampen 7 24 1 6 24 1
|
||||
let matthiasStandLights = new M433SwitchItem('1st', 'Matthias', 'Stehlampen Matthias', 'StandLight', '7 24 1', '6 24 1')
|
||||
let matthiasStandLights = new M433SwitchItem('1st', 'Matthias', 'StandLight', 'Stehlampen Matthias', '7 24 1', '6 24 1')
|
||||
matthiasStandLights.start()
|
||||
allLabeledItems.push(matthiasStandLights)
|
||||
|
||||
@ -64,6 +106,15 @@ let diningRoomCupboardLight = new M433SwitchItem('Gnd', 'DiningRoom', 'CupboardL
|
||||
diningRoomCupboardLight.start()
|
||||
allLabeledItems.push(diningRoomCupboardLight)
|
||||
|
||||
// Esszimmer Regallicht
|
||||
let diningRoomShelfLight = new UrlSwitchItem('Gnd', 'DiningRoom', 'ShelfLight', 'Regallicht Esszimmer', 'http://regallampe/dv?dv=1023', 'http://regallampe/dv?dv=0')
|
||||
diningRoomShelfLight.start()
|
||||
allLabeledItems.push(diningRoomShelfLight)
|
||||
|
||||
let diningRoomNaehkaestchenLight = new HueColorBulbItem('Gnd', 'DiningRoom', 'NaehkaestchenLight', 'Lampe Naehkaestchen', 15)
|
||||
diningRoomNaehkaestchenLight.start()
|
||||
allLabeledItems.push(diningRoomNaehkaestchenLight)
|
||||
|
||||
// Wohnzimmer -----------------------------------------------------------------------------------------------
|
||||
// Wohnzimmer grosse Lampe 65557 24 1 65556 24 1
|
||||
let livingRoomLargeLight = new M433SwitchItem('Gnd', 'LivingRoom', 'LargeLight', 'große Lampe Wohnzimmer', '65557 24 1', '65556 24 1')
|
||||
@ -121,6 +172,17 @@ let bedRoomWolfgangsSide = new M433SwitchItem('1st', 'BedRoom', 'WolfgangsSide',
|
||||
bedRoomWolfgangsSide.start()
|
||||
allLabeledItems.push(bedRoomWolfgangsSide)
|
||||
|
||||
let bedRoomWolfgangBedLight = new HueColorBulbItem('1st', 'BedRoom', 'WolfgangBedLight', 'Bettlicht', 16)
|
||||
bedRoomWolfgangBedLight.start()
|
||||
allLabeledItems.push(bedRoomWolfgangBedLight)
|
||||
|
||||
let bedRoomWolfgangBedLightDimmerAdaptor = new DimmerAdaptor('1st', 'BedRoom', 'WolfgangBedLight')
|
||||
bedRoomWolfgangBedLightDimmerAdaptor.start()
|
||||
|
||||
let touchSwitchMultiButtonThing = new TouchSwitchMultiButtonThing('1st', 'Bedroom', 'Wolfgang',
|
||||
[ new TouchSwitchButtonSingleItem(bedRoomWolfgangBedLightDimmerAdaptor.getInTopic())])
|
||||
touchSwitchMultiButtonThing.start()
|
||||
|
||||
// Schlafzimmer Pattys Seite 13980756 24 1 13980753 24 1
|
||||
let bedRoomPattysSide = new M433SwitchItem('1st', 'BedRoom', 'PattysSide', 'Pattys Seite Schlafzimmer', '13980756 24 1', '13980753 24 1')
|
||||
bedRoomPattysSide.start()
|
||||
@ -132,43 +194,164 @@ bedRoomWindowLight.start()
|
||||
allLabeledItems.push(bedRoomWindowLight)
|
||||
|
||||
|
||||
|
||||
let windowContactBedroomStreet1st = new MaxWindowContact('1st', 'Bedroom', 'WindowContactStreet', 'Fenster Schlafzimmer Strasse', 17)
|
||||
windowContactBedroomStreet1st.start()
|
||||
allLabeledItems.push(windowContactBedroomStreet1st)
|
||||
let windowContact1BedroomGarden1st = new MaxWindowContact('1st', 'Bedroom', 'WindowContact1Garden', 'Fenster Schlafzimmer 1 Garten', 18)
|
||||
windowContact1BedroomGarden1st.start()
|
||||
allLabeledItems.push(windowContact1BedroomGarden1st)
|
||||
let windowContact2BedroomGarden1st = new MaxWindowContact('1st', 'Bedroom', 'WindowContact2Garden', 'Fenster Schlafzimmer 2 Garten', 22)
|
||||
windowContact2BedroomGarden1st.start()
|
||||
allLabeledItems.push(windowContact2BedroomGarden1st)
|
||||
|
||||
let thermostatBedroom1st = new MaxThermostat('1st', 'Bedroom', 'Thermostat', 'Thermostat Schlafzimmer', 19, [windowContact1BedroomGarden1st, windowContact2BedroomGarden1st, windowContactBedroomStreet1st])
|
||||
thermostatBedroom1st.start()
|
||||
thermostatBedroom1st.setPresetTemperature(20.0)
|
||||
allLabeledItems.push(thermostatBedroom1st)
|
||||
|
||||
let thermostatBedroom1stCron = new Cron('thermostatBedroom1stCron', thermostatBedroom1st, [
|
||||
{cronTime: '00 01 06 * * 1-5', output: 'ON'},
|
||||
{cronTime: '00 01 09 * * 1-5', output: 'OFF'},
|
||||
{cronTime: '00 01 08 * * 6,0', output: 'ON'},
|
||||
{cronTime: '00 01 11 * * 6,0', output: 'OFF'},
|
||||
{cronTime: '00 00 17 * * *', output: 'ON'},
|
||||
{cronTime: '00 59 23 * * *', output: 'OFF'}
|
||||
])
|
||||
thermostatBedroom1stCron.start()
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------
|
||||
let morningLightForwarder = new Forwarder('Gnd', 'Hallway', 'MorningLight', 'state', 'MorningLight', [
|
||||
kitchenWindowLight.stateTopic,
|
||||
kitchenCeilingLight.stateTopic,
|
||||
hallwayDeskLight.stateTopic,
|
||||
hallwayStandLight.stateTopic,
|
||||
hallwayWardrobeLight.stateTopic
|
||||
])
|
||||
morningLightForwarder.start()
|
||||
let dayLightScene = new LightScene('Gnd', 'Hallway', 'DayLight', 'DayLight',
|
||||
[
|
||||
kitchenWindowLight, kitchenCeilingLight, hallwayDeskLight, hallwayStandLight, hallwayWardrobeLight,
|
||||
diningRoomSmallLight, diningRoomStandLight, diningRoomCupboardLight, diningRoomShelfLight,
|
||||
livingRoomLargeLight, livingRoomSmallLight, livingRoomStars, livingRoomStandLight, diningRoomNaehkaestchenLight
|
||||
],
|
||||
[]
|
||||
)
|
||||
dayLightScene.start()
|
||||
allLabeledItems.push(dayLightScene)
|
||||
|
||||
let dayLightForwarder = new Forwarder('Gnd', 'Hallway', 'DayLight', 'state', 'DayLight', [
|
||||
kitchenWindowLight.stateTopic,
|
||||
kitchenCeilingLight.stateTopic,
|
||||
hallwayDeskLight.stateTopic,
|
||||
hallwayStandLight.stateTopic,
|
||||
hallwayWardrobeLight.stateTopic,
|
||||
diningRoomSmallLight.stateTopic,
|
||||
diningRoomStandLight.stateTopic,
|
||||
diningRoomCupboardLight.stateTopic,
|
||||
livingRoomLargeLight.stateTopic,
|
||||
livingRoomSmallLight.stateTopic,
|
||||
livingRoomStars.stateTopic,
|
||||
livingRoomStandLight.stateTopic
|
||||
])
|
||||
dayLightForwarder.start()
|
||||
let ecoLightScene = new LightScene('Gnd', 'Hallway', 'EcoLight', 'EcoLight',
|
||||
[
|
||||
kitchenWindowLight, hallwayDeskLight, hallwayWardrobeLight,
|
||||
diningRoomSmallLight, diningRoomStandLight, diningRoomCupboardLight, diningRoomShelfLight,
|
||||
livingRoomStars, livingRoomStandLight, diningRoomNaehkaestchenLight
|
||||
],
|
||||
[
|
||||
kitchenCeilingLight, hallwayStandLight,
|
||||
livingRoomLargeLight, livingRoomSmallLight
|
||||
]
|
||||
)
|
||||
ecoLightScene.start()
|
||||
allLabeledItems.push(ecoLightScene)
|
||||
|
||||
let ecoLightForwarder = new Forwarder('Gnd', 'Hallway', 'EcoLight', 'state', 'EcoLight', [
|
||||
kitchenWindowLight.stateTopic,
|
||||
hallwayDeskLight.stateTopic,
|
||||
hallwayWardrobeLight.stateTopic,
|
||||
diningRoomSmallLight.stateTopic,
|
||||
diningRoomStandLight.stateTopic,
|
||||
diningRoomCupboardLight.stateTopic,
|
||||
livingRoomStars.stateTopic,
|
||||
livingRoomStandLight.stateTopic
|
||||
let ecoSwitch = new MaxEcoSwitch('Gnd', 'Hallway', 'EcoSwitch', 'EcoSwitch', 6, dayLightScene, ecoLightScene)
|
||||
ecoSwitch.start()
|
||||
|
||||
let morningLightScene = new LightScene('Gnd', 'Hallway', 'MorningLight', 'MorningLight',
|
||||
[
|
||||
kitchenWindowLight, kitchenCeilingLight, hallwayDeskLight, hallwayWardrobeLight,
|
||||
hallwayStandLight
|
||||
],
|
||||
[
|
||||
diningRoomSmallLight, diningRoomStandLight, diningRoomCupboardLight, diningRoomShelfLight,
|
||||
livingRoomStars, livingRoomStandLight, livingRoomLargeLight, livingRoomSmallLight, diningRoomNaehkaestchenLight
|
||||
]
|
||||
)
|
||||
morningLightScene.start()
|
||||
allLabeledItems.push(morningLightScene)
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
let windowContactBathroomGnd = new MaxWindowContact('Gnd', 'Bathroom', 'WindowContact', 'Fenster Bad unten', 7)
|
||||
windowContactBathroomGnd.start()
|
||||
allLabeledItems.push(windowContactBathroomGnd)
|
||||
|
||||
let thermostatBathroomGnd = new MaxThermostat('Gnd', 'Bathroom', 'Thermostat', 'Thermostat Bad unten', 4, [windowContactBathroomGnd])
|
||||
thermostatBathroomGnd.start()
|
||||
thermostatBathroomGnd.setPresetTemperature(20.0)
|
||||
allLabeledItems.push(thermostatBathroomGnd)
|
||||
|
||||
let thermostatBathroomGndCron = new Cron('thermostatBathroomGndCron', thermostatBathroomGnd, [
|
||||
{cronTime: '00 02 06 * * 1-5', output: 'ON'},
|
||||
{cronTime: '00 02 08 * * 6,0', output: 'ON'},
|
||||
{cronTime: '00 02 11 * * *', output: 'OFF'},
|
||||
{cronTime: '00 02 19 * * *', output: 'ON'},
|
||||
{cronTime: '00 00 23 * * *', output: 'OFF'}
|
||||
])
|
||||
ecoLightForwarder.start()
|
||||
thermostatBathroomGndCron.start()
|
||||
|
||||
|
||||
let windowContactBathroom1st = new MaxWindowContact('1st', 'Bathroom', 'WindowContact', 'Fenster Bad oben', 2)
|
||||
windowContactBathroom1st.start()
|
||||
allLabeledItems.push(windowContactBathroom1st)
|
||||
|
||||
let thermostatBathroom1st = new MaxThermostat('1st', 'Bathroom', 'Thermostat', 'Thermostat Bad oben', 3, [windowContactBathroom1st])
|
||||
thermostatBathroom1st.start()
|
||||
thermostatBathroom1st.setPresetTemperature(20.0)
|
||||
allLabeledItems.push(thermostatBathroom1st)
|
||||
|
||||
let thermostatBathroom1stCron = new Cron('thermostatBathroom1stCron', thermostatBathroom1st, [
|
||||
{cronTime: '00 00 06 * * 1-5', output: 'ON'},
|
||||
{cronTime: '00 00 08 * * 6,0', output: 'ON'},
|
||||
{cronTime: '00 00 11 * * *', output: 'OFF'},
|
||||
{cronTime: '00 00 19 * * *', output: 'ON'},
|
||||
{cronTime: '00 00 23 * * *', output: 'OFF'}
|
||||
])
|
||||
thermostatBathroom1stCron.start()
|
||||
|
||||
|
||||
|
||||
let windowContactKitchen1 = new MaxWindowContact('Gnd', 'Kitchen', 'WindowContact1', 'Fenster Küche Garten', 11)
|
||||
windowContactKitchen1.start()
|
||||
allLabeledItems.push(windowContactKitchen1)
|
||||
let windowContactKitchen2 = new MaxWindowContact('Gnd', 'Kitchen', 'WindowContact2', 'Fenster Küche Terassentür Garten', 10)
|
||||
windowContactKitchen2.start()
|
||||
allLabeledItems.push(windowContactKitchen2)
|
||||
let windowContactKitchen3 = new MaxWindowContact('Gnd', 'Kitchen', 'WindowContact3', 'Fenster Küche Straße 1', 12)
|
||||
windowContactKitchen3.start()
|
||||
allLabeledItems.push(windowContactKitchen3)
|
||||
let windowContactKitchen4 = new MaxWindowContact('Gnd', 'Kitchen', 'WindowContact4', 'Fenster Küche Straße 2', 13)
|
||||
windowContactKitchen4.start()
|
||||
allLabeledItems.push(windowContactKitchen4)
|
||||
|
||||
let thermostatKitchen = new MaxThermostat('Gnd', 'Kitchen', 'Thermostat', 'Thermostat Küche', 14, [
|
||||
windowContactKitchen1, windowContactKitchen2, windowContactKitchen3, windowContactKitchen4])
|
||||
thermostatKitchen.start()
|
||||
thermostatKitchen.setPresetTemperature(20.0)
|
||||
allLabeledItems.push(thermostatKitchen)
|
||||
|
||||
let thermostatKitchenCron = new Cron('thermostatKitchenCron', thermostatKitchen, [
|
||||
{cronTime: '00 00 06 * * 1-5', output: 'ON'},
|
||||
{cronTime: '00 00 08 * * 6,0', output: 'ON'},
|
||||
{cronTime: '00 00 10 * * 1-3', output: 'OFF'},
|
||||
{cronTime: '00 30 13 * * 1-3', output: 'ON'},
|
||||
{cronTime: '00 00 23 * * *', output: 'OFF'}
|
||||
])
|
||||
thermostatKitchenCron.start()
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
let windowContactFrontdoor = new MaxWindowContact('Gnd', 'Hallway', 'FrontdoorContact', 'Haustür', 23)
|
||||
windowContactFrontdoor.start()
|
||||
allLabeledItems.push(windowContactFrontdoor)
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
let relayBox = new RelayBoxThing('base', 'labor', 'relaybox', 'IoT/Command/RelayBox', 'IoT/Status/RelayBox', [
|
||||
"Küche", "Herd", "Waschküche"
|
||||
])
|
||||
relayBox.start()
|
||||
allLabeledItems.push(relayBox)
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
let geoFences = new GeoFences()
|
||||
geoFences.exec()
|
||||
|
||||
geoFences.on('change', (attendanceSheet: AttendanceSheetType) => {
|
||||
logger.info(`geoFences change event: ${JSON.stringify(attendanceSheet)}`)
|
||||
})
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
let testFourButton = new HomematicFourButtonThing('Gnd', 'Hallway', 'TestButton', 9, [
|
||||
new HomematicFourButtonSingleItem('dispatcher_ng/items/Gnd/Hallway/Testlight/dimmerIn'),
|
||||
@ -197,21 +380,46 @@ let testForwarder = new Forwarder('Gnd', 'Hallway', 'TestForwarder', 'state', 'T
|
||||
testForwarder.start()
|
||||
|
||||
|
||||
let testScene = new LightScene('Gnd', 'Hallway', 'TestScene', 'TestScene',
|
||||
[aquariumLight, annaBedLight],
|
||||
[matthiasStandLights, matthiasBedLight]
|
||||
)
|
||||
testScene.start()
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
// Homekit export
|
||||
let homekitObject : { [key:string]:{} } = {}
|
||||
let openhabList : string[] = []
|
||||
|
||||
// logger.info("allLabeledItems")
|
||||
// logger.info(JSON.stringify(allLabeledItems))
|
||||
|
||||
allLabeledItems.forEach((item: AItem) => {
|
||||
let exportData : ExportType|null = item.exportItem()
|
||||
if (exportData != null) {
|
||||
if ('id' in exportData['homekit']) {
|
||||
homekitObject[exportData['homekit']['id']] = exportData['homekit']['object']
|
||||
}
|
||||
openhabList.push(exportData['openhab'])
|
||||
if (exportData['openhab'] instanceof Array) {
|
||||
let da : string[] = exportData['openhab'] as string[]
|
||||
da.forEach((o: string) => openhabList.push(o))
|
||||
} else {
|
||||
let da : string = exportData['openhab'] as string
|
||||
openhabList.push(da)
|
||||
}
|
||||
// logger.info("openHabList")
|
||||
// logger.info(JSON.stringify(openhabList))
|
||||
}
|
||||
})
|
||||
|
||||
let heatingMainSwitchExport : ExportType|null = MaxThermostat.exportHeatingMainSwitchItem()
|
||||
if (heatingMainSwitchExport != null) {
|
||||
let da : string = heatingMainSwitchExport['openhab'] as string
|
||||
openhabList.push(da)
|
||||
}
|
||||
|
||||
fs.writeFileSync(config.dict.homekitFile, JSON.stringify(homekitObject, null, 4))
|
||||
fs.writeFileSync(config.dict.openhabItemFile, openhabList.join('\n'))
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"target": "es2017",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"lib": ["es6"],
|
||||
"lib": ["es2017"],
|
||||
"strictNullChecks": true,
|
||||
"noImplicitAny": true,
|
||||
"noEmitOnError": true,
|
||||
|
Reference in New Issue
Block a user