rework thermostat

This commit is contained in:
2018-04-06 23:00:41 +02:00
parent 9db2aebf09
commit 37acc620d5
9 changed files with 134 additions and 50 deletions

4
src/Disabler.ts Normal file
View File

@ -0,0 +1,4 @@
export interface Disabler {
transform(payload: string) : string
getStateFeedbackTopic(): string
}

View File

@ -27,8 +27,8 @@ 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) : ExportType {
return {'homekit': ThermostatHomekitExport(itemId, label, temperatureTopic, temperatureFeedbackTopic), 'openhab': ThermostatOpenHAPExport(itemId, label, temperatureTopic, temperatureFeedbackTopic)}
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 {
@ -145,8 +145,11 @@ function ContactOpenHABExport(id: string, label: string, status: string): string
return `Contact ${id} "${label}" {mqtt="<[localbroker:${status}:state:default]"}`
}
function ThermostatOpenHAPExport(id: string, label: string, setTemperature: string, statusTemperature: string) : string {
return `Number ${id} "${label}" {mqtt=">[localbroker:${setTemperature}:command:*:default],<[localbroker:${statusTemperature}: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}" {mqtt=">[localbroker:${setTemperature}:command:*:default],<[localbroker:${statusTemperature}:state:default]"}`)
o.push(`Number Preset-${id} "Preset-${label}" {mqtt=">[localbroker:${presetTemperature}:command:*:default],<[localbroker:${presetStatusTemperature}:state:default]"}`)
return o
}
function HueColorLightHomekitExport(id: string, label: string,

View File

@ -2,14 +2,15 @@ import * as logger from './log'
import { mqttHandler } from './MqttDispatcher'
import { HasInTopic } from './AItem'
import { AHomegearItem } from './AHomegearItem'
import { MaxWindowContact } from './MaxWindowContact';
// import { MaxWindowContact } from './MaxWindowContact';
import { ThermostatExport, ExportType } from './Export'
import { Disabler } from './Disabler'
const WINDOW_OPEN_TEMPERATURE = 4.5
const DISABLED_TEMPERATURE = 5.0
type WindowContactHolder = {
windowContact : MaxWindowContact
type DisabledHolder = {
disabler : Disabler
state : string
}
@ -19,8 +20,13 @@ export class MaxThermostat extends AHomegearItem implements HasInTopic {
private temperatureFeedbackTopic: string
private temperatureTopic: string
private temperature: number
private windowContactMap: { [key:string]: WindowContactHolder }
private windowOpen: boolean
private presetTemperatureFeedbackTopic: string
private presetTemperatureTopic: string
private presetTemperature: number
private hardDisablerMap: { [key:string]: DisabledHolder }
private hardDisabled: boolean
private commandTopic: string
// Thermostat: homegear/instance1/set/3/1/SET_TEMPERATURE
getInTopic() : string {
@ -28,24 +34,29 @@ export class MaxThermostat extends AHomegearItem implements HasInTopic {
}
exportItem() : ExportType|null {
return ThermostatExport(this.itemId, this.label, this.temperatureTopic, this.temperatureFeedbackTopic)
return ThermostatExport(this.itemId, this.label, this.temperatureTopic, this.temperatureFeedbackTopic, this.presetTemperatureTopic, this.presetTemperatureFeedbackTopic)
}
constructor(floor: string, room: string, item: string, label: string, hmId: number, windowContacts: MaxWindowContact[]) {
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.deviceFeedbackTopic
this.presetTemperatureTopic,
this.deviceFeedbackTopic,
this.commandTopic
]
this.windowOpen = false
this.windowContactMap = {}
windowContacts.forEach((windowContact) => {
this.subscribeTopics.push(windowContact.getStateFeedbackTopic())
this.windowContactMap[windowContact.getStateFeedbackTopic()] = { windowContact: windowContact, state: 'unknown' }
this.hardDisabled = false
this.hardDisablerMap = {}
hardDisablers.forEach((hardDisabler) => {
this.subscribeTopics.push(hardDisabler.getStateFeedbackTopic())
this.hardDisablerMap[hardDisabler.getStateFeedbackTopic()] = { disabler: hardDisabler, state: 'unknown' }
})
}
@ -54,27 +65,37 @@ export class MaxThermostat extends AHomegearItem implements HasInTopic {
if (topic == this.temperatureTopic) {
this.temperature = parseFloat(payload)
setTemperature = true
} else if (topic == this.commandTopic) {
if (payload == 'START') {
this.temperature = this.presetTemperature
} else {
this.temperature = DISABLED_TEMPERATURE
}
setTemperature = true
} 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.windowContactMap) {
this.windowContactMap[topic].state = payload
this.windowOpen = false
Object.values(this.windowContactMap).forEach((w) => {
if (w.state == 'OPEN') {
this.windowOpen = true
} 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.windowOpen) {
if (! this.hardDisabled) {
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}`)
mqttHandler.send(this.temperatureFeedbackTopic, `${DISABLED_TEMPERATURE}`)
mqttHandler.send(this.actionTopic, `${DISABLED_TEMPERATURE}`)
}
}
}

View File

@ -2,8 +2,9 @@ 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 {
export class MaxWindowContact extends AHomegearItem implements Disabler {
private deviceFeedbackTopic: string
private stateFeedbackTopic: string
private stateTopic: string
@ -13,6 +14,18 @@ export class MaxWindowContact extends AHomegearItem {
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`