mqtt: always send globally, always retain, thermostat und windowContact completed

This commit is contained in:
Wolfgang Hottgenroth
2018-01-15 17:10:42 +01:00
parent f88cf5ee0d
commit 09a63fe736
8 changed files with 179 additions and 32 deletions

50
dist/MaxThermostat.js vendored Normal file
View File

@ -0,0 +1,50 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const MqttDispatcher_1 = require("./MqttDispatcher");
const AHomematicItem_1 = require("./AHomematicItem");
// import { SwitchExport, ExportType } from './Export'
const WINDOW_OPEN_TEMPERATURE = 4.5;
class MaxThermostat extends AHomematicItem_1.AHomematicItem {
// Thermostat: homegear/instance1/set/3/1/SET_TEMPERATURE
constructor(floor, room, item, label, hmId, windowContacts) {
super(floor, room, item, label, hmId);
this.temperatureTopic = `${this.topicFirstPart}/temperature`;
this.temperatureFeedbackTopic = `${this.topicFirstPart}/temperature/feedback`;
this.deviceFeedbackTopic = `${this.deviceTopicPre}/1/SET_TEMPERATURE`;
this.actionTopic = `${this.actionTopicPre}/1/SET_TEMPERATURE`;
this.subscribeTopics = [
this.temperatureTopic,
this.deviceFeedbackTopic
];
this.windowOpen = false;
this.windowContactMap = {};
windowContacts.forEach((windowContact) => {
this.subscribeTopics.push(windowContact.getStateFeedbackTopic());
this.windowContactMap[windowContact.getStateFeedbackTopic()] = { windowContact: windowContact, state: 'unknown' };
});
}
processMessage(topic, payload) {
if ((topic == this.temperatureTopic) || (topic == this.deviceFeedbackTopic)) {
this.temperature = parseFloat(payload);
}
else if (topic in this.windowContactMap) {
this.windowContactMap[topic].state = payload;
this.windowOpen = false;
Object.values(this.windowContactMap).forEach((w) => {
if (w.state == 'OPEN') {
this.windowOpen = true;
}
});
}
if (!this.windowOpen) {
MqttDispatcher_1.mqttHandler.send(this.temperatureFeedbackTopic, `${this.temperature}`);
MqttDispatcher_1.mqttHandler.send(this.actionTopic, `${this.temperature}`);
}
else {
MqttDispatcher_1.mqttHandler.send(this.temperatureFeedbackTopic, `${WINDOW_OPEN_TEMPERATURE}`);
MqttDispatcher_1.mqttHandler.send(this.actionTopic, `${WINDOW_OPEN_TEMPERATURE}`);
}
}
}
exports.MaxThermostat = MaxThermostat;
//# sourceMappingURL=MaxThermostat.js.map

26
dist/MaxWindowContact.js vendored Normal file
View File

@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const MqttDispatcher_1 = require("./MqttDispatcher");
const AHomematicItem_1 = require("./AHomematicItem");
// import { SwitchExport, ExportType } from './Export'
class MaxWindowContact extends AHomematicItem_1.AHomematicItem {
getStateFeedbackTopic() {
return this.stateFeedbackTopic;
}
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
];
}
processMessage(topic, payload) {
this.state = payload;
MqttDispatcher_1.mqttHandler.send(this.stateFeedbackTopic, this.state);
}
}
exports.MaxWindowContact = MaxWindowContact;
//# sourceMappingURL=MaxWindowContact.js.map

View File

