def set_poweron_afteroffon(self, key, OnOffMode=0xFF):
    # OSRAM/LEDVANCE
    # 0xfc0f --> Command 0x01
    # 0xfc01 --> Command 0x01

    # Tuya Blitzworl
    # 0x0006 / 0x8002  -> 0x00 Off ; 0x01 On ; 0x02 Previous state

    # Ikea / Philips/ Legrand
    # 0x0006 / 0x4003 -> 0x00 Off, 0x01 On, 0xff Previous

    self.log.logging("BasicOutput", "Debug", "set_PowerOn_OnOff for %s - OnOff: %s" % (key, OnOffMode), key)
    if key not in self.ListOfDevices:
        self.log.logging("BasicOutput", "Error", "set_PowerOn_OnOff for %s not found" % (key), key)
        return
    model_name = ""
    if "Model" in self.ListOfDevices[key]:
        model_name = self.ListOfDevices[key]["Model"]
    manuf_spec = "00"
    manuf_id = "0000"

    ListOfEp = getListOfEpForCluster(self, key, "0006")
    cluster_id = "0006"
    attribute = "4003"

    if model_name in ( "TS0121", "TS0115", "TS011F-multiprise", "TS011F-2Gang-switches", "TS011F-plug" ):
        attribute = "8002"
        if OnOffMode == 0xFF:
            OnOffMode = 0x02

    data_type = "30"  #
    ListOfEp = getListOfEpForCluster(self, key, "0006")
    for EPout in ListOfEp:
        data = "%02x" % OnOffMode
        self.log.logging(
            "BasicOutput", "Debug", "set_PowerOn_OnOff for %s/%s - OnOff: %s" % (key, EPout, OnOffMode), key
        )
        if attribute in self.ListOfDevices[key]["Ep"][EPout]["0006"]:
            del self.ListOfDevices[key]["Ep"][EPout]["0006"][attribute]
        return write_attribute(
            self,
            key,
            ZIGATE_EP,
            EPout,
            cluster_id,
            manuf_id,
            manuf_spec,
            attribute,
            data_type,
            data,
            ackIsDisabled=True,
        )
def ScanDevicesForGroupMemberShip(self, DevicesToScan):

    self.logging("Debug",
                 "ScanDevicesForGroupMemberShip : %s " % DevicesToScan)

    for NwkId in DevicesToScan:
        if NwkId == "0000":
            submitForGroupMemberShipScaner(self, NwkId, "01")
            continue
        if NwkId not in self.ListOfDevices:
            self.logging(
                "Debug",
                "ScanDevicesForGroupMemberShip : Skiping %s not existing" %
                NwkId)
            continue
        if not mainPoweredDevice:
            self.logging(
                "Debug",
                "ScanDevicesForGroupMemberShip : Skiping %s not main powered" %
                NwkId)
            continue

        ListEp = getListOfEpForCluster(self, NwkId, "0004")
        self.logging(
            "Debug", "ScanDevicesForGroupMemberShip : List of Ep %s for  %s" %
            (str(ListEp), NwkId))

        for Ep in ListEp:
            if [NwkId, Ep] not in self.ScanDevicesToBeDone:
                self.GroupStatus = "scan"
                submitForGroupMemberShipScaner(self, NwkId, Ep)
def set_PIROccupiedToUnoccupiedDelay(self, key, delay, ListOfEp=None):

    cluster_id = "0406"
    attribute = "0010"
    data_type = "21"
    manuf_id = "0000"
    manuf_spec = "00"
    if ListOfEp is None:
        ListOfEp = getListOfEpForCluster(self, key, cluster_id)
    for EPout in ListOfEp:
        data = "%04x" % delay
        self.log.logging(
            "BasicOutput", "Log", "set_PIROccupiedToUnoccupiedDelay for %s/%s - delay: %s" % (key, EPout, delay), key
        )
        if attribute in self.ListOfDevices[key]["Ep"][EPout][cluster_id]:
            del self.ListOfDevices[key]["Ep"][EPout][cluster_id][attribute]
        return write_attribute(
            self,
            key,
            ZIGATE_EP,
            EPout,
            cluster_id,
            manuf_id,
            manuf_spec,
            attribute,
            data_type,
            data,
            ackIsDisabled=False,
        )
