Example #1
0
def tuya_cmd(self,
             nwkid,
             EPout,
             cluster_frame,
             sqn,
             cmd,
             action,
             data,
             action2=None,
             data2=None):
    if nwkid not in self.ListOfDevices:
        return
    transid = "%02x" % get_next_tuya_transactionId(self, nwkid)
    len_data = (len(data)) // 2
    payload = cluster_frame + sqn + cmd + "00" + transid + action + "00" + "%02x" % len_data + data
    if action2 and data2:
        len_data2 = (len(data2)) // 2
        payload += action2 + "00" + "%02x" % len_data2 + data2
    raw_APS_request(
        self,
        nwkid,
        EPout,
        "ef00",
        "0104",
        payload,
        zigate_ep=ZIGATE_EP,
        ackIsDisabled=is_ack_tobe_disabled(self, nwkid),
    )
    self.log.logging(
        "Tuya", "Debug",
        "tuya_cmd - %s/%s cmd: %s payload: %s" % (nwkid, EPout, cmd, payload))
Example #2
0
def poll_checkin_response_command(self,
                                  Sqn,
                                  nwkid,
                                  ep,
                                  ContinueFastPoll=True,
                                  DurationFastPoll=0xFC0):

    # Poll Control: Check-in Response
    # 0 quarterseconds ( 0xFC0 => 1 minute of Fast Polling)

    Domoticz.Log("poll_checkin_response_command %s/%s %s %s" %
                 (nwkid, ep, ContinueFastPoll, DurationFastPoll))

    cmd = "00"  # Check-in Response
    if nwkid not in self.ListOfDevices:
        Domoticz.Error(" - nwkid: %s do not exist" % nwkid)
        return
    cluster_id = "0020"  # Poll Control Cluster
    ContinueFastPoll = "%02x" % ContinueFastPoll
    DurationFastPoll = "%04x" % (struct.unpack(
        ">H", struct.pack("H", int("%04x" % DurationFastPoll, 16)))[0])

    cluster_frame = "11"
    payload = cluster_frame + Sqn + cmd + ContinueFastPoll + DurationFastPoll
    raw_APS_request(self, nwkid, ep, "0020", "0104", payload)
    Domoticz.Log("Accept Fast Poll command 0x%s for %s/%s with payload: %s" %
                 (cmd, nwkid, ep, payload))
def cluster0101_toggle_door(self, NwkId):

    cmd = "02"
    # determine which Endpoint
    EPout = "01"
    sqn = get_and_inc_SQN(self, NwkId)

    # Cluster Frame:
    # 0b xxxx xxxx
    #           |- Frame Type: Cluster Specific (0x01)
    #          |-- Manufacturer Specific False
    #         |--- Command Direction: Client to Server (0)
    #       | ---- Disable default response: True
    #    |||- ---- Reserved : 0x000
    #  ClusterFrame: 0b0001 0001
    cluster_frame = "11"

    payload = cluster_frame + sqn + cmd
    raw_APS_request(self,
                    NwkId,
                    "01",
                    "0101",
                    "0104",
                    payload,
                    zigate_ep=ZIGATE_EP)
Example #4
0
def poll_fast_poll_stop(self, Sqn, nwkid, ep):

    # Fast Poll Stop to be called for Remote Devices
    Domoticz.Log("poll_fast_poll_stop %s/%s" % (nwkid, ep))
    cmd = "01"  # Fast Poll Stop ( no data)

    if nwkid not in self.ListOfDevices:
        Domoticz.Error("Fast Poll Stop - nwkid: %s do not exist" % nwkid)
        return

    cluster_id = "0020"  # Poll Control Cluster
    cluster_frame = "11"
    payload = cluster_frame + Sqn + cmd
    raw_APS_request(self, nwkid, ep, "0020", "0104", payload)
    Domoticz.Log(
        "send Fast Poll Stop command 0x%s for %s/%s with payload: %s" %
        (cmd, nwkid, ep, payload))
