Welche Laus ist Dir denn über die Leber gelaufen?
rule "Temperaturpruefung"
when
Time cron "30 0/5 * ? * MON-SUN"
then
var deltaT05 = 10.0f as Number
var deltaT10 = 0.0f as Number
var diff = 0.0f
var roomDiff = 0.0f
var modeFaktor = 1f
var limiter = 3f
gRoomsWithDaikin.members.forEach[ GroupItem m |
val gDaikin = m.members.findFirst[ d | d.name.startsWith("gDaikin") ] as GroupItem
val klimaItem = gDaikin.members.findFirst[ k | k.name.endsWith("_Power") ] as SwitchItem
if (klimaItem.state == ON) {
deltaT05 = 10.0f as Number
deltaT10 = 0.0f as Number
var lastChange = (gDaikin.members.findFirst[ t |
t.name.endsWith("_LastChange")
].state as DateTimeType).getZonedDateTime
if (now.minusMinutes(5).isAfter(lastChange))
{
val modeItem = gDaikin.members.findFirst[ k |
k.name.endsWith("_Mode") ] as StringItem
val fanItem = gDaikin.members.findFirst[ k |
k.name.endsWith("_Fan") ] as StringItem
val aktTempItem = m.members.findFirst[ t |
t.name.endsWith("_ActualTemperature")
] as NumberItem
val setTempItem = m.members.findFirst[ t |
t.name.endsWith("_SetTemperature")
] as NumberItem
val setPointItem = gDaikin.members.findFirst[ t |
t.name.endsWith("_SetPoint")
]
val inTempItem = gDaikin.members.findFirst[ t |
t.name.endsWith("_IndoorTemperature")
]
val demandItem = gDaikin.members.findFirst[ d |
d.name.endsWith("MaxPower")
]
val dcItem = gDaikin.members.findFirst[ d |
d.name.endsWith("DemandControlMode")
]
var setPoint = (setPointItem.state as Number).floatValue
val inTemp = (inTempItem.state as Number).floatValue
var demandPower = (if (demandItem.state == UNDEF) minPower
else (demandItem.state as Number).intValue)
var deltaSecs = 0
var tItem = aktTempItem.previousState()
if (modeItem.state == "COLD") {
modeFaktor = -1f
limiter = -1f
}
else {
modeFaktor = 1f
limiter = 3f
}
do {
deltaSecs = (now.toEpochSecond - ZonedDateTime.parse(tItem.timestamp.toString).toInstant.toEpochMilli / 1000 as Number).intValue + 1
if (deltaSecs > 300 && deltaT05.intValue == 10) {
deltaT05 = ((aktTempItem.deltaSince(now.minusSeconds(deltaSecs)) as Number).floatValue / deltaSecs * 300f * modeFaktor) as Number
}
tItem = aktTempItem.persistedState(now.minusSeconds(deltaSecs))
} while (deltaSecs < 600)
deltaT10 = ((aktTempItem.deltaSince(now.minusSeconds(deltaSecs)) as Number).floatValue / deltaSecs * 600f * modeFaktor) as Number
roomDiff = ((aktTempItem.state as Number).floatValue -
(setTempItem.state as Number).floatValue) * modeFaktor
// Raum-Soll erreicht
if (roomDiff >= 0.0f) {
if (deltaT05.floatValue >= 0.1f) {
if (setPoint > inTemp) setPoint = inTemp
else
setPoint -= Math.round(10f * deltaT05.floatValue * modeFaktor)
}
else {
if (deltaT05.floatValue > 0f && deltaT05.floatValue < 0.1f)
setPoint -= 0.5f * modeFaktor
else
setPoint -= Math.round(10f * deltaT05.floatValue * modeFaktor) / 2f
}
// setPoint fürs Kühlen zu groß oder Heizen zu klein
if (setPoint > inTemp - limiter && modeItem.state == "COLD" ||
setPoint < inTemp - limiter && modeItem.state == "HEAT")
{
diff = Math.max(setPoint - (inTemp - limiter),
(inTemp - limiter) - setPoint)
if (dcItem.state.toString.toUpperCase == "OFF" || demandPower <= minPower)
{
fanItem.sendCommand("SILENCE")
}
else {
demandPower -= Math.round(10f * diff)
demandPower = Math.max(minPower, demandPower)
}
setPoint = inTemp - limiter
} // setPoint < minTemp ...
} // roomDiff >= 0.0f
// Kurz vor Raum-Soll
if (roomDiff >= -0.5f && roomDiff < 0.0f) {
if (fanItem.state == "SILENCE") {
fanItem.sendCommand("AUTO")
}
if (deltaT05.floatValue > 0.1f)
setPoint -= Math.round(20f * deltaT05.floatValue * modeFaktor)
if (deltaT05.floatValue <= 0f)
setPoint -= Math.round(roomDiff * 10f * modeFaktor)
if (modeItem.state == "HEAT")
setPoint = Math.max(inTemp - limiter + 0.5f, setPoint)
if (setPoint > maxTemp && modeItem.state == "HEAT" ||
setPoint < minTemp && modeItem.state == "COLD")
{
demandPower = Math.min(demandPower + 5, 95)
setPoint = (if (modeItem.state == "HEAT") inTemp else minTemp)
}
} // roomDiff >= -0.5 && roomDiff < 0
// Raum-Soll noch weit entfernt
if (roomDiff < -0.5f) {
if (fanItem.state == "SILENCE") {
fanItem.sendCommand("AUTO")
}
if (deltaT05.floatValue < 0.1f)
setPoint -= Math.round(roomDiff * 10f * modeFaktor) * 0.5f
if (setPoint > maxTemp && modeItem.state == "HEAT" ||
setPoint < minTemp && modeItem.state == "COLD")
{
demandPower += 5
setPoint = (if (modeItem.state == "HEAT")
(inTemp + (maxTemp - inTemp) / 2f)
else minTemp)
}
} // roomDiff < -0.5
demandPower = Math.min(95, Math.max(minPower, demandPower))
if (modeItem.state == "HEAT")
setPoint = Math.min(maxTemp, setPoint)
if (modeItem.state == "COLD")
setPoint = Math.max(minTemp, setPoint)
setPoint = Math.round(setPoint * 2f) / 2f
if (modeItem == "HEAT" && setPoint < inTemp &&
(setPointItem.state as Number).floatValue - setPoint > 2f)
{
setPoint = (setPointItem.state as Number).floatValue - 2f
}
if (demandItem.state != UNDEF &&
dcItem.state.toString.toUpperCase != "OFF")
{
if (demandPower != (demandItem.state as Number).intValue) {
demandItem.sendCommand(demandPower)
setPointItem.persist
inTempItem.persist
setTempItem.persist
}
}
if (setPoint != (setPointItem.state as Number).floatValue) {
setPointItem.sendCommand(setPoint)
demandItem.persist
inTempItem.persist
setTempItem.persist
}
} // now.plusMinutes(5).isAfter(lastChange)
} // klimaItem == ON
]
end
Ich stelle meine Raumthermostate abhängig von der AT automatisch auf "Heizen" bzw. "Kühlen" um. Deshalb ist die Regelung so ausgelegt, dass sie für beide Betriebsarten funktioniert.