def ballast_Configuration_max_level(self, nwkid, value):
    ListOfEp = getListOfEpForCluster(self, nwkid, "0301")
    if ListOfEp:
        for EPout in ListOfEp:
            write_attribute(
                self, nwkid, ZIGATE_EP, EPout, "0301", "0000", "00", "0011", "20", "%02x" % value, ackIsDisabled=True
            )
            read_attribute(self, nwkid, ZIGATE_EP, EPout, "0301", "00", "00", "0000", 1, "0011", ackIsDisabled=True)
Exemple #5
0
def pollingDeviceStatus(self, NwkId):
    # """
    # Purpose is to trigger ReadAttrbute 0x0006 and 0x0008 on attribute 0x0000 if applicable
    # """

    if self.busy or self.ZigateComm.loadTransmit() > MAX_LOAD_ZIGATE:
        return True
    self.log.logging("Heartbeat", "Debug",
                     "--------> pollingDeviceStatus Device %s" % NwkId, NwkId)
    if len(getListOfEpForCluster(self, NwkId, "0006")) != 0:
        ReadAttributeRequest_0006_0000(self, NwkId)
        self.log.logging("Heartbeat", "Debug",
                         "++ pollingDeviceStatus -  %s  for ON/OFF" % (NwkId),
                         NwkId)

    if len(getListOfEpForCluster(self, NwkId, "0008")) != 0:
        ReadAttributeRequest_0008_0000(self, NwkId)
        self.log.logging(
            "Heartbeat", "Debug",
            "++ pollingDeviceStatus -  %s  for LVLControl" % (NwkId), NwkId)

    if len(getListOfEpForCluster(self, NwkId, "0102")) != 0:
        ReadAttributeRequest_0102_0008(self, NwkId)
        self.log.logging(
            "Heartbeat", "Debug",
            "++ pollingDeviceStatus -  %s  for WindowCovering" % (NwkId),
            NwkId)

    if len(getListOfEpForCluster(self, NwkId, "0101")) != 0:
        ReadAttributeRequest_0101_0000(self, NwkId)
        self.log.logging(
            "Heartbeat", "Debug",
            "++ pollingDeviceStatus -  %s  for DoorLock" % (NwkId), NwkId)

    if len(getListOfEpForCluster(self, NwkId, "0201")) != 0:
        ReadAttributeRequest_0201_0012(self, NwkId)
        self.log.logging(
            "Heartbeat", "Debug",
            "++ pollingDeviceStatus -  %s  for Thermostat" % (NwkId), NwkId)
    return False
Exemple #6
0
def danfoss_room_sensor_polling(self, NwkId):

    # This has been triggered because "DanfossRoomFreq" exist and > 0
    # This is expected for a eTRV which belongs to a Room for which an external Temp sensor exist
    # External Temp Sensor will only have the "DanfossRoom" parameter

    self.log.logging(
        "Danfoss",
        "Debug",
        "danfoss_room_sensor_polling - Triggered for Nwkid: %s" % (NwkId, ),
        nwkid=NwkId,
    )

    if "Param" not in self.ListOfDevices[NwkId]:
        return
    if "DanfossRoom" not in self.ListOfDevices[NwkId]["Param"]:
        return
    room = self.ListOfDevices[NwkId]["Param"]["DanfossRoom"]

    self.log.logging(
        "Danfoss",
        "Debug",
        "danfoss_room_sensor_polling - Triggered for Nwkid: %s - room: %s" %
        (NwkId, room),
        nwkid=NwkId,
    )

    # Search for Temp Sensor for that Room
    for x in self.ListOfDevices:
        if x == NwkId:
            continue
        if "Param" not in self.ListOfDevices[x]:
            continue
        if "DanfossRoom" not in self.ListOfDevices[x]["Param"]:
            continue
        if self.ListOfDevices[x]["Param"]["DanfossRoom"] != room:
            continue

        ep_list = ListOfEp = getListOfEpForCluster(self, x, "0402")
        if ep_list == []:
            continue

        ep = ep_list[0]

        if "0000" not in self.ListOfDevices[x]["Ep"][ep]["0402"]:
            continue

        # At that stage we have found a Device which is in the same room and as the 0402 Cluster
        # Temp value is store in 0x0402/0x0000 is degrees
        temp_room = self.ListOfDevices[x]["Ep"][ep]["0402"]["0000"]
        danfoss_write_external_sensor_temp(self, NwkId, temp_room)