Example #5
0
def tuya_cmd_0x0000_0xf0(self, NwkId):

    # Seen at pairing of a WGH-JLCZ02 / TS011F and TS0201 and TS0601 (MOES BRT-100)

    payload = "11" + get_and_inc_SQN(self, NwkId) + "fe"
    raw_APS_request(
        self,
        NwkId,
        '01',
        "0000",
        "0104",
        payload,
        zigate_ep=ZIGATE_EP,
        ackIsDisabled=is_ack_tobe_disabled(self, NwkId),
    )
    self.log.logging(
        "Tuya", "Debug",
        "tuya_cmd_0x0000_0xf0 - Nwkid: %s reset device Cmd: fe" % NwkId)
Example #6
0
def default_response_for_philips_hue_reporting_attribute(
        self, Nwkid, srcEp, cluster, sqn):

    fcf = "10"
    cmd = "0b"
    cmd_reporting_attribute = "0a"
    status = "00"
    payload = fcf + sqn + cmd + cmd_reporting_attribute + "00"
    raw_APS_request(self,
                    Nwkid,
                    srcEp,
                    cluster,
                    "0104",
                    payload,
                    zigate_ep=ZIGATE_EP,
                    ackIsDisabled=False)
    self.log.logging(
        "Philips", "Log",
        "default_response_for_philips_hue_reporting_attribute - %s/%s " %
        (Nwkid, srcEp))
Example #7
0
def send_timesynchronisation(self, NwkId, srcEp, ClusterID, dstNWKID, dstEP,
                             serial_number):

    # Request: cmd: 0x24  Data: 0x0008
    # 0008 600d8029 600d8e39
    # Request: cmd: 0x24 Data: 0x0053
    # 0053 60e9ba1f  60e9d63f
    if NwkId not in self.ListOfDevices:
        return
    sqn = get_and_inc_SQN(self, NwkId)

    field1 = "0d"
    field2 = "80"
    field3 = "29"

    EPOCTime = datetime(1970, 1, 1)
    now = datetime.utcnow()
    UTCTime_in_sec = int((now - EPOCTime).total_seconds())
    LOCALtime_in_sec = int((utc_to_local(now) - EPOCTime).total_seconds())

    utctime = "%08x" % UTCTime_in_sec
    localtime = "%08x" % LOCALtime_in_sec
    self.log.logging(
        "Tuya",
        "Debug",
        "send_timesynchronisation - %s/%s UTC: %s Local: %s" %
        (NwkId, srcEp, UTCTime_in_sec, LOCALtime_in_sec),
    )

    payload = "11" + sqn + "24" + serial_number + utctime + localtime
    raw_APS_request(self,
                    NwkId,
                    srcEp,
                    "ef00",
                    "0104",
                    payload,
                    zigate_ep=ZIGATE_EP,
                    ackIsDisabled=False)
    self.log.logging("Tuya", "Debug",
                     "send_timesynchronisation - %s/%s " % (NwkId, srcEp))
Example #8
0
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,
    )
Example #9
0
def read_attribute_response(self,
                            nwkid,
                            ep,
                            sqn,
                            cluster,
                            status,
                            data_type,
                            attribute,
                            value,
                            manuf_code="0000"):
    # self.log.logging( None, 'Log', "Nwkid: %s Ep: %s Sqn: %s Cluster: %s Status: %s Data_Type: %s Attribute: %s Value: %s" \
    #    %( nwkid, ep, sqn, cluster, status, data_type, attribute, value))

    cmd = "01"  # Attribute Response
    if manuf_code == "0000":
        manuf_specific = "00"

    attribute = "%04x" % struct.unpack(
        "H", struct.pack(">H", int(attribute, 16)))[0]

    if manuf_code == "0000":
        cluster_frame = "18"  # Profile-wide, Server to Client, Disable default Response
        payload = cluster_frame + sqn + cmd
    else:
        cluster_frame = "28"  # Manufacturer Specific , Server to Client, Disable default Response
        payload = cluster_frame + manuf_code + sqn + cmd

    payload += attribute + status
    if status == "00":
        payload += data_type + encode_endian_data(value, data_type)

    # self.log.logging( None, 'Log', "read_attribute_response - %s/%s Cluster: %s Payload: %s" %(nwkid, ep, cluster, payload))
    raw_APS_request(self,
                    nwkid,
                    ep,
                    cluster,
                    "0104",
                    payload,
                    zigate_ep=ZIGATE_EP)
