Example #1
0
    def execute(self, module, input):
        now = ZonedDateTime.now()

        if itemStateOlderThen("Dawn_Time", now) and itemStateNewerThen(
                "Dusk_Time", now):
            # triggers solar value update
            sendCommand("Solar_Total_Yield", REFRESH)

            sendCommand("Solar_AC_Power", REFRESH)

            acPower = getItemState('Solar_AC_Power').intValue()
            dailyConsumption = getItemState("Solar_Daily_Yield").doubleValue()

            msg = "{} W, {:.2f} kWh".format(acPower, dailyConsumption)

            if itemLastUpdateOlderThen(
                    "Solar_Total_Yield",
                    now.minusMinutes(15)) and itemStateOlderThen(
                        "Dawn_Time", now.minusMinutes(60)):
                self.log.error("Solar values not updated")

        else:
            msg = "Inaktiv"

        postUpdateIfChanged("Solar_Message", msg)
Example #2
0
    def execute(self, module, input):
        if getItemState("pOther_Manual_State_Auto_Rollershutter") != ON:
            return

        contactItemName = input['event'].getItemName()

        if contactItemName not in contact_map:
            return

        config = contact_map[contactItemName]

        state = None
        if input['event'].getItemState() == OPEN:
            state = UP
        else:
            if getItemState("pOther_Automatic_State_Rollershutter").intValue(
            ) == SunProtectionHelper.STATE_ROLLERSHUTTER_DOWN:
                # check that more windows are DOWN than UP.
                #closedShutters = 0
                #for _config in configs:
                #    if getItemState(_config["shutter"]).intValue() == 100:
                #        closedShutters += 1
                #if closedShutters >= math.floor( len(configs) / 2 ):
                state = DOWN
            elif ("sunprotection" in config
                  and getItemState(config["sunprotection"]) == ON
                  and "sunprotectionOnlyIfAway" not in config):
                state = DOWN

        if state is None:
            return

        sendCommand(config["shutter"], state)
Example #3
0
    def updateInfoMessage(self,
                          infoItem,
                          temperatureItem,
                          humidityItem,
                          co2Item=None,
                          temperatureTargetItem=None):
        #self.log.info(u">>>delay: {}".format(infoItem))

        msg = u""
        if temperatureTargetItem is not None:
            msg = u"{}({}) ".format(
                msg,
                getItemState(temperatureTargetItem).format("%.1f"))

        #self.log.info(temperatureItem)
        msg = u"{}{} °C, ".format(msg,
                                  getItemState(temperatureItem).format("%.1f"))
        #self.log.info(humidityItem)
        msg = u"{}{} %".format(msg, getItemState(humidityItem).format("%.1f"))

        if co2Item is not None:
            msg = u"{}, {} ppm".format(msg, getItemState(co2Item).format("%d"))

        postUpdateIfChanged(infoItem, msg)

        self.updateTimer[infoItem] = None
Example #4
0
 def execute(self, module, input):
     if getItemState(
             "pOther_Manual_State_Auto_Lighting") == ON and getItemState(
                 "pOther_Presence_State").intValue(
                 ) == PresenceHelper.STATE_AWAY:
         sendCommand("pGF_Corridor_Light_Hue_Color", 30)
         sendCommand("pGF_Livingroom_Light_Hue4_Color", 30)
Example #5
0
    def execute(self, module, input):
        if getItemState("pOther_Manual_State_Auto_Rollershutter") != ON:
            return

        if self.awayTimer != None:
            self.awayTimer.cancel()
            self.awayTimer = None

        if getItemState("pOther_Automatic_State_Rollershutter").intValue() in [
                SunProtectionHelper.STATE_ROLLERSHUTTER_DOWN,
                SunProtectionHelper.STATE_ROLLERSHUTTER_MAYBE_UP
        ]:
            return

        if input['event'].getItemState().intValue(
        ) == PresenceHelper.STATE_AWAY:
            self.presenceTimer = startTimer(self.log,
                                            1800,
                                            self.updateCallback,
                                            args=[DOWN])
        elif input['event'].getItemState().intValue(
        ) == PresenceHelper.STATE_PRESENT and input['event'].getOldItemState(
        ).intValue() in [
                PresenceHelper.STATE_AWAY, PresenceHelper.STATE_MAYBE_PRESENT
        ]:
            self.updateCallback(UP)
