mqtt: always send globally, always retain, thermostat und windowContact completed
This commit is contained in:
50
dist/MaxThermostat.js
vendored
Normal file
50
dist/MaxThermostat.js
vendored
Normal 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
26
dist/MaxWindowContact.js
vendored
Normal 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
|
24
dist/MqttDispatcher.js
vendored
24
dist/MqttDispatcher.js
vendored
@ -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
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
|
8
dist/main.js
vendored
8
dist/main.js
vendored
@ -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 = {};
|
||||
|
@ -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}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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}`)
|
||||
//}
|
||||
|
11
src/main.ts
11
src/main.ts
@ -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]:{} } = {}
|
||||
|
Reference in New Issue
Block a user