Example #10
0
def poll_set_short_poll_interval(self,
                                 Sqn,
                                 nwkid,
                                 ep,
                                 NewShortPollInterval=0x2):

    Domoticz.Log("poll_set_short_poll_interval %s/%s %s" %
                 (nwkid, ep, NewShortPollInterval))
    cmd = "03"

    NewShortPollInterval = "%04x" % (struct.unpack(
        ">H", struct.pack("H", int("%04x" % NewShortPollInterval, 16)))[0])

    if nwkid not in self.ListOfDevices:
        Domoticz.Error(" - nwkid: %s do not exist" % nwkid)
        return
    cluster_id = "0020"  # Poll Control Cluster
    cluster_frame = "11"

    payload = cluster_frame + Sqn + cmd + NewShortPollInterval
    raw_APS_request(self, nwkid, ep, "0020", "0104", payload)
    Domoticz.Log("Accept Fast Poll command 0x%s for %s/%s with payload: %s" %
                 (cmd, nwkid, ep, payload))
Example #11
0
def poll_checkin_command(self, Sqn, snwkid, ep):
    # Server -> End Device
    # The Poll Control Cluster server sends out a Check-in command to the devices to which it is paired based on the server’s Check-inIntervalattribute.
    # It does this to find out if any of the Poll Control Cluster Clients with which it is paired are interested in having it enter fastpoll mode
    # so that it can be managed. This request is sent out based on either the Check-inInterval,
    # or the next Check-in value in the Fast Poll Stop Request generated by the Poll Control Cluster Client.
    # The Check-in command expects a Check-in Response command to be sent back from the Poll Control Client.
    # If the Poll Control Server does not receive a Check-in response back from the Poll Control Client up to7.68 seconds
    # it is free to return to polling according to the LongPollInterval.

    Domoticz.Log("poll_checkin_command %s %s" % (snwkid, ep))
    cmd = "00"
    if snwkid not in self.ListOfDevices:
        Domoticz.Error(" - nwkid: %s do not exist" % snwkid)
        return
    cluster_id = "0020"  # Poll Control Cluster

    cluster_frame = "11"

    payload = cluster_frame + Sqn + cmd
    raw_APS_request(self, snwkid, ep, "0020", "0104", payload)
    Domoticz.Log("Accept Fast Poll command 0x%s for %s/%s with payload: %s" %
                 (cmd, snwkid, ep, payload))
    return
Example #12
0
def tuya_send_default_response(self, Nwkid, srcEp, sqn, cmd, orig_fcf):
    if Nwkid not in self.ListOfDevices:
        return

    orig_fcf = int(orig_fcf, 16)
    frame_type = "%02x" % (0b00000011 & orig_fcf)
    manuf_spec = "%02x" % ((0b00000100 & orig_fcf) >> 2)
    direction = "%02x" % (not ((0b00001000 & orig_fcf) >> 3))
    disabled_default = "%02x" % ((0b00010000 & orig_fcf) >> 4)

    if disabled_default == "01":
        return

    fcf = build_fcf("00", manuf_spec, direction, disabled_default)

    payload = fcf + sqn + "0b"
    if manuf_spec == "01":
        payload += TUYA_MANUF_CODE[2:4] + TUYA_MANUF_CODE[0:2]
    payload += cmd + "00"
    raw_APS_request(
        self,
        Nwkid,
        srcEp,
        "ef00",
        "0104",
        payload,
        zigate_ep=ZIGATE_EP,
        highpriority=True,
        ackIsDisabled=is_ack_tobe_disabled(self, Nwkid),
    )
    self.log.logging(
        "Tuya",
        "Debug",
        "tuya_send_default_response - %s/%s fcf: 0x%s ManufSpec: 0x%s Direction: 0x%s DisableDefault: 0x%s"
        % (Nwkid, srcEp, fcf, manuf_spec, direction, disabled_default),
    )