Example #6
0
    def execute(self, module, input):
        # we don't want do be notified
        if getItemState("pOther_Manual_State_Air_Thoroughly_Notify") != ON:
            return

        if 'event' in input:
            if self.timer != None:
                self.timer.cancel()
                self.timer = None

            if input['event'].getItemState().intValue(
            ) == PresenceHelper.STATE_PRESENT and input[
                    'event'].getOldItemState().intValue() in [
                        PresenceHelper.STATE_AWAY,
                        PresenceHelper.STATE_MAYBE_PRESENT
                    ]:
                # delayed notification to give all devices the chance to be detected as present
                self.timer = startTimer(
                    self.log,
                    60,
                    self.process,
                    args=[PresenceHelper.getPresentRecipients()])  # 1 min
        else:
            # we are away
            if getItemState("pOther_Presence_State").intValue() in [
                    PresenceHelper.STATE_AWAY,
                    PresenceHelper.STATE_MAYBE_PRESENT
            ]:
                return

            # recipients will be selected only if there are state changes
            recipients = None

            self.process(recipients)
Example #7
0
 def execute(self, module, input):
     if getItemState(
             "pOther_Automatic_State_Sunprotection_Terrace").intValue(
             ) == SunProtectionHelper.STATE_TERRACE_MAYBE_CLOSED:
         pass
     elif getItemState(
             "pOther_Automatic_State_Sunprotection_Terrace").intValue(
             ) == SunProtectionHelper.STATE_TERRACE_CLOSED:
         # DOWN only if automatic is enabled and (people are present or where present changed recently or terrace door is open)
         if (getItemState("pOther_Manual_State_Auto_Sunprotection") == ON
                 and
             (getItemState("pOther_Presence_State").intValue() not in [
                 PresenceHelper.STATE_AWAY,
                 PresenceHelper.STATE_MAYBE_PRESENT
             ] or itemLastChangeNewerThen(
                 "pOther_Presence_State",
                 ZonedDateTime.now().minusMinutes(120)) or getItemState(
                     "pGF_Livingroom_Openingcontact_Window_Terrace_State")
              == OPEN)):
             #self.log.info(u"down")
             sendCommand("pOutdoor_Terrace_Shading_Left_Control", DOWN)
             sendCommand("pOutdoor_Terrace_Shading_Right_Control", DOWN)
     else:
         #self.log.info(u"up")
         # UP always when sun protection time is over
         sendCommand("pOutdoor_Terrace_Shading_Left_Control", UP)
         sendCommand("pOutdoor_Terrace_Shading_Right_Control", UP)
    def confirmArriving(self):
        presenceState = getItemState("pOther_Presence_State").intValue()

        if presenceState != PresenceHelper.STATE_MAYBE_PRESENT:
            return

        newestUpdate = None
        for item in getItem("gSensor_Indoor").getAllMembers():
            if getItemState(item) == OPEN:
                newestUpdate = ZonedDateTime.now()
                break

            _update = getItemLastUpdate(item)
            if newestUpdate == None or _update.isAfter(newestUpdate):
                newestUpdate = _update

        ref = ZonedDateTime.now().minusSeconds(7)
        self.isConfirmed = newestUpdate.isAfter(ref) or newestUpdate.isEqual(
            ref)

        if self.isConfirmed:
            self.delayedAwayCheck()
        else:
            self.setAway(False)

        self.confirmTimer = None
Example #9
0
 def getPresentRecipients():
     recipients = []
     if getItemState("pOther_Presence_Holger_State") == OnOffType.ON:
         recipients.append('bot_holger')
     if getItemState("pOther_Presence_Sandra_State") == OnOffType.ON:
         recipients.append('bot_sandra')
     return recipients
Example #10
0
    def execute(self, module, input):
        if getItemState("pOther_Manual_State_Notify") != ON:
            return

        state = getItemState("pOther_Presence_State").intValue()

        if state in [PresenceHelper.STATE_AWAY, PresenceHelper.STATE_SLEEPING]:
            itemName = input['event'].getItemName()
            item = getItem(itemName)

            location = self.getLocation(item)

            if "Door" in itemName:
                msg = u"Tür im {} {}".format(
                    location.getLabel(), u"offen" if
                    input['event'].getItemState() == OPEN else u"geschlossen")
            elif "Window" in itemName:
                msg = u"Fenster im {} {}".format(
                    location.getLabel(), u"offen" if
                    input['event'].getItemState() == OPEN else u"geschlossen")
            elif "Motiondetector" in itemName:
                if input['event'].getItemState() == CLOSED:
                    return

                # during sleep, ignore moving detection
                if state == PresenceHelper.STATE_SLEEPING:
                    return

                msg = u"Bewegung im {} erkannt".format(location.getLabel())

            #self.log.info(u"{} {} {} {}".format(group,itemName,item.getLabel(),location.getLabel()))

            sendNotification(u"Alarm", u"{}".format(msg))
