def callBackForWriteAttributeIfNeeded(self, key): # Scan for this device if there are any pending Write Attributes needed. if key not in self.ListOfDevices: return if "Ep" not in self.ListOfDevices[key]: return for endpoint in self.ListOfDevices[key]["Ep"]: for clusterId in self.ListOfDevices[key]["Ep"][endpoint]: if clusterId in ("Type", "ColorMode", "ClusterType"): continue for attribute in list( get_list_waiting_request_datastruct( self, "WriteAttributes", key, endpoint, clusterId)): self.log.logging( "WriteAttributes", "Debug", "device awake let's write attribute for %s/%s" % (key, endpoint), key) request = get_request_datastruct(self, "WriteAttributes", key, endpoint, clusterId, attribute) if request is None: continue data_type, EPin, EPout, manuf_id, manuf_spec, data, ackIsDisabled = request write_attribute(self, key, EPin, EPout, clusterId, manuf_id, manuf_spec, attribute, data_type, data, ackIsDisabled)
def thermostat_eurotronic_hostflag(self, NwkId, action): HOSTFLAG_ACTION = { "turn_display": 0x000002, "boost": 0x000004, "clear_off": 0x000010, "set_off_mode": 0x000020, "child_lock": 0x000080, } if action not in HOSTFLAG_ACTION: self.log.logging("Thermostats", "Log", "thermostat_eurotronic_hostflag - unknown action %s" % action) return manuf_id = "0000" manuf_spec = "00" cluster_id = "%04x" % 0x0201 attribute = "%04x" % 0x4008 data_type = "22" # U24 data = "%06x" % HOSTFLAG_ACTION[action] EPout = "01" for tmpEp in self.ListOfDevices[NwkId]["Ep"]: if "0201" in self.ListOfDevices[NwkId]["Ep"][tmpEp]: EPout = tmpEp write_attribute(self, NwkId, "01", EPout, cluster_id, manuf_id, manuf_spec, attribute, data_type, data) self.log.logging( "Thermostats", "Debug", "thermostat_eurotronic_hostflag - for %s with value %s / cluster: %s, attribute: %s type: %s action: %s" % (NwkId, data, cluster_id, attribute, data_type, action), nwkid=NwkId, )
def setXiaomiVibrationSensitivity(self, key, sensitivity="medium"): VIBRATION_SENSIBILITY = {"high": 0x01, "medium": 0x0B, "low": 0x15} if sensitivity not in VIBRATION_SENSIBILITY: sensitivity = "medium" manuf_id = "115f" manuf_spec = "01" cluster_id = "%04x" % 0x0000 attribute = "%04x" % 0xFF0D data_type = "20" # Int8 data = "%02x" % VIBRATION_SENSIBILITY[sensitivity] write_attribute( self, key, ZIGATE_EP, "01", cluster_id, manuf_id, manuf_spec, attribute, data_type, data, ackIsDisabled=is_ack_tobe_disabled(self, key), )
def danfoss_control_algo(self, NwkId, mode): # Scale factor of setpoint filter timeconstant ("aggressiveness" of control algorithm) 1= Quick ... 5=Moderate ... 10=Slow manuf_id = "1246" manuf_spec = "01" cluster_id = "%04x" % 0x0201 Hattribute = "%04x" % 0x4020 data_type = "20" # Uint8 self.log.logging("Thermostats", "Debug", "Danfoss Aly Control_Algo: %s" % mode, nwkid=NwkId) Hdata = "%02x" % mode EPout = "01" for tmpEp in self.ListOfDevices[NwkId]["Ep"]: if "0201" in self.ListOfDevices[NwkId]["Ep"][tmpEp]: EPout = tmpEp self.log.logging( "Thermostats", "Debug", "danfoss_control_algo - for %s with value %s / cluster: %s, attribute: %s type: %s" % (NwkId, Hdata, cluster_id, Hattribute, data_type), nwkid=NwkId, ) write_attribute(self, NwkId, "01", EPout, cluster_id, manuf_id, manuf_spec, Hattribute, data_type, Hdata)
def danfoss_orientation(self, NwkId, orientation): # 0110 02 955e 01 01 0201 00 01 1246 01 4014 10 01 orient = 0 if orientation == "V": orient = 1 elif orientation == "H": orient = 0 else: return manuf_id = "1246" manuf_spec = "01" cluster_id = "%04x" % 0x0201 EPout = "01" for tmpEp in self.ListOfDevices[NwkId]["Ep"]: if "0201" in self.ListOfDevices[NwkId]["Ep"][tmpEp]: EPout = tmpEp Hattribute = "%04x" % 0x4014 data_type = "10" # boolean self.log.logging("Danfoss", "Debug", "danfoss_orientation: %s" % orient, nwkid=NwkId) Hdata = "%02x" % orient self.log.logging( "Danfoss", "Debug", "danfoss_orientation for %s with value %s / cluster: %s, attribute: %s type: %s" % (NwkId, Hdata, cluster_id, Hattribute, data_type), nwkid=NwkId, ) write_attribute(self, NwkId, ZIGATE_EP, EPout, cluster_id, manuf_id, manuf_spec, Hattribute, data_type, Hdata, ackIsDisabled=False) read_attribute(self, NwkId, ZIGATE_EP, EPout, cluster_id, "00", manuf_spec, manuf_id, 1, Hattribute, ackIsDisabled=False)
def Thermostat_LockMode(self, NwkId, lockmode): LOCK_MODE = {"unlocked": 0x00, "templock": 0x02, "off": 0x04, "off-2": 0x05} if lockmode not in LOCK_MODE: return manuf_id = "0000" manuf_spec = "00" cluster_id = "%04x" % 0x0204 Hattribute = "%04x" % 0x0001 data_type = "30" # Int16 self.log.logging("Thermostats", "Debug", "lockmode: %s" % lockmode, nwkid=NwkId) lockmode = LOCK_MODE[lockmode] Hdata = "%02x" % lockmode EPout = "01" for tmpEp in self.ListOfDevices[NwkId]["Ep"]: if "0204" in self.ListOfDevices[NwkId]["Ep"][tmpEp]: EPout = tmpEp self.log.logging( "Thermostats", "Debug", "Thermostat_LockMode - for %s with value %s / cluster: %s, attribute: %s type: %s" % (NwkId, Hdata, cluster_id, Hattribute, data_type), nwkid=NwkId, ) write_attribute(self, NwkId, "01", EPout, cluster_id, manuf_id, manuf_spec, Hattribute, data_type, Hdata) write_attribute(self, NwkId, "01", EPout, cluster_id, manuf_id, manuf_spec, Hattribute, data_type, Hdata)
def OrviboRegistration(self, nwkid): cluster = "0000" attribute = "0099" datatype = "20" value = "01" EPout = "01" for tmpEp in self.ListOfDevices[nwkid]["Ep"]: if "0000" in self.ListOfDevices[nwkid]["Ep"][tmpEp]: EPout = tmpEp # Set Commissioning as Done manuf_id = "0000" manuf_spec = "00" cluster_id = "0000" Hattribute = "0099" data_type = "20" # Bool data = "01" Domoticz.Log("Orvibo registration for %s" % nwkid) write_attribute( self, nwkid, ZIGATE_EP, EPout, cluster_id, manuf_id, manuf_spec, Hattribute, data_type, data, ackIsDisabled=is_ack_tobe_disabled(self, nwkid), )
def tuya_cmd_ts004F(self, NwkId, mode): TS004F_MODE = { 'Scene': 0x01, # Scene controller 'Dimmer': 0x00, # Remote dimming } # By default set to 0x00 if mode not in TS004F_MODE: return write_attribute(self, NwkId, ZIGATE_EP, "01", "0006", "0000", "00", "8004", "30", '%02x' % TS004F_MODE[mode], ackIsDisabled=False) ieee = self.ListOfDevices[NwkId]['IEEE'] cluster = "0006" bindDevice(self, ieee, "01", cluster, destaddr=None, destep="01") bindDevice(self, ieee, "02", cluster, destaddr=None, destep="01") bindDevice(self, ieee, "03", cluster, destaddr=None, destep="01") bindDevice(self, ieee, "04", cluster, destaddr=None, destep="01")
def danfoss_exercise_trigger_time(self, NwkId, min_from_midnight): # Minutes since midnight, 0xFFFF = undefined if min_from_midnight > 1439: return manuf_id = "1246" manuf_spec = "01" cluster_id = "%04x" % 0x0201 EPout = "01" for tmpEp in self.ListOfDevices[NwkId]["Ep"]: if "0201" in self.ListOfDevices[NwkId]["Ep"][tmpEp]: EPout = tmpEp Hattribute = "%04x" % 0x4011 data_type = "21" # uint16 self.log.logging("Danfoss", "Debug", "Danfoss Aly Trigger_time Min from Midnigh: %s" % min_from_midnight, nwkid=NwkId) Hdata = "%04x" % min_from_midnight EPout = "01" self.log.logging( "Danfoss", "Debug", "danfoss_exercise_trigger_time - Trigger time for %s with value %s / cluster: %s, attribute: %s type: %s" % (NwkId, Hdata, cluster_id, Hattribute, data_type), nwkid=NwkId, ) write_attribute(self, NwkId, "01", EPout, cluster_id, manuf_id, manuf_spec, Hattribute, data_type, Hdata, ackIsDisabled=False) read_attribute(self, NwkId, ZIGATE_EP, EPout, cluster_id, "00", manuf_spec, manuf_id, 1, Hattribute, ackIsDisabled=False)
def danfoss_write_external_sensor_temp(self, NwkId, temp): # 0110 02 955e 01 01 0201 00 01 1246 01 4015 29 02bc # Convert value to a 0.5 multiple temp = 50 * (temp // 50) manuf_id = "1246" manuf_spec = "01" cluster_id = "%04x" % 0x0201 EPout = "01" for tmpEp in self.ListOfDevices[NwkId]["Ep"]: if "0201" in self.ListOfDevices[NwkId]["Ep"][tmpEp]: EPout = tmpEp Hattribute = "%04x" % 0x4015 data_type = "29" # Int16 self.log.logging("Danfoss", "Debug", "danfoss_write_external_sensor_temp: %s" % temp, nwkid=NwkId) Hdata = "%04x" % temp self.log.logging( "Danfoss", "Debug", "danfoss_write_external_sensor_temp - Trigger time for %s with value %s / cluster: %s, attribute: %s type: %s" % (NwkId, Hdata, cluster_id, Hattribute, data_type), nwkid=NwkId, ) write_attribute(self, NwkId, ZIGATE_EP, EPout, cluster_id, manuf_id, manuf_spec, Hattribute, data_type, Hdata, ackIsDisabled=False) read_attribute(self, NwkId, ZIGATE_EP, EPout, cluster_id, "00", manuf_spec, manuf_id, 1, Hattribute, ackIsDisabled=False)
def tuya_window_cover_calibration(self, nwkid, start_stop): # (0x0102) | Write Attributes (0x02) | 0xf001 | 8-Bit (0x30) | 0 (0x00) | Start Calibration # (0x0102) | Write Attributes (0x02) | 0xf001 | 8-Bit (0x30) | 1 (0x01) | End Calibration write_attribute(self, nwkid, ZIGATE_EP, "01", "0102", "0000", "00", "f001", "30", start_stop, ackIsDisabled=True)
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 thermostat_Mode(self, NwkId, mode): SYSTEM_MODE = { "Off": 0x00, "Auto": 0x01, "Reserved": 0x02, "Cool": 0x03, "Heat": 0x04, "Emergency Heating": 0x05, "Pre-cooling": 0x06, "Fan Only": 0x07, "Dry": 0x08, "Sleep": 0x09, } if mode not in SYSTEM_MODE: Domoticz.Error("thermostat_Mode - unknown system mode: %s" % mode) return if "Model" in self.ListOfDevices[NwkId] and self.ListOfDevices[NwkId]["Model"] in ("AC211", "AC221", "CAC221"): casaia_check_irPairing(self, NwkId) manuf_id = "0000" manuf_spec = "00" cluster_id = "%04x" % 0x0201 attribute = "%04x" % 0x001C data_type = "30" # Enum8 data = "%02x" % SYSTEM_MODE[mode] EPout = "01" for tmpEp in self.ListOfDevices[NwkId]["Ep"]: if "0201" in self.ListOfDevices[NwkId]["Ep"][tmpEp]: EPout = tmpEp write_attribute(self, NwkId, "01", EPout, cluster_id, manuf_id, manuf_spec, attribute, data_type, data) self.log.logging( "Thermostats", "Debug", "thermostat_Mode - for %s with value %s / cluster: %s, attribute: %s type: %s" % (NwkId, data, cluster_id, attribute, data_type), nwkid=NwkId, ) if "Model" in self.ListOfDevices[NwkId] and self.ListOfDevices[NwkId]["Model"] in ("TAFFETAS2 D1.00P1.01Z1.00"): self.log.logging( "Thermostats", "Log", "thermostat_Mode - for %s with value %s / cluster: %s, attribute: %s type: %s" % (NwkId, data, cluster_id, attribute, data_type), nwkid=NwkId, )
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")
def philips_set_pir_occupancySensibility(self, nwkid, level): if level in (0, 1, 2): write_attribute(self, nwkid, ZIGATE_EP, "02", "0406", "100b", "01", "0030", "20", "%02x" % level, ackIsDisabled=False) ReadAttributeRequest_0406_philips_0030(self, nwkid)
def tuya_window_cover_motor_reversal(self, nwkid, mode): # (0x0102) | Write Attributes (0x02) | 0xf002 | 8-Bit (0x30) | 0 (0x00) | Off # (0x0102) | Write Attributes (0x02) | 0xf002 | 8-Bit (0x30) | 1 (0x01) | On if int(mode) in (0, 1): write_attribute(self, nwkid, ZIGATE_EP, "01", "0102", "0000", "00", "f002", "30", "%02x" % int(mode), ackIsDisabled=True)
def tuya_TS0121_registration(self, NwkId): self.log.logging("Tuya", "Debug", "tuya_TS0121_registration - Nwkid: %s" % 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)
def setPowerOn_OnOff(self, key, OnOffMode=0xFF): # OSRAM/LEDVANCE # 0xfc0f --> Command 0x01 # 0xfc01 --> Command 0x01 # Tested on Ikea Bulb without any results ! POWERON_MODE = (0x00, 0x01, 0xFE) # Off # On # Previous state if "Manufacturer" in self.ListOfDevices[key]: manuf_spec = "01" manuf_id = self.ListOfDevices[key]["Manufacturer"] else: manuf_spec = "00" manuf_id = "0000" EPin = "01" EPout = "01" for tmpEp in self.ListOfDevices[key]["Ep"]: if "0006" in self.ListOfDevices[key]["Ep"][tmpEp]: EPout = tmpEp cluster_id = "0006" attribute = "4003" data_type = "30" # data = "ff" data = "%02x" % OnOffMode if OnOffMode in POWERON_MODE else "%02x" % 255 self.log.logging( "Output", "Debug", "set_PowerOn_OnOff for %s/%s - OnOff: %s" % (key, EPout, OnOffMode), key) write_attribute( self, key, "01", EPout, cluster_id, manuf_id, manuf_spec, attribute, data_type, data, ackIsDisabled=is_ack_tobe_disabled(self, key), ) ReadAttributeRequest_0006_400x(self, key)
def cable_connected_mode(self, nwkid, Mode): data_type = "09" # 16-bit Data Hattribute = "0000" Hdata = "0000" if Mode == "10": # Sortie de Cable: 0x0100 # Radiateur sans FIP: 0x0100 # Appareil de cuisine: 0x0100 Hdata = "0100" # Disable FIP elif Mode == "20": # FIP # Radiateur avec FIP: 0x0200 + Bind fc40 + configReporting ( fc40 / 0000 / TimeOut 600 ) Hdata = "0200" # Enable FIP manuf_id = "0000" manuf_spec = "00" cluster_id = "%04x" % 0xFC01 EPout = "01" for tmpEp in self.ListOfDevices[nwkid]["Ep"]: if "fc01" in self.ListOfDevices[nwkid]["Ep"][tmpEp]: EPout = tmpEp write_attribute( self, nwkid, "01", EPout, cluster_id, manuf_id, manuf_spec, Hattribute, data_type, Hdata[2:4] + Hdata[0:2], ackIsDisabled=is_ack_tobe_disabled(self, nwkid), ) ReadAttributeRequest_0006_0000(self, nwkid) ReadAttributeRequest_0b04_050b(self, nwkid) ReadAttributeRequest_fc40(self, nwkid)
def tuya_backlight_command(self, nwkid, mode): # 0x0006 / 0x80001 # Indicator LED off: 0x00 # Indicator switch On/Off: 0x01 # Indicate swicth location: 0x02 # (0x0006) | Write Attributes (0x02) | 0x8001 | 8-Bit (0x30) | 0 (0x00) | Light Mode 1 # (0x0006) | Write Attributes (0x02) | 0x8001 | 8-Bit (0x30) | 1 (0x01) | Light Mode 2 # (0x0006) | Write Attributes (0x02) | 0x8001 | 8-Bit (0x30) | 2 (0x02) | Light Mode 3 if int(mode) in (0, 1, 2): write_attribute(self, nwkid, ZIGATE_EP, "01", "0006", "0000", "00", "8001", "30", "%02x" % int(mode), ackIsDisabled=True)
def casaia_swing_OnOff(self, NwkId, OnOff): if OnOff not in ("00", "01"): return EPout = get_ffad_endpoint(self, NwkId) write_attribute( self, NwkId, ZIGATE_EP, EPout, "0201", CASAIA_MANUF_CODE, "01", "fd00", "10", OnOff, ackIsDisabled=is_ack_tobe_disabled(self, NwkId), ) self.log.logging( "CasaIA", "Debug", "swing_OnOff ++++ %s/%s OnOff: %s" % (NwkId, EPout, OnOff), NwkId)
def enableOppleSwitch(self, nwkid): if nwkid not in self.ListOfDevices: return if "Model" not in self.ListOfDevices[nwkid]: return if (self.ListOfDevices[nwkid]["Model"] in ("lumi.remote.b686opcn01-bulb", "lumi.remote.b486opcn01-bulb", "lumi.remote.b286opcn01-bulb") and "Lumi" not in self.ListOfDevices[nwkid]): self.ListOfDevices[nwkid]["Lumi"] = {"AqaraOppleBulbMode": True} return manuf_id = "115f" manuf_spec = "01" cluster_id = "fcc0" Hattribute = "0009" data_type = "20" Hdata = "01" self.log.logging( "Lumi", "Debug", "Write Attributes LUMI Opple Magic Word Nwkid: %s" % nwkid, nwkid) write_attribute( self, nwkid, ZIGATE_EP, "01", cluster_id, manuf_id, manuf_spec, Hattribute, data_type, Hdata, ackIsDisabled=is_ack_tobe_disabled(self, nwkid), )
def change_fan_mode(self, NwkId, Ep, fan_mode): if fan_mode not in FAN_MODE: return if "Model" in self.ListOfDevices[NwkId] and self.ListOfDevices[NwkId]["Model"] in ("AC211", "AC221", "CAC221"): casaia_check_irPairing(self, NwkId) # Fan Mode Sequence data = "%02x" % 0x02 write_attribute( self, NwkId, ZIGATE_EP, Ep, "0202", "0000", "00", "0001", "30", data, ackIsDisabled=is_ack_tobe_disabled(self, NwkId), ) data = "%02x" % FAN_MODE[fan_mode] write_attribute( self, NwkId, ZIGATE_EP, Ep, "0202", "0000", "00", "0000", "30", data, ackIsDisabled=is_ack_tobe_disabled(self, NwkId), )
def thermostat_Setpoint_SPZB(self, NwkId, setpoint): manuf_id = "1037" manuf_spec = "01" cluster_id = "%04x" % 0x0201 Hattribute = "%04x" % 0x4003 data_type = "29" # Int16 self.log.logging("Thermostats", "Debug", "setpoint: %s" % setpoint, nwkid=NwkId) setpoint = int((setpoint * 2) / 2) # Round to 0.5 degrees self.log.logging("Thermostats", "Debug", "setpoint: %s" % setpoint, nwkid=NwkId) Hdata = "%04x" % setpoint EPout = "01" for tmpEp in self.ListOfDevices[NwkId]["Ep"]: if "0201" in self.ListOfDevices[NwkId]["Ep"][tmpEp]: EPout = tmpEp self.log.logging( "Thermostats", "Debug", "thermostat_Setpoint_SPZB - for %s with value %s / cluster: %s, attribute: %s type: %s" % (NwkId, Hdata, cluster_id, Hattribute, data_type), nwkid=NwkId, ) write_attribute(self, NwkId, "01", EPout, cluster_id, manuf_id, manuf_spec, Hattribute, data_type, Hdata)
def thermostat_Setpoint(self, NwkId, setpoint): self.log.logging("Thermostats", "Debug", "thermostat_Setpoint - for %s with value %s" % (NwkId, setpoint), nwkid=NwkId) if "Model" in self.ListOfDevices[NwkId] and self.ListOfDevices[NwkId]["Model"] != {}: if self.ListOfDevices[NwkId]["Model"] == "SPZB0001": # Eurotronic self.log.logging( "Thermostats", "Debug", "thermostat_Setpoint - calling SPZB for %s with value %s" % (NwkId, setpoint), nwkid=NwkId, ) thermostat_Calibration(self, NwkId) thermostat_Setpoint_SPZB(self, NwkId, setpoint) return if self.ListOfDevices[NwkId]["Model"] in ("EH-ZB-RTS", "EH-ZB-HACT", "EH-ZB-VACT", "Wiser2-Thermostat", "iTRV"): # Schneider self.log.logging( "Thermostats", "Debug", "thermostat_Setpoint - calling Schneider for %s with value %s" % (NwkId, setpoint), nwkid=NwkId, ) schneider_setpoint(self, NwkId, setpoint) return if self.ListOfDevices[NwkId]["Model"] in (TUYA_eTRV_MODEL): # Tuya self.log.logging( "Thermostats", "Debug", "thermostat_Setpoint - calling Tuya for %s with value %s" % (NwkId, setpoint), nwkid=NwkId, ) tuya_setpoint(self, NwkId, setpoint) return if self.ListOfDevices[NwkId]["Model"] in ("AC201A",): casaia_setpoint(self, NwkId, setpoint) return if self.ListOfDevices[NwkId]["Model"] in ("eTRV0100", "eT093WRO"): if "Param" in self.ListOfDevices[NwkId] and "DanfossSetPointType" in self.ListOfDevices[NwkId]["Param"] and int(self.ListOfDevices[NwkId]["Param"]["DanfossSetPointType"]): thermostat_Calibration(self, NwkId) thermostat_Setpoint_Danfoss(self, NwkId, setpoint) ReadAttributeRequest_0201(self, NwkId) return self.log.logging("Thermostats", "Debug", "thermostat_Setpoint - standard for %s with value %s" % (NwkId, setpoint), nwkid=NwkId) EPout = "01" for tmpEp in self.ListOfDevices[NwkId]["Ep"]: if "0201" in self.ListOfDevices[NwkId]["Ep"][tmpEp]: EPout = tmpEp # Heat setpoint by default cluster_id = "%04x" % 0x0201 Hattribute = "%04x" % 0x0012 if ( cluster_id in self.ListOfDevices[NwkId]["Ep"][EPout] and "001c" in self.ListOfDevices[NwkId]["Ep"][EPout][cluster_id] and self.ListOfDevices[NwkId]["Ep"][EPout][cluster_id]["001c"] == 0x03 ): # Cool Setpoint Hattribute = "%04x" % 0x0011 manuf_id = "0000" manuf_spec = "00" data_type = "29" # Int16 self.log.logging("Thermostats", "Debug", "setpoint: %s" % setpoint, nwkid=NwkId) setpoint = int((setpoint * 2) / 2) # Round to 0.5 degrees self.log.logging("Thermostats", "Debug", "setpoint: %s" % setpoint, nwkid=NwkId) Hdata = "%04x" % setpoint if self.ZiGateModel == 2 and int(self.FirmwareVersion, 16) < 0x0320: # Bug on ZiGate V2 - firmware 0x320 fix it Domoticz.Log("---Zigate Model: %s Version: %s" % (self.ZiGateModel, self.FirmwareVersion)) Hdata = Hdata[2:4] + Hdata[0:2] Domoticz.Log("Patch Hdata %s" % Hdata) EPout = "01" self.log.logging( "Thermostats", "Deug", "thermostat_Setpoint - for %s with value 0x%s / cluster: %s, attribute: %s type: %s" % (NwkId, Hdata, cluster_id, Hattribute, data_type), nwkid=NwkId, ) write_attribute(self, NwkId, "01", EPout, cluster_id, manuf_id, manuf_spec, Hattribute, data_type, Hdata) ReadAttributeRequest_0201(self, NwkId)
def danfoss_viewdirection(self, NwkId, viewdirection): # Command Manufactuer Specific # Set viewing direction # 0110 02 955e 01 01 0204 00 01 1246 01 4000 30 01 viewdir = 0 if viewdirection == 1: viewdir = 0 elif viewdirection == 2: viewdir = 1 else: return manuf_id = "1246" manuf_spec = "01" cluster_id = "%04x" % 0x0204 EPout = "01" for tmpEp in self.ListOfDevices[NwkId]["Ep"]: if "0201" in self.ListOfDevices[NwkId]["Ep"][tmpEp]: EPout = tmpEp Hattribute = "%04x" % 0x4000 data_type = "30" # enum8 self.log.logging("Danfoss", "Debug", "danfoss_viewdirection: %s" % viewdir, nwkid=NwkId) Hdata = "%02x" % viewdir self.log.logging( "Danfoss", "Debug", "danfoss_viewdirection for %s with value %s / cluster: %s, attribute: %s type: %s" % (NwkId, Hdata, cluster_id, Hattribute, data_type), nwkid=NwkId, ) write_attribute(self, NwkId, ZIGATE_EP, EPout, cluster_id, manuf_id, manuf_spec, Hattribute, data_type, Hdata, ackIsDisabled=False) read_attribute(self, NwkId, ZIGATE_EP, EPout, cluster_id, "00", manuf_spec, manuf_id, 1, Hattribute, ackIsDisabled=False)
def legrand_fc01(self, nwkid, command, OnOff): # EnableLedInDark -> enable to detect the device in dark # EnableDimmer -> enable/disable dimmer # EnableLedIfOn -> enable Led with device On self.log.logging("Legrand", "Debug", "legrand_fc01 Nwkid: %s Cmd: %s OnOff: %s " % (nwkid, command, OnOff), nwkid) LEGRAND_REFRESH_TIME = (3 * 3600) + 15 LEGRAND_COMMAND_NAME = ("LegrandFilPilote", "EnableLedInDark", "EnableDimmer", "EnableLedIfOn", "EnableLedShutter") if nwkid not in self.ListOfDevices: return if command not in LEGRAND_COMMAND_NAME: Domoticz.Error("Unknown Legrand command %s" % command) return if "Model" not in self.ListOfDevices[nwkid]: return if self.ListOfDevices[nwkid]["Model"] in ( {} , "" ): return if self.ListOfDevices[nwkid]["Model"] not in LEGRAND_CLUSTER_FC01: self.log.logging( "Legrand", "Error", "%s is not an Legrand known model: %s" % (nwkid, self.ListOfDevices[nwkid]["Model"]), nwkid, ) return if "Legrand" not in self.ListOfDevices[nwkid]: self.ListOfDevices[nwkid]["Legrand"] = {} for cmd in LEGRAND_COMMAND_NAME: if cmd not in self.ListOfDevices[nwkid]["Legrand"]: self.ListOfDevices[nwkid]["Legrand"][cmd] = 0xFF if command == "EnableLedInDark" and command in LEGRAND_CLUSTER_FC01[self.ListOfDevices[nwkid]["Model"]]: if ( self.FirmwareVersion and self.FirmwareVersion.lower() <= "031c" and time() < self.ListOfDevices[nwkid]["Legrand"]["EnableLedInDark"] + LEGRAND_REFRESH_TIME ): return if self.FirmwareVersion and self.FirmwareVersion.lower() <= "031c": self.ListOfDevices[nwkid]["Legrand"]["EnableLedInDark"] = int(time()) data_type = "10" # Bool Hdata = "%02x" % OnOff self.log.logging( "Legrand", "Debug", "--------> %s Nwkid: %s data_type: %s Hdata: %s " % (command, nwkid, data_type, Hdata), nwkid, ) elif command == "EnableLedShutter" and command in LEGRAND_CLUSTER_FC01[self.ListOfDevices[nwkid]["Model"]]: if ( self.FirmwareVersion and self.FirmwareVersion.lower() <= "031c" and time() < self.ListOfDevices[nwkid]["Legrand"]["EnableLedShutter"] + LEGRAND_REFRESH_TIME ): return if self.FirmwareVersion and self.FirmwareVersion.lower() <= "031c": self.ListOfDevices[nwkid]["Legrand"]["EnableLedShutter"] = int(time()) data_type = "10" # Bool Hdata = "%02x" % OnOff self.log.logging( "Legrand", "Debug", "--------> %s Nwkid: %s data_type: %s Hdata: %s " % (command, nwkid, data_type, Hdata), nwkid, ) elif command == "EnableDimmer" and command in LEGRAND_CLUSTER_FC01[self.ListOfDevices[nwkid]["Model"]]: if ( self.FirmwareVersion and self.FirmwareVersion.lower() <= "031c" and time() < self.ListOfDevices[nwkid]["Legrand"]["EnableDimmer"] + LEGRAND_REFRESH_TIME ): return if self.FirmwareVersion and self.FirmwareVersion.lower() <= "031c": self.ListOfDevices[nwkid]["Legrand"]["EnableDimmer"] = int(time()) data_type = "09" # 16-bit Data if OnOff == 1: Hdata = "0101" # Enable Dimmer elif OnOff == 0: Hdata = "0100" # Disable Dimmer else: Hdata = "0000" self.log.logging( "Legrand", "Debug", "--------> %s Nwkid: %s data_type: %s Hdata: %s " % (command, nwkid, data_type, Hdata), nwkid, ) elif command == "EnableLedIfOn" and command in LEGRAND_CLUSTER_FC01[self.ListOfDevices[nwkid]["Model"]]: if ( self.FirmwareVersion and self.FirmwareVersion.lower() <= "031c" and time() < self.ListOfDevices[nwkid]["Legrand"]["EnableLedIfOn"] + LEGRAND_REFRESH_TIME ): return if self.FirmwareVersion and self.FirmwareVersion.lower() <= "031c": self.ListOfDevices[nwkid]["Legrand"]["EnableLedIfOn"] = int(time()) data_type = "10" # Bool Hdata = "%02x" % OnOff self.log.logging( "Legrand", "Debug", "--------> %s Nwkid: %s data_type: %s Hdata: %s " % (command, nwkid, data_type, Hdata), nwkid, ) else: return Hattribute = LEGRAND_CLUSTER_FC01[self.ListOfDevices[nwkid]["Model"]][command] manuf_id = "0000" manuf_spec = "00" cluster_id = "%04x" % 0xFC01 EPout = "01" for tmpEp in self.ListOfDevices[nwkid]["Ep"]: if "fc01" in self.ListOfDevices[nwkid]["Ep"][tmpEp]: EPout = tmpEp self.log.logging( "Legrand", "Debug", "legrand %s OnOff - for %s with value %s / cluster: %s, attribute: %s type: %s" % (command, nwkid, Hdata, cluster_id, Hattribute, data_type), nwkid=nwkid, ) write_attribute( self, nwkid, "01", EPout, cluster_id, manuf_id, manuf_spec, Hattribute, data_type, Hdata, ackIsDisabled=is_ack_tobe_disabled(self, nwkid), ) ReadAttributeRequest_fc01(self, nwkid)
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), )
def thermostat_Calibration(self, NwkId, calibration=None): # Calibration is an int8 representing a temperature offset (in the range -2.5°C to 2.5°C) # from 0xE7 ( -2.5 ) to 0x19 ( +2.5 ) # that can be added to or subtracted from the displayed temperature if ( "Param" in self.ListOfDevices[NwkId] and "Calibration" in self.ListOfDevices[NwkId]["Param"] and isinstance(self.ListOfDevices[NwkId]["Param"]["Calibration"], (float, int)) ): calibration = int(10 * self.ListOfDevices[NwkId]["Param"]["Calibration"]) if calibration is None: calibration = 0 if calibration < -25 or calibration > 25: self.log.logging( "Thermostats", "Error", "thermostat_Calibration - Wrong Calibration offset on %s off %s" % (NwkId, calibration), ) calibration = 0 if calibration < 0: # in two’s complement form calibration = int(hex(-calibration - pow(2, 32))[9:], 16) self.log.logging( "Thermostats", "Debug", "thermostat_Calibration - 2 complement form of Calibration offset on %s off %s" % (NwkId, calibration), ) if "Thermostat" not in self.ListOfDevices[NwkId]: self.ListOfDevices[NwkId]["Thermostat"] = {} if ( "Calibration" in self.ListOfDevices[NwkId]["Thermostat"] and calibration == 10 * self.ListOfDevices[NwkId]["Thermostat"]["Calibration"] ): return self.log.logging("Thermostats", "Log", "thermostat_Calibration - Set Thermostat offset on %s off %s" % (NwkId, calibration)) self.ListOfDevices[NwkId]["Thermostat"]["Calibration"] = calibration manuf_id = "0000" manuf_spec = "00" cluster_id = "%04x" % 0x0201 attribute = "%04x" % 0x0010 data_type = "28" # Int8 data = "%02x" % calibration EPout = "01" for tmpEp in self.ListOfDevices[NwkId]["Ep"]: if "0201" in self.ListOfDevices[NwkId]["Ep"][tmpEp]: EPout = tmpEp write_attribute(self, NwkId, "01", EPout, cluster_id, manuf_id, manuf_spec, attribute, data_type, data) self.log.logging( "Thermostats", "Debug", "thermostat_Calibration - for %s with value %s / cluster: %s, attribute: %s type: %s" % (NwkId, data, cluster_id, attribute, data_type), nwkid=NwkId, )