Exemple #7
0
def danfoss_exercise_day_of_week(self, NwkId, week_num):
    # 0 = Sunday, 1 = Monday, … 6 = Saturday, 7 = undefined

    if week_num > 6:
        return
    manuf_id = "1246"
    manuf_spec = "01"
    cluster_id = "%04x" % 0x0201

    EPout = ListOfEp = getListOfEpForCluster(self, NwkId, "0201")

    Hattribute = "%04x" % 0x4010
    data_type = "30"  # enum8
    self.log.logging("Danfoss",
                     "Debug",
                     "Danfoss Aly Trigger_Week Num: %s" % week_num,
                     nwkid=NwkId)

    Hdata = "%02x" % week_num

    self.log.logging(
        "Danfoss",
        "Debug",
        "danfoss_exercise_trigger_time - Week Num for %s with value %s / cluster: %s, attribute: %s type: %s"
        % (NwkId, Hdata, cluster_id, Hattribute, data_type),
        nwkid=NwkId,
    )
    for ep in EPout:
        write_attribute(self,
                        NwkId,
                        "01",
                        ep,
                        cluster_id,
                        manuf_id,
                        manuf_spec,
                        Hattribute,
                        data_type,
                        Hdata,
                        ackIsDisabled=False)
        read_attribute(self,
                       NwkId,
                       ZIGATE_EP,
                       ep,
                       cluster_id,
                       "00",
                       manuf_spec,
                       manuf_id,
                       1,
                       Hattribute,
                       ackIsDisabled=False)
def leaveRequest(self, ShortAddr=None, IEEE=None, RemoveChild=0x00, Rejoin=0x00):
    """
    E_SL_MSG_LEAVE_REQUEST / 0x004C / ZPS_eAplZdoLeaveNetwork
    If you wish to move a whole network branch from under
    the requesting node to a different parent node, set
    bRemoveChildren to FALSE and bRejoin to TRUE.
    """

    _ieee = None

    if IEEE:
        _ieee = IEEE
    else:
        if ShortAddr and ShortAddr in self.ListOfDevices and "IEEE" in self.ListOfDevices[ShortAddr]:
            _ieee = self.ListOfDevices[ShortAddr]["IEEE"]
        else:
            self.log.logging(
                "BasicOutput",
                "Error",
                "leaveRequest - Unable to determine IEEE address for %s %s" % (ShortAddr, IEEE),
                ShortAddr,
                {"Error code": "BOUTPUTS-LEAVE-01", "ListOfDevices": self.ListOfDevices},
            )
            return None

    if Rejoin == 0x00 and ShortAddr:
        ep_list = getListOfEpForCluster(self, ShortAddr, "0000")
        if ep_list:
            self.log.logging(
                "BasicOutput", "Log", "reset_device - Send a Device Reset to %s/%s" % (ShortAddr, ep_list[0]), ShortAddr
            )
            reset_device(self, ShortAddr, ep_list[0])

    _rmv_children = "%02X" % RemoveChild
    _rejoin = "%02X" % Rejoin

    #datas = _ieee + _rmv_children + _rejoin
    self.log.logging(
        "BasicOutput",
        "Debug",
        "---------> Sending a leaveRequest - NwkId: %s, IEEE: %s, RemoveChild: %s, Rejoin: %s"
        % (ShortAddr, IEEE, RemoveChild, Rejoin),
        ShortAddr,
    )
    return zdp_management_leave_request(self, ShortAddr, _ieee, _rejoin, _rmv_children)