Example #11
0
    def execute(self, module, input):
        moverStatus = getItemState("pOutdoor_Mower_Status").toString()

        if itemLastUpdateOlderThen("pOutdoor_Mower_WlanSignal",
                                   ZonedDateTime.now().minusMinutes(60)):
            if moverStatus != "98":
                postUpdate("pOutdoor_Mower_Status", 98)
                postUpdate(
                    "pOutdoor_Mower_StatusFormatted",
                    Transformation.transform("MAP", "robonect_status.map",
                                             "98"))
        else:
            seconds = getItemState("pOutdoor_Mower_Duration").intValue()
            hours = seconds / (60 * 60)
            seconds = seconds % (60 * 60)
            minutes = seconds / 60
            #seconds = seconds % 60

            msg = u"{} seit ".format(
                Transformation.transform("MAP", "robonect_status.map",
                                         moverStatus))
            if hours < 10: msg = u"{}0".format(msg)
            msg = u"{}{}:".format(msg, hours)
            if minutes < 10: msg = u"{}0".format(msg)
            msg = u"{}{}:".format(msg, minutes)

            postUpdateIfChanged("pOutdoor_Mower_StatusFormatted", msg)
    def execute(self, module, input):
        active = []
        group = "Fehler"

        ventilation_state = getItemState(
            "pGF_Utilityroom_Ventilation_State_Message").toString()
        if ventilation_state != "Alles ok":
            if ventilation_state == "Filter":
                active.append(u"Filter")
            else:
                active.append(u"Lüftung")

        if getItemState("pGF_Utilityroom_Heating_State_Message").toString(
        ) != "Alles ok":
            active.append(u"Heizung")

        if getItemState("pGF_Garage_Solar_Inverter_Is_Working") == OFF:
            active.append(u"Solar")

        if getItemState("State_Server").intValue() > 1:
            active.append(u"Server")

        if len(active) == 0:
            active.append(u"Alles ok")
            group = "Info"

        msg = u", ".join(active)

        if postUpdateIfChanged("pOther_State_Message_Main", msg):
            sendNotificationToAllAdmins("Main " + group, msg)
    def delayUpdate(self):
        msg = u"{}%, {}%".format(
            getItemState("pGF_Utilityroom_Heating_Power").format("%.0f"),
            getItemState("pGF_Utilityroom_Heating_Circuit_Pump_Speed").format(
                "%.0f"))
        postUpdateIfChanged("pGF_Utilityroom_Heating_Power_Message", msg)

        self.updateTimer = None
Example #14
0
    def execute(self, module, input):
        now = ZonedDateTime.now()

        currentErtrag = getItemState("Solar_Annual_Yield").doubleValue()
        currentEinspeisung = getItemState(
            "Electric_VZ_Jahreseinspeisung").doubleValue()

        postUpdateIfChanged("Solar_Annual_Consumption",
                            currentErtrag - currentEinspeisung)
    def delayUpdate(self):
        msg = u"{}°C, {}°C".format(
            getItemState("pGF_Utilityroom_Heating_Temperature_Offset").format(
                "%.1f"),
            getItemState("pGF_Utilityroom_Heating_Temperature_Offset_Target").
            format("%.1f"))
        postUpdateIfChanged(
            "pGF_Utilityroom_Heating_Temperature_Offset_Message", msg)

        self.updateTimer = None