Example #13
0
def tuya_sirene_registration(self, nwkid):

    self.log.logging("Tuya", "Debug", "tuya_sirene_registration - Nwkid: %s" % nwkid)

    EPout = "01"
    payload = "11" + get_and_inc_SQN(self, nwkid) + "10" + "002a"
    raw_APS_request(
        self,
        nwkid,
        EPout,
        "ef00",
        "0104",
        payload,
        zigate_ep=ZIGATE_EP,
        ackIsDisabled=is_ack_tobe_disabled(self, nwkid),
    )

    # (1) 3 x Write Attribute Cluster 0x0000 - Attribute 0xffde  - DT 0x20  - Value: 0x13
    EPout = "01"
    write_attribute(self, nwkid, ZIGATE_EP, EPout, "0000", "0000", "00", "ffde", "20", "13", ackIsDisabled=False)

    # (2) Cmd 0xf0 send on Cluster 0x0000 - no data
    payload = "11" + get_and_inc_SQN(self, nwkid) + "f0"
    raw_APS_request(
        self,
        nwkid,
        EPout,
        "0000",
        "0104",
        payload,
        zigate_ep=ZIGATE_EP,
        ackIsDisabled=is_ack_tobe_disabled(self, nwkid),
    )

    # (3) Cmd 0x03 on Cluster 0xef00  (Cluster Specific)
    payload = "11" + get_and_inc_SQN(self, nwkid) + "03"
    raw_APS_request(
        self,
        nwkid,
        EPout,
        "ef00",
        "0104",
        payload,
        zigate_ep=ZIGATE_EP,
        ackIsDisabled=is_ack_tobe_disabled(self, nwkid),
    )

    # Set the Siren to °C
    tuya_siren_temp_unit(self, nwkid, unit="C")
Example #14
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),
        )
Example #15
0
def tuya_registration(self, nwkid, device_reset=False, parkside=False):
    if "Model" not in self.ListOfDevices[nwkid]:
        return
    _ModelName = self.ListOfDevices[nwkid]["Model"]

    self.log.logging(
        "Tuya", "Debug",
        "tuya_registration - Nwkid: %s Model: %s" % (nwkid, _ModelName))

    # (1) 3 x Write Attribute Cluster 0x0000 - Attribute 0xffde  - DT 0x20  - Value: 0x13 ( 19 Decimal)
    #  It looks like for Lidl Watering switch the Value is 0x0d ( 13 in decimal )
    EPout = "01"
    self.log.logging(
        "Tuya", "Debug",
        "tuya_registration - Nwkid: %s ----- 0x13 in 0x0000/0xffde" % nwkid)
    if parkside:
        write_attribute(self,
                        nwkid,
                        ZIGATE_EP,
                        EPout,
                        "0000",
                        "0000",
                        "00",
                        "ffde",
                        "20",
                        "0d",
                        ackIsDisabled=True)
    else:
        write_attribute(self,
                        nwkid,
                        ZIGATE_EP,
                        EPout,
                        "0000",
                        "0000",
                        "00",
                        "ffde",
                        "20",
                        "13",
                        ackIsDisabled=True)

    # (3) Cmd 0x03 on Cluster 0xef00  (Cluster Specific) / Zigbee Device Reset
    if device_reset:
        payload = "11" + get_and_inc_SQN(self, nwkid) + "03"
        raw_APS_request(
            self,
            nwkid,
            EPout,
            "ef00",
            "0104",
            payload,
            zigate_ep=ZIGATE_EP,
            ackIsDisabled=is_ack_tobe_disabled(self, nwkid),
        )
        self.log.logging(
            "Tuya", "Debug",
            "tuya_registration - Nwkid: %s reset device Cmd: 03" % nwkid)

    # Gw->Zigbee gateway query MCU version
    self.log.logging(
        "Tuya", "Debug",
        "tuya_registration - Nwkid: %s Request MCU Version Cmd: 10" % nwkid)
    if _ModelName in ("TS0601-_TZE200_nklqjk62", ):
        payload = "11" + get_and_inc_SQN(self, nwkid) + "10" + "000e"
    else:
        payload = "11" + get_and_inc_SQN(self, nwkid) + "10" + "0002"
    raw_APS_request(
        self,
        nwkid,
        EPout,
        "ef00",
        "0104",
        payload,
        zigate_ep=ZIGATE_EP,
        ackIsDisabled=is_ack_tobe_disabled(self, nwkid),
    )