Daikin - ESP32 Faikout Modul

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.

1 „Gefällt mir“