Example #16
0
    def findStep(self):
        duration = getItemState(
            "pOutdoor_Watering_Logic_Program_Duration").intValue() * 60.0

        remaining = 0
        info = u""

        # detect current active index
        activeIndex = -1
        for i in range(len(circuits)):
            group = circuits[i]
            if getItemState(group[2][0] + "_Powered") == ON:
                activeIndex = i
                runtime = ChronoUnit.SECONDS.between(
                    getItemLastChange(group[2][0] + "_Powered"),
                    ZonedDateTime.now())
                remaining = (duration * group[0]) - runtime
                break

        if remaining <= 0:
            nextIndex = -1

            # detect next index
            for i in range(len(circuits)):
                if activeIndex != -1 and i <= activeIndex:
                    continue
                group = circuits[i]
                for circuit in group[2]:
                    if getItemState(circuit + "_Auto") == ON:
                        nextIndex = i
                        break
                if nextIndex != -1:
                    break

            if nextIndex == -1:
                self.disableAllCircuits()
                postUpdate("pOutdoor_Watering_Logic_Program_Start", OFF)
            else:
                for circuit in circuits[nextIndex][2]:
                    if getItemState(circuit + "_Auto") == ON:
                        sendCommand(circuit + "_Powered", ON)

                nextGroup = circuits[nextIndex]

                remaining = (duration * nextGroup[0])
                info = nextGroup[1]

                # deactivate current index
                if activeIndex != -1:
                    for circuit in circuits[activeIndex][2]:
                        sendCommand(circuit + "_Powered", OFF)
        else:
            info = circuits[activeIndex][1]

        return [info, remaining]
Example #17
0
    def execute(self, module, input):
        now = ZonedDateTime.now()

        currentSupply = getItemState(
            "pGF_Utilityroom_Electricity_Total_Supply").doubleValue()
        currentYield = getItemState(
            "pGF_Garage_Solar_Inverter_Total_Yield").doubleValue()

        # Tagesverbrauch
        startSupply = getHistoricItemState(
            "pGF_Utilityroom_Electricity_Total_Supply",
            now.toLocalDate().atStartOfDay(now.getZone())).doubleValue()
        startYield = getHistoricItemState(
            "pGF_Garage_Solar_Inverter_Total_Yield",
            now.toLocalDate().atStartOfDay(now.getZone())).doubleValue()

        # sometimes solar converter is providing wrong value. Mostly if he is inactive in the night
        if currentYield > 1000000000 or startYield > 1000000000:
            # can be INFO because it is a 'normal' behavior of this  solar converter
            self.log.info(
                u"Wrong Solar Value: currentYield is {}, startYield is {}".
                format(currentYield, startYield))
            return

        totalSupply = currentSupply - startSupply
        totalYield = currentYield - startYield
        dailyConsumption = totalYield - totalSupply

        postUpdateIfChanged("pGF_Garage_Solar_Inverter_Daily_Yield",
                            totalYield)

        #self.log.info(u"A {} {}".format(currentSupply,currentYield))
        #self.log.info(u"B {} {}".format(startSupply,startYield))
        #self.log.info(u"C {} {}".format(totalSupply,totalYield))

        postUpdateIfChanged("pGF_Garage_Solar_Inverter_Daily_Consumption",
                            dailyConsumption)

        # Jahresverbrauch
        refDay = now.withYear(now.getYear()).withMonth(1).withDayOfMonth(1)
        refDate = refDay.toLocalDate().atStartOfDay(refDay.getZone())
        startSupply = getHistoricItemState(
            "pGF_Utilityroom_Electricity_Total_Supply", refDate).doubleValue()
        startYield = getHistoricItemState(
            "pGF_Garage_Solar_Inverter_Total_Yield", refDate).doubleValue()

        totalSupply = currentSupply - startSupply
        totalYield = currentYield - startYield
        annualConsumption = totalYield - totalSupply

        #self.log.info(u"D {} {}".format(startSupply,startYield))
        #self.log.info(u"E {}".format(annualConsumption))

        postUpdateIfChanged("pGF_Garage_Solar_Inverter_Annual_Consumption",
                            annualConsumption)