@ -70,18 +70,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}`);
let options = { retain: true, qos: 0 };
this.mqttClient.publish(topic, payload, options);
//} else {
// logger.info(`Internally delivered: ${topic}`)
//}
}
}
exports.mqttHandler = new MqttHandler();

44
dist/UrlSwitchItem.js vendored Normal file
View 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

8
dist/main.js vendored
View File

@ -13,6 +13,8 @@ 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");
logger.info("Dispatcher starting");
let allLabeledItems = new Array();
// Anna -----------------------------------------------------------------------------------------------------
@ -154,6 +156,12 @@ let testForwarder = new Forwarder_1.Forwarder('Gnd', 'Hallway', 'TestForwarder',
testForwarder.start();
let testScene = new Scene_1.LightScene('Gnd', 'Hallway', 'TestScene', 'TestScene', [aquariumLight, annaBedLight], [matthiasStandLights, matthiasBedLight]);
testScene.start();
let windowContact1 = new MaxWindowContact_1.MaxWindowContact('Gnd', 'Bathroom', 'WindowContact1', 'Fenster Bad unten', 2);
windowContact1.start();
let windowContact2 = new MaxWindowContact_1.MaxWindowContact('Gnd', 'Bathroom', 'WindowContact2', 'Fenster Bad unten', 20);
windowContact2.start();
let thermostat1 = new MaxThermostat_1.MaxThermostat('Gnd', 'Bathroom', 'Thermostat', 'Thermostat Bad unten', 3, [windowContact1, windowContact2]);
thermostat1.start();
// ----------------------------------------------------------------------------------------------------------
// Homekit export
let homekitObject = {};

View File

@ -7,14 +7,18 @@ import { MaxWindowContact } from './MaxWindowContact';
const WINDOW_OPEN_TEMPERATURE = 4.5
type WindowContactHolder = {
windowContact : MaxWindowContact
state : string
}
export class MaxThermostat extends AHomematicItem {
private actionTopic: string
private deviceFeedbackTopic: string
private temperatureFeedbackTopic: string
private temperatureTopic: string
private temperature: number
private windowContacts: MaxWindowContact[]
private windowContactTopics: string[]
private windowContactMap: { [key:string]: WindowContactHolder }
private windowOpen: boolean
// Thermostat: homegear/instance1/set/3/1/SET_TEMPERATURE
@ -28,32 +32,34 @@ export class MaxThermostat extends AHomematicItem {
this.temperatureTopic,
this.deviceFeedbackTopic
]
this.windowContacts = windowContacts
this.windowOpen = false
this.windowContactTopics = []
this.windowContacts.forEach((windowContact) => {
this.windowContactMap = {}
windowContacts.forEach((windowContact) => {
this.subscribeTopics.push(windowContact.getStateFeedbackTopic())
this.windowContactTopics.push(windowContact.getStateFeedbackTopic())
this.windowContactMap[windowContact.getStateFeedbackTopic()] = { windowContact: windowContact, state: 'unknown' }
})
}
processMessage(topic: string, payload: string) : void {
if (topic == this.temperatureTopic) {
if ((topic == this.temperatureTopic) || (topic == this.deviceFeedbackTopic)) {
this.temperature = parseFloat(payload)
mqttHandler.send(this.temperatureFeedbackTopic, `${this.temperature}`)
mqttHandler.send(this.actionTopic, `${this.temperature}`)
} else if (topic == this.deviceFeedbackTopic) {
this.temperature = parseFloat(payload)
mqttHandler.send(this.temperatureFeedbackTopic, `${this.temperature}`)
} else if (this.windowContactTopics.indexOf(topic) >= 0) {
if (payload == 'CLOSED') {
} else {
}
} else if (topic in this.windowContactMap) {
this.windowContactMap[topic].state = payload
this.windowOpen = false
Object.values(this.windowContactMap).forEach((w) => {
if (w.state == 'OPEN') {
this.windowOpen = true
}
})
}
if (! this.windowOpen) {
mqttHandler.send(this.temperatureFeedbackTopic, `${this.temperature}`)
mqttHandler.send(this.actionTopic, `${this.temperature}`)
} else {
mqttHandler.send(this.temperatureFeedbackTopic, `${WINDOW_OPEN_TEMPERATURE}`)
mqttHandler.send(this.actionTopic, `${WINDOW_OPEN_TEMPERATURE}`)
}
}

View File

@ -2,6 +2,7 @@ import * as logger from './log'
import * as Mqtt from 'mqtt'
import * as fs from 'fs'
import * as config from './config'
import { IClientPublishOptions } from 'mqtt';
@ -97,7 +98,8 @@ class MqttHandler {
//}
//if (! sent) {
logger.info(`External sending required: ${topic}`)
this.mqttClient.publish(topic, payload)
let options : IClientPublishOptions = { retain: true, qos: 0 }
this.mqttClient.publish(topic, payload, options)
//} else {
// logger.info(`Internally delivered: ${topic}`)
//}

View File

@ -15,6 +15,8 @@ import { HomematicSwitchItem } from './HomematicSwitchItem'
import { Forwarder } from './Forwarder'
import { LightScene } from './Scene'
import { MaxEcoSwitch } from './MaxEcoSwitch'
import { MaxThermostat } from './MaxThermostat'
import { MaxWindowContact } from './MaxWindowContact'
logger.info("Dispatcher starting")
@ -211,6 +213,15 @@ let testScene = new LightScene('Gnd', 'Hallway', 'TestScene', 'TestScene',
testScene.start()
let windowContact1 = new MaxWindowContact('Gnd', 'Bathroom', 'WindowContact1', 'Fenster Bad unten', 2)
windowContact1.start()
let windowContact2 = new MaxWindowContact('Gnd', 'Bathroom', 'WindowContact2', 'Fenster Bad unten', 20)
windowContact2.start()
let thermostat1 = new MaxThermostat('Gnd', 'Bathroom', 'Thermostat', 'Thermostat Bad unten', 3, [windowContact1, windowContact2])
thermostat1.start()
// ----------------------------------------------------------------------------------------------------------
// Homekit export
let homekitObject : { [key:string]:{} } = {}