def get_group_identifiers_request(self, nwkid):
    cluster_frame = "19"
    sqn = get_and_inc_SQN(self, nwkid)
    command = "41"
    start_index = "00"
    cluster = "1000"
    ListOfEp = getListOfEpForCluster(self, nwkid, cluster)
    if len(ListOfEp) != 1:
        return
    payload = cluster_frame + sqn + command + start_index
    ep = ListOfEp[0]
    raw_APS_request(
        self,
        nwkid,
        ep,
        cluster,
        "0104",
        payload,
        zigate_ep=ZIGATE_EP,
        ackIsDisabled=is_ack_tobe_disabled(self, nwkid),
        highpriority=True,
    )
Exemple #10
0
def thermostat_Setpoint_Danfoss(self, NwkId, setpoint):
    # Command Manufactuer Specific
    # Setpoint command sends: setpointType (enum8) + HeatingSetpoint (16bit)
    # if setpointType = 1 the actuator will make a large movement to minimize reaction time to UI.
    # If setpointType = 0 the behavior will be the same as setting the attribute "Occupied Heating Setpoint" to the same value.
    # if setpointType = 2 displayed setpoint is not effected but regulated setpoint will change. can be used for Forecast functionality
    self.log.logging(
        "Danfoss",
        "Debug",
        "thermostat_Setpoint_Danfoss - for %s with value %s " %
        (NwkId, setpoint),
        nwkid=NwkId,
    )

    if "Param" not in self.ListOfDevices[NwkId]:
        return
    if "DanfossSetPointType" not in self.ListOfDevices[NwkId]["Param"]:
        return
    if not int(self.ListOfDevices[NwkId]["Param"]["DanfossSetPointType"]):
        return
    if int(self.ListOfDevices[NwkId]["Param"]["DanfossSetPointType"]) not in (
            1, 2):
        return

    self.log.logging(
        "Danfoss",
        "Debug",
        "thermostat_Setpoint_Danfoss - for %s with value %s and SetPointType: %s"
        % (NwkId, setpoint,
           int(self.ListOfDevices[NwkId]["Param"]["DanfossSetPointType"])),
        nwkid=NwkId,
    )

    danfoss_setpoint_command = "40"
    danfoss_setpoint_type = "%02x" % int(
        self.ListOfDevices[NwkId]["Param"]["DanfossSetPointType"])
    danfoss_setpoint_value = "%04x" % int(
        (setpoint * 2) / 2)  # Round to 0.5 degrees

    EPout = getListOfEpForCluster(self, NwkId, "0201")
    #
    cluster_id = "%04x" % 0x0201
    manuf_id = "1246"
    sqn = get_and_inc_SQN(self, NwkId)
    cluster_frame = build_fcf("1", "1", "0", "0")
    payload = cluster_frame + manuf_id[2:4] + manuf_id[
        0:
        2] + sqn + danfoss_setpoint_command + danfoss_setpoint_type + danfoss_setpoint_value[
            2:4] + danfoss_setpoint_value[0:2]
    self.log.logging(
        "Danfoss",
        "Debug",
        "thermostat_Setpoint_Danfoss - for %s with cluster_frame: %s payload: %s "
        % (NwkId, cluster_frame, payload),
        nwkid=NwkId,
    )

    for ep in EPout:
        raw_APS_request(
            self,
            NwkId,
            ep,
            cluster_id,
            "0104",
            payload,
            zigate_ep=ZIGATE_EP,
            ackIsDisabled=is_ack_tobe_disabled(self, NwkId),
        )