Example #18
0
    def execute(self, module, input):
        msg = u"Nicht aktiv"

        if getItemState(
                "pOther_Manual_State_Auto_Attic_Light").intValue() != 1:
            soilMoistSensor1 = getItemState(
                "pIndoor_Plant_Sensor_Device_State1").intValue(
                ) if getItemState(
                    "pIndoor_Plant_Sensor_Device_Enabled1") == ON else 1000
            soilMoistSensor2 = getItemState(
                "pIndoor_Plant_Sensor_Device_State2").intValue(
                ) if getItemState(
                    "pIndoor_Plant_Sensor_Device_Enabled2") == ON else 1000
            soilMoistSensor3 = getItemState(
                "pIndoor_Plant_Sensor_Device_State3").intValue(
                ) if getItemState(
                    "pIndoor_Plant_Sensor_Device_Enabled3") == ON else 1000
            soilMoistSensor4 = getItemState(
                "pIndoor_Plant_Sensor_Device_State4").intValue(
                ) if getItemState(
                    "pIndoor_Plant_Sensor_Device_Enabled4") == ON else 1000

            if soilMoistSensor1 < 380 or soilMoistSensor2 < 380 or soilMoistSensor3 < 380 or soilMoistSensor4 < 380:
                msg = u"Jetzt Giessen"
            elif soilMoistSensor1 < 400 or soilMoistSensor2 < 400 or soilMoistSensor3 < 400 or soilMoistSensor4 < 400:
                msg = u"Giessen"
            else:
                msg = u"Feucht genug"

        postUpdateIfChanged("pIndoor_Plant_Sensor_Watering_Info", msg)
    def delayUpdate(self):
        solarCollector = getItemState(
            "pGF_Utilityroom_Heating_Temperature_Solar_Collector")
        solarStorage = getItemState(
            "pGF_Utilityroom_Heating_Temperature_Solar_Storage")
        msg = u"{}°C, {}°C".format(solarCollector.format("%.1f"),
                                   solarStorage.format("%.1f"))
        postUpdateIfChanged(
            "pGF_Utilityroom_Heating_Temperature_Solar_Message", msg)

        self.updateTimer = None
Example #20
0
    def execute(self, module, input):
        dailyEnergyDemand = getItemState(
            "pGF_Utilityroom_Electricity_Current_Daily_Demand").doubleValue()
        dailyEnergySupply = getItemState(
            "pGF_Utilityroom_Electricity_Current_Daily_Supply").doubleValue()
        dailySolarSupply = getItemState(
            "pGF_Garage_Solar_Inverter_Daily_Yield").doubleValue()

        postUpdateIfChanged(
            "pGF_Utilityroom_Electricity_Current_Daily_Consumption",
            dailyEnergyDemand - dailyEnergySupply + dailySolarSupply)
    def delayUpdate(self):
        if isinstance(getItemState("pGF_Utilityroom_Ventilation_Incoming"), UnDefType) \
            or isinstance(getItemState("pGF_Utilityroom_Ventilation_Outgoing"), UnDefType):
            return

        msg = u"→ {}%, ← {}%".format(
            getItemState("pGF_Utilityroom_Ventilation_Incoming").toString(),
            getItemState("pGF_Utilityroom_Ventilation_Outgoing").toString())
        postUpdateIfChanged("pGF_Utilityroom_Ventilation_Fan_Message", msg)

        self.updateTimer = None
    def delayUpdate(self):
        msg = u"({}°C) {}°C, {}°C".format(
            getItemState("pOutdoor_Weather_Forecast_Temperature_4h").format(
                "%.1f"),
            getItemState("pGF_Utilityroom_Heating_Temperature_Outdoor").format(
                "%.1f"),
            getItemState("pGF_Utilityroom_Heating_Temperature_Outdoor_Subdued"
                         ).format("%.1f"))
        postUpdateIfChanged(
            "pGF_Utilityroom_Heating_Temperature_Outdoor_Message", msg)

        self.updateTimer = None
Example #23
0
 def _getCurrentColors(self):
     color1 = getItemState(
         "pGF_Livingroom_Light_Hue1_Color").toString().split(",")
     color2 = getItemState(
         "pGF_Livingroom_Light_Hue2_Color").toString().split(",")
     color3 = getItemState(
         "pGF_Livingroom_Light_Hue3_Color").toString().split(",")
     color4 = getItemState(
         "pGF_Livingroom_Light_Hue4_Color").toString().split(",")
     color5 = getItemState(
         "pGF_Livingroom_Light_Hue5_Color").toString().split(",")
     return [color1, color2, color3, color4, color5]
Example #24
0
    def execute(self, module, input):
        reference_duration = getItemState(
            "pOutdoor_Watering_Logic_Program_Duration").intValue()

        for i in range(len(circuits)):
            for circuit in circuits[i][2]:
                if getItemState(circuit + "_Auto") == ON:
                    duration = (circuits[i][0] * reference_duration)
                    duration = int(math.floor(duration))

                    postUpdate(circuit + "_Info", u"{} min.".format(duration))
                else:
                    postUpdate(circuit + "_Info", u"inaktiv")
