da ich nun endlich meine steurung soweit fertig habe wollte ich diese gerne mal mit euch teilen.
Habe hier eine abgewandelte version von meiner weil ich jeden raum einzelnd habe.
Zu der item ich habe in Homematic die Thermostate und Fenster Kontakte in eine Gruppe gepackt und diese gruppe steuere ich über openhab dann an
heizung.items
Code: Alles auswählen
Group Whg "Home" <house>
String Whg_Heating_Mode "Heizmodus [%s]" <heating> (Whg)
// horizontale Gruppen
Group:Contact:OR(OPEN,CLOSED) Windows "Offene Fenster [%d]" <contact> (Whg)
Group Batteries "Batteriezustände" <battery> (Whg)
Group:Number:SUM Bat_Binary "Batteriezustände (Binary) [%d]" <battery> (Batteries)
Group:Number:MIN Bat_Percent "Batteriezustände (%) [%d %%]" <battery> (Batteries)
Group:Number:MIN Bat_Volts "Batteriezustände (Volt) [%.1f V]" <battery> (Batteries)
// Wartung / Maintenance
Group:Number:SUM Unreach_Group "Nicht erreichbare Geräte [%d]" <siren> (Whg)
Group:Number:SUM Pending_Group "Ausstehender Config [%d]" <siren> (Whg)
Group:Number:SUM Error_Group "Geräte mit Fehlerzustand [%d]" <error2> (Whg)
String Whg_Heating_Mode "Wohnung Heizmodus [%s]" <heating> (Whg)
Switch Whg_Heating_UpdateHeater "Sende Soll-Temperaturen an Heizkörper" <heating> (Whg)
Switch Whg_Wartung_Trigger "Wartungsroutinen auslösen" (Whg) {expire="5s"}
// Heizung und Fenster Gruppen
Group Heating_Group "Heizung Gesamt" <heating> (Whg)
Group:Number:AVG Heating_TargetTemps "Raumtemperaturen Soll [%.1f °C]" <temperature> (Heating_Group)
Group Heating_OpModes "Raumtemperaturen Mode [%.1f °C]" <"heating-off"> (Heating_Group)
Group:Number:AVG Heating_TargetPresets "Raumtemperaturen Soll Zeitprogramm [%.1f °C]" <line> (Heating_Group)
//INT0000001
Switch FZimmer_Unreach "Florian Zimmer" <siren> (Unreach_Group) {channel="homematic:HM-CC-VG-1:3014F711A0001F5A4993D3F2:INT0000001:0#UNREACH"}
Switch FZimmer_Pending "Florian Zimmer" <siren> (Pending_Group) {channel="homematic:HM-CC-VG-1:3014F711A0001F5A4993D3F2:INT0000001:0#CONFIG_PENDING"}
Switch FZimmer_LowBat "Florian LowBat" <battery> (Bat_Binary) {channel="homematic:HM-CC-VG-1:3014F711A0001F5A4993D3F2:INT0000001:0#LOWBAT"}
Contact FZimmer_Fenster_State "Fenster [MAP(window.map):%s]" <contact> (Windows) {channel="homematic:HM-Sec-SC-2:3014F711A0001F5A4993D3F2:OEQ1477775:1#STATE"}
String FZimmer_Fenster_Error "Fenster [MAP(HM-Sec-SCo.map):%s]" <error2> (Error_Group) {channel="homematic:HM-Sec-SC-2:3014F711A0001F5A4993D3F2:OEQ1477775:1#ERROR"}
Contact FZimmer_DachFenster_State "DachFenster [MAP(window.map):%s]" <contact> (Windows) {channel="homematic:HM-Sec-SC-2:3014F711A0001F5A4993D3F2:OEQ1477397:1#STATE"}
String FZimmer_DachFenster_Error "DachFenster [MAP(HM-Sec-SCo.map):%s]" <error2> (Error_Group) {channel="homematic:HM-Sec-SC-2:3014F711A0001F5A4993D3F2:OEQ1477397:1#ERROR"}
String FZimmer_Heizung_Fault "Heizung [MAP(HM-CC-RT-DN.map):%s]" <error2> (Error_Group) {channel="homematic:HM-CC-RT-DN:3014F711A0001F5A4993D3F2:QEQ1293126:4#FAULT_REPORTING"}
Number:ElectricPotential FZimmer_Heizung_Battery "Heizung [%.1f V]" <"battery-100"> (Heating,Bat_Volts) {channel="homematic:HM-CC-RT-DN:3014F711A0001F5A4993D3F2:QEQ1293126:4#BATTERY_STATE"}
//Gruppe
Number:Temperature FZimmer_ActTemp "Florian Heizung Ist-Temperatur [%.1f °C]" <temperature> (Heating) {channel="homematic:HM-CC-VG-1:3014F711A0001F5A4993D3F2:INT0000001:1#ACTUAL_TEMPERATURE"}
Number:Temperature FZimmer_SetTemp "Florian Heizung Soll-Temperatur [%.1f °C]" <temperature> (Heating,Heating_TargetTemps) {channel="homematic:HM-CC-VG-1:3014F711A0001F5A4993D3F2:INT0000001:1#SET_TEMPERATURE"}
String FZimmer_Mode "Florian Heizung Betriebsart [MAP(HM-CC-RT-DN.map):%s]" <"heating-off"> (Heating,Heating_OpModes) {channel="homematic:HM-CC-VG-1:3014F711A0001F5A4993D3F2:INT0000001:1#CONTROL_MODE"}
Switch FZimmer_Auto "Florian Heizung Auto-Mode" <temperature> (Heating) {channel="homematic:HM-CC-VG-1:3014F711A0001F5A4993D3F2:INT0000001:1#AUTO_MODE"}
Number:Temperature FZimmer_Manu "Florian Heizung Manu-Mode [%.1f °C]" <"heating-40"> (Heating) {channel="homematic:HM-CC-VG-1:3014F711A0001F5A4993D3F2:INT0000001:1#MANU_MODE"}
Switch FZimmer_BoostMode "Florian Heizung Boost-Mode" <fire> (Heating) {channel="homematic:HM-CC-VG-1:3014F711A0001F5A4993D3F2:INT0000001:1#BOOST_MODE"}
Number FZimmer_BoostTime "Florian Heizung Boost-Restdauer" <"clock-on"> (Heating) {expire="300s"}
Number FZimmer_Preset "Florian Heizung Soll-Temperatur Schnellauswahl" <"heating-60"> (Heating)
Number FZimmer_PresetTemp "Florian Heizung Soll-Temperatur Zeitprogramm [%.1f °C]" <line> (Heating,Heating_TargetPresets)
String FZimmer_Summary "Florian Heizung Übersicht [%s]" <thermometer_red> (Heating)
heizung_raume.rules
Code: Alles auswählen
import org.eclipse.xtext.xbase.lib.Functions
val String filename = "heizung-raeume.rules"
val Number tempHigher = 24.0
val Number tempComfort = 21.0
val Number tempMid = 19.0
val Number tempLower = 17.0
val Number tempChill = 15.0
val Number tempAway = 15.0
val Number tempAwayLonger = 13.0
val Number tempOff = 4.5
val Functions$Function5<StringItem, NumberItem, NumberItem, NumberItem, SwitchItem, String> //
generateSummary = [Heater_Mode, Heater_Act_Temp, Heater_Set_Temp, Heater_Valve_Position, Window_Mode |
var String summary = "(fehlende Daten)"
if (Heater_Act_Temp.state instanceof Number && Heater_Set_Temp.state instanceof Number && Heater_Valve_Position.state instanceof Number) {
val actTemp = (Heater_Act_Temp.state as DecimalType).floatValue
val setTemp = (Heater_Set_Temp.state as DecimalType).floatValue
val valvePos = (Heater_Valve_Position.state as DecimalType).floatValue
val mode = Heater_Mode.state as StringType
summary = //
if (Window_Mode.state == ON) String::format("( ↻ Fenster offen ) %.1f °C", actTemp)
else if (mode == "BOOST-MODE") String::format("( 🔥 Boost ) %.1f °C", actTemp)
else if (mode == "AUTO-MODE") String::format("( ⚙ %.1f °C ) %.1f °C", setTemp, actTemp)
else if (valvePos > 60) String::format("( ⟰ %.1f °C ) %.1f °C", setTemp, actTemp)
else if (valvePos > 40) String::format("( ⤊ %.1f °C ) %.1f °C", setTemp, actTemp)
else if (valvePos > 20) String::format("( ⇈ %.1f °C ) %.1f °C", setTemp, actTemp)
else if (valvePos > 0) String::format("( ↑ %.1f °C ) %.1f °C", setTemp, actTemp)
else if (setTemp > actTemp) String::format("( • %.1f °C ) %.1f °C", setTemp, actTemp)
else String::format("%.1f °C", actTemp)
}
return summary
]
rule "System started - Heizung"
when
System started
then
createTimer(now.plusSeconds(200)) [|
logInfo(filename, "System started - Heizung")
if (FZimmer_Heizung_Fault.state == NULL) FZimmer_Heizung_Fault.postUpdate("NO_FAULT")
]
end
// Heizung Auswertung Schnellauswahl (Sitemap) //
//Florian Zimmer
rule "FZimmer_Heizung Auswertung Schnellauswahl (Sitemap)"
when
Item FZimmer_Preset received command
then {
//logInfo(filename, "Auswertung Schnellauswahl (Sitemap)")
switch (receivedCommand){
case 0: FZimmer_Manu.sendCommand(tempLower)
case 1: FZimmer_Manu.sendCommand(tempComfort)
case 2: FZimmer_Manu.sendCommand(tempHigher)
}
FZimmer_Preset.postUpdate(-1)
}
end
heizung_modus.rules
Code: Alles auswählen
val String filename = "heizung-modus.rules"
val Number tempHigher = 24.0
val Number tempComfort = 21.0
val Number tempMid = 19.0
val Number tempLower = 17.0
val Number tempChill = 15.0
val Number tempAway = 15.0
val Number tempAwayLonger = 13.0
val Number tempOff = 4.5
//Florian Zimmer
rule "System started"
when
System started
then
createTimer(now.plusSeconds(180)) [ |
logInfo(filename, "Whg_Heating system started")
if (Whg_Heating_Mode.state == NULL) Whg_Heating_Mode.postUpdate("OFF_SUMMER")
Heating_TargetPresets.members.filter[item | item.state == NULL].forEach[item | item.postUpdate(tempMid)]
Whg_Heating_UpdateHeater.sendCommand(ON)
]
end
// Heizmodus //
//Florian Zimmer
rule "Heizmodus umschalten und Stellglieder setzen"
when
Item Whg_Heating_Mode received update or
Item Whg_Heating_UpdateHeater received command ON
then
Whg_Heating_UpdateHeater.postUpdate(OFF)
logInfo(filename, "Wohnung Heizmodus: " + Whg_Heating_Mode.state)
switch Whg_Heating_Mode.state {
case "NORMAL" : {
FZimmer_Manu.sendCommand(FZimmer_PresetTemp.state as Number)
}
case "LONGERAFK" : {
FZimmer_Manu.sendCommand(tempAwayLonger)
}
case "SICKDAY" : {
FZimmer_Manu.sendCommand(tempHigh)
}
case "OFF_SUMMER" : {
FZimmer_Manu.sendCommand(tempOff)
}
case "CALENDAR" : { logWarn(filename, "Wohnung Heizmodus: CALENDAR (nicht implementiert)") }
case "AUTO_DEVICE" : { logWarn(filename, "Wohnung Heizmodus: AUTO_DEVICE (nicht implementiert)") }
case "MANU_DEVICE" : { logWarn(filename, "Wohnung Heizmodus: MANU_DEVICE (nicht implementiert)") }
default : { logError(filename, "Wohnung Heizmodus ungültig: " + Whg_Heating_Mode.state) }
}
end
zudem wird dem item Heating_TargetPresets tempMid zugewiesen was in meinem fall 19°C wäre und Whg_Heating_UpdateHeater wird auf ON gestellt
mit der zweiten rule schalte ich den Heizmodus um
das wars auch soweit zu den heizungs rules
kommen wir zu der wartungs rule
die Homematic geräte bieten ja die möglichkeit Unreach, Error und batterie stände aus zulesen
die rule macht 2 mal täglich eine ausführung (kann aber auch über die den Switch in der sitemap ausgelöst werden) und schaut ob fehler vorliegen an den geräten oder ob batterien vielleicht leer sind und benachrichtigen mich in diesem fall über telegram
wartungs.rules
Code: Alles auswählen
val String filename = "wartung.rules"
rule "Wartung: Unreach"
when
Time cron "5 45 9,17 * * ?" or
Item Whg_Wartung_Trigger received command ON
then
logInfo(filename, "Wartung - Unreach läuft...")
Unreach_Group.members.forEach(item | {
if (item.state == ON) {
logWarn(filename, "Wartung - Unreach FEHLER: " + item.label)
sendTelegram("florian", item.label + "Warnung")
}
})
end
rule "Wartung: Fehler-Items"
when
Time cron "0 45 9,17 * * ?" or
Item Whg_Wartung_Trigger received command ON
then
logInfo(filename, "Wartung - Fehler-Items läuft...")
Error_Group.members.forEach(item | {
if (item.state != "NO_FAULT" && item.state != "NO_ERROR" && item.state != 0) {
logWarn(filename, "Wartung - Fehler-Item FEHLER: " + item.label + ": " + item.state)
sendTelegram("florian", item.label + " (Status " + item.state + ")")
}
})
end
rule "Wartung: Batterien"
when
Time cron "10 45 9,17 * * ?" or
Item Whg_Wartung_Trigger received command ON
then
logInfo(filename, "Wartung - Batterien läuft...")
Bat_Binary.members.forEach(item | {
//logInfo(filename, "Wartung - Batterie (Binary) '" + item.label + "' Type (" + item.type + "): " + item.state)
if (item.state == ON) {
logWarn(filename, "Wartung - Batterie schwach: " + item.label)
sendTelegram("florian", item.label + " schwach")
}
})
Bat_Volts.members.forEach(item | {
//logInfo(filename, "Wartung - Batterie (Volts) '" + item.label + "' Type (" + item.type + "): " + item.state)
if (item.state <= 2.4) {
logWarn(filename, "Wartung - Batterie schwach: " + item.label)
sendTelegram("florian", item.label + " schwach (" + item.state + "V)")
}
})
Bat_Percent.members.forEach(item | {
//logInfo(filename, "Wartung - Batterie (Percent) '" + item.label + "' Type (" + item.type + "): " + item.state)
if (item.state <= 20) {
logWarn(filename, "Wartung - Batterie schwach: " + item.label)
sendTelegram("florian", item.label + " schwach (" + item.state + "%)")
}
})
end
nochmal nebenbei die .maps die ich verwende
window.map
Code: Alles auswählen
CLOSED=geschlossen ✔
OPEN=offen ✘
TILTED=gekippt ✘
//
ON=offen ✘
OFF=geschlossen ✔
//
NULL=unbekannt ⁉
UNDEF=unbekannt ⁉
-=unbekannt ⁉
HM-Sec-SCo.map
Code: Alles auswählen
// 1#ERROR
NO_ERROR=Kein Fehler
SABOTAGE=Sabotage am Sensor
//
NULL=unbekannt ⁉
UNDEF=unbekannt ⁉
-=unbekannt ⁉
HM-CC-RT-DN.map
Code: Alles auswählen
// 4#CONTROL_MODE
-1=-Unbestimmt-
AUTO-MODE=Automatik
MANU-MODE=Manuell
PARTY-MODE=Arbeit
BOOST-MODE=Boost
// 4#FAULT_REPORTING
NO_FAULT=Kein Fehler
VALVE_TIGHT=Ventil undicht
ADJUSTING_RANGE_TOO_LARGE=Stellbereich zu groß
ADJUSTING_RANGE_TOO_SMALL=Stellbereich zu klein
COMMUNICATION_ERROR=Gerätekommunikation gestört
LOWBAT=Batteriespannung gering
VALVE_ERROR_POSITION=Ventil in Fehlerposition
//
NULL=unbekannt ⁉
UNDEF=unbekannt ⁉
-=unbekannt ⁉
und zu guter letzt noch die sitemap
.sitemap
Code: Alles auswählen
Frame label="Temperaturen und Heizung" {
//
Text item=Valve_DG label="Dachgeschoss" icon="attic" {
//
Frame label="Florian Zimmer" {
//
Selection item=Whg_Heating_Mode label="Heizungsmodus" mappings=[NORMAL="Normal",
LONGERAFK="Abwesend",
SICKDAY="Krank",
OFF_SUMMER="Aus (Standby)"
]
//
Text item=FZimmer_ActTemp label="Aktuelle Temperatur [%.1f °C]"
//
Text item=FZimmer_Heizung_Battery label="Florian Zimmer [%.1f V]" visibility=[FZimmer_Heizung_Battery < 2.2] valuecolor=[<2.2="maroon"]
Text label="Florian Heizstellglied [N/A ✘]" icon="error2" visibility=[FZimmer_Unreach != OFF] valuecolor=["maroon"]
Text item=FZimmer_Heizung_Fault label="Florian Zimmer [MAP(HM-CC-RT-DN.map):%s]" visibility=[FZimmer_Heizung_Fault != NO_FAULT] valuecolor=["maroon"]
Text item=FZimmer_Summary label="Florian Zimmer [%s]" visibility=[FZimmer_Unreach == OFF] {
Frame label="Aktuell" {
Text item=FZimmer_ActTemp label="Temperatur [%.1f °C]"
}
Frame label="Heizung" visibility=[Whg_Heating_Mode != OFF_SUMMER] {
Setpoint item=FZimmer_SetTemp label="Stellwert (±1) [%.1f °C]" minValue=4.5 maxValue=24.0 step=1.0 visibility=[FZimmer_SetTemp > 4.5]
Setpoint item=FZimmer_SetTemp label="Stellwert (±½) [%.1f °C]" minValue=4.5 maxValue=24.0 step=0.5 visibility=[FZimmer_SetTemp > 4.5]
Switch item=FZimmer_SetTemp label="Stellglied [OFF]" mappings=[5.0=Einschalten] visibility=[FZimmer_SetTemp == 4.5]
Selection item=FZimmer_Preset label="Schnellwahl" mappings=[0="Abgesenkt", 1="Komfort", 2="Warm"]
Switch item=FZimmer_BoostMode label="Boost (5min)" mappings=[ON="Starten"]
Text item=FZimmer_BoostTime label="Boost-Restzeit [%d sec]" visibility=[FZimmer_BoostTime > 0]
}
Frame label="Fenster/Türen" {
Text item=FZimmer_Fenster_State label="Fenster [MAP(window.map):%s]"
Text item=FZimmer_DachFenster_State label="DachFenster [MAP(window.map):%s]"
}
}
}
}
}
Switch item=Whg_Wartung_Trigger label="Wartungsroutinen" icon="pantry" mappings=[ON="Starten"]
Hoffe ich kann mit diesen beispiel ein paar leuten helfen. nehme auch gerne noch verbesserungs vorschläge an.
habe diese rule nicht alle selber gemacht sondern auf github gefunden und selber etwas angepasst wollte den link von github ja noch mit verlinken aber finde diesen nicht mehr.
Also viel spass damit
LG
Florian