Example #25
0
    def execute(self, module, input):
        if getItemState("pOther_Manual_State_Auto_Rollershutter") != ON:
            return

        if getItemState("pOther_Automatic_State_Rollershutter").intValue(
        ) == SunProtectionHelper.STATE_ROLLERSHUTTER_DOWN:
            for config in configs:
                if getItemState(config["contact"]) != CLOSED:
                    continue
                sendCommand(config["shutter"], DOWN)
        elif getItemState("pOther_Presence_State").intValue(
        ) == PresenceHelper.STATE_AWAY and getItemState(
                "pOther_Automatic_State_Rollershutter").intValue(
                ) == SunProtectionHelper.STATE_ROLLERSHUTTER_UP:
            sendCommand("gShutters", UP)
    def execute(self, module, input):
        active = []

        if getItemState("gOutdoor_Watering_Circuits") == ON:
            active.append(u"Bewässerung")

        if getItemState("pOutdoor_Light_Automatic_Main_Switch") != ON:
            active.append(u"Beleuchtung")

        if len(active) == 0:
            active.append(u"Alles ok")

        msg = ", ".join(active)

        postUpdateIfChanged("pOther_State_Message_Garden", msg)
Example #27
0
    def callbackProgress(self):
        if self.progressTimer is not None and self.currentProgressMsg != getItemState(
                "pOutdoor_Watering_Logic_Program_State").toString():
            self.log.info("Cancel Watering Progress Zombie Timer")
            self.cleanProgressTimer()
            return

        msg, remaining = self.findStep()

        if remaining <= 0:
            self.cleanProgressTimer()
            return

        remainingInMinutes = int(math.floor(remaining / 60.0))

        if remainingInMinutes > 0:
            msg = u"{} noch {} min".format(msg, remainingInMinutes)
        else:
            msg = u"{} gleich fertig".format(msg)

        self.currentProgressMsg = msg
        postUpdate("pOutdoor_Watering_Logic_Program_State",
                   self.currentProgressMsg)

        self.progressTimer = startTimer(self.log, 60.0, self.callbackProgress)
Example #28
0
    def updateCallback(self, state):
        for config in configs:
            # handle only shutters which depends on presence state
            if "sunprotectionOnlyIfAway" not in config:
                continue

            if state == DOWN:
                if getItemState(config["contact"]) != CLOSED:
                    continue

                if getItemState(config["sunprotection"]) != ON:
                    continue

            sendCommandIfChanged(config["shutter"], state)

        self.awayTimer = None
    def delayUpdate(self):
        if isinstance(getItemState("pGF_Utilityroom_Ventilation_Indoor_Incoming_Temperature"), UnDefType) \
            or isinstance(getItemState("pGF_Utilityroom_Ventilation_Indoor_Outgoing_Temperature"), UnDefType):
            return

        msg = u"→ {}°C, ← {}°C".format(
            getItemState(
                "pGF_Utilityroom_Ventilation_Indoor_Incoming_Temperature").
            format("%.1f"),
            getItemState(
                "pGF_Utilityroom_Ventilation_Indoor_Outgoing_Temperature").
            format("%.1f"))
        postUpdateIfChanged(
            "pGF_Utilityroom_Ventilation_Indoor_Temperature_Message", msg)

        self.updateTimer = None
Example #30
0
    def execute(self, module, input):
        global ruleTimeouts
        now = ZonedDateTime.now()

        #last = ruleTimeouts.get("Motiondetector_Outdoor_Individual_Switches",0)
        #if now - last > 1000:
        ruleTimeouts["Motiondetector_Outdoor_Main_Switch"] = now
        ruleTimeouts["Light_Outdoor"] = now

        itemName = input['event'].getItemName()
        itemCommand = input['event'].getItemCommand()

        switchState = ON
        for i, entry in enumerate(manualMappings):
            if entry[1] == itemName:
                sendCommandIfChanged(entry[0], OFF)
                if itemCommand == OFF:
                    switchState = OFF
            else:
                if getItemState(entry[1]) == OFF:
                    switchState = OFF

        # must be a command to inform physical knx switch
        sendCommandIfChanged("pOutdoor_Light_Automatic_Main_Switch",
                             switchState)