From 06c689b476dd3fce69d6e5ac1dd6f98bf025fb4b Mon Sep 17 00:00:00 2001 From: Smanar Date: Fri, 17 Feb 2023 19:17:53 +0100 Subject: [PATCH 01/16] Update plugin.py --- plugin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugin.py b/plugin.py index e1ef21a..51ac26a 100644 --- a/plugin.py +++ b/plugin.py @@ -1033,6 +1033,10 @@ def WebSocketConnexion(self,_Data): elif 'attr' in _Data: attr = _Data['attr'] + #MAJ capabilities, not used yet + elif 'capabilities' in _Data: + capabilities = _Data['capabilities'] + else: Domoticz.Error("Unknow MAJ: " + str(_Data) ) From ed74d8811e32d5b9000721e83e9609de17ca67c7 Mon Sep 17 00:00:00 2001 From: Smanar Date: Fri, 17 Feb 2023 19:21:32 +0100 Subject: [PATCH 02/16] Update plugin.py --- plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.py b/plugin.py index 51ac26a..18b0d5e 100644 --- a/plugin.py +++ b/plugin.py @@ -3,7 +3,7 @@ # Author: Smanar # """ - +

deCONZ Bridge


From 558ffe9ef223f97aacdf3f0b914b7081aff72199 Mon Sep 17 00:00:00 2001 From: BabaIsYou <85300265+BabaIsYou@users.noreply.github.com> Date: Thu, 23 Feb 2023 10:23:45 -0500 Subject: [PATCH 03/16] Add custom icon for Battery level widget Did not test it as Python and me are not close friends then have to be reviewed before ;-) --- plugin.py | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/plugin.py b/plugin.py index 18b0d5e..f1edb44 100644 --- a/plugin.py +++ b/plugin.py @@ -78,6 +78,13 @@ FullSpecialDeviceList = ["orientation", "heatsetpoint", "mode", "preset", "lock", "current", "voltage"] +#Custom icon files for battery level +#https://github.com/999LV/BatteryLevel +icons = {"batterylevelfull": "batterylevelfull icons.zip", + "batterylevelok": "batterylevelok icons.zip", + "batterylevellow": "batterylevellow icons.zip", + "batterylevelempty": "batterylevelempty icons.zip"} + #https://github.com/febalci/DomoticzEarthquake/blob/master/plugin.py #https://stackoverflow.com/questions/32436864/raw-post-request-with-json-in-body @@ -135,7 +142,18 @@ def onStart(self): global ENABLEBATTERYWIDGET ENABLEBATTERYWIDGET = True self.SpecialDeviceList = self.SpecialDeviceList + ["current", "voltage"] - + self.batterylevelfull = 75 # Default values for Battery Levels + self.batterylevelok = 50 + self.batterylevellow = 25 + # load custom battery images + for key, value in icons.items(): + if key not in Images: + Domoticz.Image(value).Create() + Domoticz.Debug("Added icon: " + key + " from file " + value) + Domoticz.Debug("Number of icons loaded = " + str(len(Images))) + for image in Images: + Domoticz.Log("Icon " + str(Images[image].ID) + " " + Images[image].Name) + #Read banned devices try: with open(Parameters["HomeFolder"]+"banned_devices.txt", 'r') as myPluginConfFile: @@ -1399,7 +1417,16 @@ def UpdateDeviceProc(kwarg,Unit): NewIEE = Devices[Unit].DeviceID.split("-")[0] Unit2 = GetDomoDeviceInfo(NewIEE + '_battery') if Unit2 and getattr(Devices[Unit2],'BatteryLevel') != kwarg['BatteryLevel']: - kwarg2 = {"nValue":0, "sValue":str(kwarg["BatteryLevel"])} + levelBatt=kwarg['BatteryLevel'] + if levelBatt >= self.batterylevelfull: + icon = "batterylevelfull" + elif levelBatt >= self.batterylevelok: + icon = "batterylevelok" + elif levelBatt >= self.batterylevellow: + icon = "batterylevellow" + else: + icon = "batterylevelempty" + kwarg2 = {"nValue":0, "sValue":str(kwarg["BatteryLevel"]),"Image":Images[icon].ID} Devices[Unit2].Update(**kwarg2) Domoticz.Debug("### Update special device ("+NewIEE+") : " + str(kwarg)) From 57a8cec8967691ca00236bfd79b5d48a23edae69 Mon Sep 17 00:00:00 2001 From: BabaIsYou <85300265+BabaIsYou@users.noreply.github.com> Date: Thu, 23 Feb 2023 10:29:18 -0500 Subject: [PATCH 04/16] Icon files for battery level --- batterylevelempty icons.zip | Bin 0 -> 5478 bytes batterylevelfull icons.zip | Bin 0 -> 7404 bytes batterylevellow icons.zip | Bin 0 -> 6356 bytes batterylevelok icons.zip | Bin 0 -> 6824 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 batterylevelempty icons.zip create mode 100644 batterylevelfull icons.zip create mode 100644 batterylevellow icons.zip create mode 100644 batterylevelok icons.zip diff --git a/batterylevelempty icons.zip b/batterylevelempty icons.zip new file mode 100644 index 0000000000000000000000000000000000000000..d22949f86bc23e19eaf62c0c000b9672bc0ed4be GIT binary patch literal 5478 zcmWIWW@Zs#00D)7#a_L0d?Qz|Fff3yC{QdZv7{ums4^$DEHx)Jx1gj_uOKhIGr-TC zmrIHZD9`KZ;SvO-4M3QK4M>JF{cHzPEa{HEjtmSN`?>!lvI6;>1s;*b3=Dh+L6~vJ z#O${~LCF%=h?3y^w370~qEv>0#LT=By}Z;C1rt33Jwr2>%=KS^2B~_wIEG|6znyi` zJ0?=(nCm8yMcjr*T3b638ugl@x|f(m&TwdT@c7r1v)M=NCX3T1qbZxW+8-qTC&tjlPG4-vqOQ}Yy?grll9G~`f`fzqEV|@<`|{=HLx-GZoK2fDb?U-p%h+^v zbvHz<&B)GfKL5P=_~V1OZb`jJjgN?U@cF`zi3*~j7s8)@_#m)*_wIt-cjxRmoA!8p z@9C$HR9^nNc~eq;Z=C*X7S(6;PHB0_+R{G1{8qV1kR(3T9yh26)tX=zK_h#XJ z{qhg_J)BJ{YJM-@x zICpk7$DMt>>;2~|eRv@lQ~v&u{$9ELuS+C^+?*b}H-&^avc2J#JCgHYd-V1X$A5oU zTJp#4AuyI=RyLNuck%dHdk7ee7kDz*nt=XEN%(Ygv$o-fbk9x>&HersAfW^Pu|JOY zKQxirm}hXH_&J}=qZfP2`S<<){;>LoK-|PP%TBVam-znlr0^eQyS=y9#~u9oi1p3+ z`G>!K)0I*3%lP9lp-U?)JiL;1S-q-+gam`>j+N3kuU5`U@ zm7})l*J~?oUcY}|-|5tQVZNZiqd$LIMjiF~y?1VuYS_(Nx1#b^U#d(^RXuh3bYN7} zspnU(UR|+zwR3Q=u+))NK94=tuUPRw*9~mrLxA3|43eNsz|DvjM zMWvDFZ?#*>t;c#rR!VS+i;LgsTq0+%HFBlOiihs0t|eW61M>6rr;Fu2S&_41znGMI z)RISE84Le2c5gI)q30Xm0W4J*JYD@<);T3K1>h{&q=Bk1iZ&CAc>lDt(E@I?fEz8~ zMhm#1UBF4@Ui$Od6fAkIwA&nwm| zsVKo{$ysBHxa8;Nmt-ba>87MQ`};*H6y%hqXXf#8;cg>}1FgU?$HZc^{2VPmN6XLA z@^fgEpNvc*47f-4fF&FdD1b>Ug&nA<3-HEm1gIAc0SZ9sHgL!gOL+AIHxy#<&fm!5GwFip03z6~>q`gmE3I+;3y2p^T8rZ}`b23T^JSo7~1v zkuF5B!yrp#waB)VqEK?HR8sAk+TGXhRonjEAM-u0@A;nRInVh#=Q)2o@AEugs*^Aj z1@O(6TIqNg=R21R0|37BYl8w=tk44qjL?IjjIdY+10T%{&!)PNrNlAf;B6_21JNCf zdVGh2&j2)`H<@67hTA&Z0zgxq#Co6zSQd+R*cAf+h%UZEAS zJP-;*2hy1=JTsJqHNxxR^-YNM#+Lv96QdAqJtOR%mF?Q;u?u~Dh|D77LU!U{Vg*_K zk#0y$EhHr}O^k%wpTI@m&q6DpWRSuzRNaN)$Z8QM$be7RaI^M>OE$&7AFambNEn{R z5lckBADXs) z)zve#wW3o~Qz7~>LyPLU#gLw;A^75od8~yWs{+V(C6SJEZXw>HDb+)RY;6CRj$55)71{KxUpr=DVc|tzjG3~sReXMm!Q%a&H0t$RV&zCv zNwc%FZ0~yexH!}8ZgrG;?|L^XmEF}vKq)9xUc06o)P#p`B^YhwsMQ{9W1sGZILJTTu8e#Niqmv0S zu&ps$9oCP-@BL_{TxOAerOB-OZV<9Mr)#13YUkWz?6C5Ys%0DwflI4@9JIT~gmL9O zB;ldePFL6OnWc-5BuSNqnh-gnhP?K>?SF=H~o!6b0tQNDKMCMpt)7YB?jdkm_ z;AiEReM0w&w78gFF)rw%_~qw+5VcH064KYvLgIeON!>(I9aqH?|5UgjMNdVQlag*2C219*}hE; zE-3_mNys`x%#YYSdp<58Ab`Cca&FZ->yjF(E+_xpcP1%)Pxfq~uJ z6@L;9s)s(c>;dnKFKxmJHRLp0RA-|%=ie?(^HGxzR1bugz-=ZYuxYUW$}q*Q%8oI5IT1KnOXgIi662v(PYUkG7tG6 z%f{0mwYqCn^&Z-FMq2i+tjwK_q76kk9?c$R`>c*`DBIvrP>tPNhRC_O@1pi$EYAPF#&cD=I zyh9J8AT$DbqLlUieTv1hbLdk!aglevZm!vFCMG7g8|7bO%#{&Iua{C8{qs>3dYEGA z=(kE8>LUk3=&iyaIRJ{i3$cL^kVgF~y)a;_&*^1k=I5Fs1-u0)z<=CP0_~VFHAGD+uH72LeE(2hH1Dlw)TBUh`cHbb4?UGX~F!XMMgN zv;3lh7_~2oMGrot6B26Y>f(!yX2gcmnNs3kU+2k#9egfhWF`Ql0FVMe3IHhpqyUiL z1|T6qsE--7f6lXk5CaYS@%$yv_%x$BeO-aS*ZIk?VCVqza9~|72J& b)PT}oj`Y*l65(ef0TJ+s273ro;+Osa=gN$% literal 0 HcmV?d00001 diff --git a/batterylevellow icons.zip b/batterylevellow icons.zip new file mode 100644 index 0000000000000000000000000000000000000000..9c1aa4bc7e8b5890514671fd96c13b42b814a34a GIT binary patch literal 6356 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 Date: Thu, 23 Feb 2023 12:41:44 -0500 Subject: [PATCH 05/16] Add OTH4000-ZB for power and consumption on the same endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add OTH4000-ZB for power and consumption on the same endpoint. It's a rebranding of Sinopé Thermsostat (TH1124ZB) --- plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.py b/plugin.py index 18b0d5e..2e8beb4 100644 --- a/plugin.py +++ b/plugin.py @@ -723,7 +723,7 @@ def InitDomoticzDB(self,key,_Data,Type_device): #Create the current device self.CreateIfnotExist(IEEE,'ZHADoorLock',Name) # power and consumption on the same endpoint - elif Model == 'ZHEMI101' or Model == 'TH1124ZB' or Model == '45856' or Model == 'E1C-NB7': + elif Model == 'ZHEMI101' or Model == 'TH1124ZB' or Model == 'OTH4000-ZB' or Model == '45856' or Model == 'E1C-NB7': self.Devices[IEEE]['option'] = 1 self.CreateIfnotExist(IEEE,Type,Name,1) else: From 67ef0745cb4e76603865280a36c1ec471ff0cb85 Mon Sep 17 00:00:00 2001 From: Smanar Date: Sat, 25 Feb 2023 16:57:41 +0100 Subject: [PATCH 06/16] little clean --- .../batterylevelempty_icons.zip | Bin .../batterylevelfull_icons.zip | Bin .../batterylevellow_icons.zip | Bin .../batterylevelok_icons.zip | Bin plugin.py | 29 ++++++++---------- 5 files changed, 13 insertions(+), 16 deletions(-) rename batterylevelempty icons.zip => icons/batterylevelempty_icons.zip (100%) rename batterylevelfull icons.zip => icons/batterylevelfull_icons.zip (100%) rename batterylevellow icons.zip => icons/batterylevellow_icons.zip (100%) rename batterylevelok icons.zip => icons/batterylevelok_icons.zip (100%) diff --git a/batterylevelempty icons.zip b/icons/batterylevelempty_icons.zip similarity index 100% rename from batterylevelempty icons.zip rename to icons/batterylevelempty_icons.zip diff --git a/batterylevelfull icons.zip b/icons/batterylevelfull_icons.zip similarity index 100% rename from batterylevelfull icons.zip rename to icons/batterylevelfull_icons.zip diff --git a/batterylevellow icons.zip b/icons/batterylevellow_icons.zip similarity index 100% rename from batterylevellow icons.zip rename to icons/batterylevellow_icons.zip diff --git a/batterylevelok icons.zip b/icons/batterylevelok_icons.zip similarity index 100% rename from batterylevelok icons.zip rename to icons/batterylevelok_icons.zip diff --git a/plugin.py b/plugin.py index 2b28dea..e94f2b6 100644 --- a/plugin.py +++ b/plugin.py @@ -78,13 +78,6 @@ FullSpecialDeviceList = ["orientation", "heatsetpoint", "mode", "preset", "lock", "current", "voltage"] -#Custom icon files for battery level -#https://github.com/999LV/BatteryLevel -icons = {"batterylevelfull": "batterylevelfull icons.zip", - "batterylevelok": "batterylevelok icons.zip", - "batterylevellow": "batterylevellow icons.zip", - "batterylevelempty": "batterylevelempty icons.zip"} - #https://github.com/febalci/DomoticzEarthquake/blob/master/plugin.py #https://stackoverflow.com/questions/32436864/raw-post-request-with-json-in-body @@ -141,16 +134,20 @@ def onStart(self): Domoticz.Status("Enabling special setting ENABLEBATTERYWIDGET") global ENABLEBATTERYWIDGET ENABLEBATTERYWIDGET = True - self.SpecialDeviceList = self.SpecialDeviceList + ["current", "voltage"] - self.batterylevelfull = 75 # Default values for Battery Levels - self.batterylevelok = 50 - self.batterylevellow = 25 + + #Custom icon files for battery level + #https://github.com/999LV/BatteryLevel + icons = {"batterylevelfull": "icons/batterylevelfull_icons.zip", + "batterylevelok": "icons/batterylevelok_icons.zip", + "batterylevellow": "icons/batterylevellow_icons.zip", + "batterylevelempty": "icons/batterylevelempty_icons.zip"} + # load custom battery images for key, value in icons.items(): if key not in Images: Domoticz.Image(value).Create() - Domoticz.Debug("Added icon: " + key + " from file " + value) - Domoticz.Debug("Number of icons loaded = " + str(len(Images))) + Domoticz.Status("Added icon: " + key + " from file " + value) + Domoticz.Status("Number of icons loaded = " + str(len(Images))) for image in Images: Domoticz.Log("Icon " + str(Images[image].ID) + " " + Images[image].Name) @@ -1418,11 +1415,11 @@ def UpdateDeviceProc(kwarg,Unit): Unit2 = GetDomoDeviceInfo(NewIEE + '_battery') if Unit2 and getattr(Devices[Unit2],'BatteryLevel') != kwarg['BatteryLevel']: levelBatt=kwarg['BatteryLevel'] - if levelBatt >= self.batterylevelfull: + if levelBatt >= 75: icon = "batterylevelfull" - elif levelBatt >= self.batterylevelok: + elif levelBatt >= 50: icon = "batterylevelok" - elif levelBatt >= self.batterylevellow: + elif levelBatt >= 25: icon = "batterylevellow" else: icon = "batterylevelempty" From 4c7d35b8c7a48ed8c8e9d54c70d985f9f3554c79 Mon Sep 17 00:00:00 2001 From: Smanar Date: Sat, 25 Feb 2023 17:00:47 +0100 Subject: [PATCH 07/16] Update plugin.py --- plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.py b/plugin.py index e94f2b6..e2f48d2 100644 --- a/plugin.py +++ b/plugin.py @@ -149,7 +149,7 @@ def onStart(self): Domoticz.Status("Added icon: " + key + " from file " + value) Domoticz.Status("Number of icons loaded = " + str(len(Images))) for image in Images: - Domoticz.Log("Icon " + str(Images[image].ID) + " " + Images[image].Name) + Domoticz.Log("Icon " + str(Images[image].ID) + " " + Images[image].Name) #Read banned devices try: From 666188f0862a156d129e54401f4c86464eec1b39 Mon Sep 17 00:00:00 2001 From: Smanar Date: Sat, 25 Feb 2023 17:08:05 +0100 Subject: [PATCH 08/16] Update plugin.py --- plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin.py b/plugin.py index e2f48d2..1611fe2 100644 --- a/plugin.py +++ b/plugin.py @@ -147,8 +147,8 @@ def onStart(self): if key not in Images: Domoticz.Image(value).Create() Domoticz.Status("Added icon: " + key + " from file " + value) - Domoticz.Status("Number of icons loaded = " + str(len(Images))) - for image in Images: + Domoticz.Status("Number of icons loaded = " + str(len(Images))) + for image in Images: Domoticz.Log("Icon " + str(Images[image].ID) + " " + Images[image].Name) #Read banned devices From cd026d4245b3c26ea6c33fef4936e472323675c5 Mon Sep 17 00:00:00 2001 From: Smanar Date: Fri, 17 Mar 2023 18:05:28 +0100 Subject: [PATCH 09/16] Update widget.py --- widget.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/widget.py b/widget.py index 35631b8..f4e3fa9 100644 --- a/widget.py +++ b/widget.py @@ -255,6 +255,10 @@ def Createdatawidget(IEEE, _Name, _Type, opt): kwarg['TypeName'] = 'Custom' kwarg['Options'] = {"Custom": ("1;degree")} + elif _Type == 'ZHARelativeRotary': + kwarg['TypeName'] = 'Custom' + kwarg['Options'] = {"Custom": ("1;degree")} + elif _Type == 'Thermostat_Mode': kwarg['Type'] = 244 kwarg['Subtype'] = 62 From cf87413d902ce9c512e3a5989ec422c790a8ceb4 Mon Sep 17 00:00:00 2001 From: Smanar Date: Fri, 17 Mar 2023 18:06:02 +0100 Subject: [PATCH 10/16] Update fonctions.py --- fonctions.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fonctions.py b/fonctions.py index d00cabd..51b7fb9 100644 --- a/fonctions.py +++ b/fonctions.py @@ -436,6 +436,8 @@ def ProcessAllState(data,model,option): kwarg.update(ReturnUpdateValue( 'action' , data['action'], model ) ) if 'speed' in data: kwarg.update(ReturnUpdateValue( 'speed' , data['speed'], model ) ) + if 'expectedrotation' in data: + kwarg.update(ReturnUpdateValue( 'expectedrotation' , data['expectedrotation'], model ) ) #if 'lastupdated' in data: # kwarg.update(ReturnUpdateValue('lastupdated', data['lastupdated'])) @@ -712,6 +714,14 @@ def ReturnUpdateValue(command, val ,option = None): kwarg['nValue'] = 0 kwarg['sValue'] = str(val) + if command == 'expectedrotation': + kwarg['nValue'] = int(val) + + if kwarg['nValue'] == 0: + kwarg['sValue'] = 'Off' + else: + kwarg['sValue'] = str( kwarg['nValue'] ) + #switch if command == 'buttonevent': From 74fbaf43e4461c4a236be05ec91870d620b31ca3 Mon Sep 17 00:00:00 2001 From: Smanar Date: Sun, 26 Mar 2023 19:14:42 +0200 Subject: [PATCH 11/16] Update fonctions.py --- fonctions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fonctions.py b/fonctions.py index 51b7fb9..71901d4 100644 --- a/fonctions.py +++ b/fonctions.py @@ -374,6 +374,8 @@ def ProcessAllState(data,model,option): kwarg.update(ReturnUpdateValue('alert', data['alert'], model)) if 'status' in data: kwarg.update(ReturnUpdateValue('status', data['status'])) + if 'pm2_5' in data: + kwarg.update(ReturnUpdateValue('airqualityppb', data['pm2_5'])) if 'on' in data: kwarg.update(ReturnUpdateValue('on', data['on'], model) ) if 'x' in data: @@ -422,8 +424,6 @@ def ProcessAllState(data,model,option): kwarg.update(ReturnUpdateValue('lockstate', data['lockstate'])) if 'airqualityppb' in data: kwarg.update(ReturnUpdateValue('airqualityppb', data['airqualityppb'])) - if 'pm2_5' in data: - kwarg.update(ReturnUpdateValue('airqualityppb', data['pm2_5'])) if 'bri' in data: kwarg.update(ReturnUpdateValue('bri', data['bri'], model) ) if 'lift' in data: From f7fc71b8caa8336cefdd88ee43ac5baa982a448c Mon Sep 17 00:00:00 2001 From: Sumd84 <131442913+Sumd84@users.noreply.github.com> Date: Fri, 21 Apr 2023 17:00:41 +0200 Subject: [PATCH 12/16] Add compatibility with Xiaomi Aqara Cube T1 Pro Xiaomi Aqara Cube T1 Pro has a model id : lumi.remote.cagl02 Define new type: XCubeProT1_R and XCubeProT1_C New conversion functions: - ButtonconvertionXCUBEPROT1: Uses 'gesture' and 'buttonevent' - ButtonconvertionXCUBEPROT1_R: identical to ButtonconvertionXCUBE_R --- plugin.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/plugin.py b/plugin.py index 1611fe2..e076b6f 100644 --- a/plugin.py +++ b/plugin.py @@ -64,6 +64,7 @@ from fonctions import rgb_to_xy, rgb_to_hsv, xy_to_rgb from fonctions import Count_Type, ProcessAllState, ProcessAllConfig, First_Json, JSON_Repair, get_JSON_payload from fonctions import ButtonconvertionXCUBE, ButtonconvertionXCUBE_R, ButtonconvertionTradfriRemote, ButtonconvertionTradfriSwitch +from fonctions import ButtonconvertionXCUBEPROT1, ButtonconvertionXCUBEPROT1_R from fonctions import ButtonConvertion, VibrationSensorConvertion from fonctions import installFE, uninstallFE from widget import Createdatawidget @@ -641,7 +642,17 @@ def InitDomoticzDB(self,key,_Data,Type_device): #ignore ZHASwitch if vibration sensor if 'sensitivity' in ConfigList: return - if 'lumi.sensor_cube' in Model: + #Used by Xiaomi Cube Pro T1 + if 'lumi.remote.cagl02' in Model: + if IEEE.endswith('-03-000c'): + Type = 'XCubeProT1_R' + elif IEEE.endswith('-02-0012'): + Type = 'XCubeProT1_C' + else: + # Useless device + self.Devices[IEEE]['state'] = 'banned' + return + elif 'lumi.sensor_cube' in Model: if IEEE.endswith('-03-000c'): Type = 'XCube_R' elif IEEE.endswith('-02-0012'): @@ -989,6 +1000,10 @@ def WebSocketConnexion(self,_Data): kwarg.update(ButtonconvertionXCUBE(state['buttonevent']) ) elif model == 'XCube_R': kwarg.update(ButtonconvertionXCUBE_R(state['buttonevent']) ) + elif model == 'XCubeProT1_C': + kwarg.update(ButtonconvertionXCUBEPROT1(state['buttonevent'], state['gesture']) ) + elif model == 'XCubeProT1_R': + kwarg.update(ButtonconvertionXCUBEPROT1_R(state['buttonevent']) ) elif model == 'Tradfri_remote': kwarg.update(ButtonconvertionTradfriRemote(state['buttonevent']) ) elif model == 'Tradfri_on/off_switch': From 1ae38a760853cf91cd3194064fc1a409aab6fb39 Mon Sep 17 00:00:00 2001 From: Sumd84 <131442913+Sumd84@users.noreply.github.com> Date: Fri, 21 Apr 2023 17:14:30 +0200 Subject: [PATCH 13/16] Conversion functions for Xiaomi Aqara Cube T1 Pro Add two new conversion functions for the Xiaomi Aqara Cube T1 pro (https://github.com/Smanar/Domoticz-deCONZ/commit/f7fc71b8caa8336cefdd88ee43ac5baa982a448c) - ButtonconvertionXCUBEPROT1_R: Same as Xiaomi cube - ButtonconvertionXCUBEPROT1: uses 'gesture' and 'buttonevent' to return more complex values containing the last action and cube face being up --- fonctions.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/fonctions.py b/fonctions.py index 71901d4..c509dc5 100644 --- a/fonctions.py +++ b/fonctions.py @@ -756,6 +756,18 @@ def ButtonconvertionXCUBE_R(val): return kwarg +def ButtonconvertionXCUBEPROT1_R(val): + kwarg = {} + + kwarg['nValue'] = int(val) + + if kwarg['nValue'] == 0: + kwarg['sValue'] = 'Off' + else: + kwarg['sValue'] = str( kwarg['nValue'] ) + + return kwarg + def ButtonconvertionXCUBE(val): kwarg = {} val = str(val) @@ -785,6 +797,38 @@ def ButtonconvertionXCUBE(val): return kwarg +def ButtonconvertionXCUBEPROT1(val, gesture): + kwarg = {} + gest = int(gesture) + face = str(val) + v = 0 + + if gest == 0: # wake + v = 70 + elif gest == 1:# shake + v = 10 + elif gest == 2:# Free Fall + v = 20 + elif gest == 3:# 90 flip + v = 30 + int(face[0]) #add face up number + elif gest == 4:# 180 flip + v = 40 + int(face[0]) #add face up number + elif gest == 5:# push + v = 50 + int(face[0]) #add face up number + elif gest == 6:# double tap + v = 60 + int(face[0]) #add face up number + else:# Unknown + v = 80 + + if v == 0: + kwarg['sValue'] = 'Off' + else: + kwarg['sValue'] = str( v ) + + kwarg['nValue'] = v + + return kwarg + # <=4002 >=5002 +=2002 -=3002 4001/5001/2001/3001 def ButtonconvertionTradfriRemote(val): kwarg = {} From 70f3eb326d4fbb2e263d2e21bb8b1ce00214a1bc Mon Sep 17 00:00:00 2001 From: Sumd84 <131442913+Sumd84@users.noreply.github.com> Date: Fri, 21 Apr 2023 20:50:27 +0200 Subject: [PATCH 14/16] Xiaomi Cube Pro T1 position value In ButtonconvertionXCUBEPROT1, assign the same values as ButtonconvertionXCUBE for each action for consistency purposes. --- fonctions.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/fonctions.py b/fonctions.py index c509dc5..324be8b 100644 --- a/fonctions.py +++ b/fonctions.py @@ -803,22 +803,22 @@ def ButtonconvertionXCUBEPROT1(val, gesture): face = str(val) v = 0 - if gest == 0: # wake - v = 70 - elif gest == 1:# shake - v = 10 - elif gest == 2:# Free Fall + if gest == 0: # wake v = 20 - elif gest == 3:# 90 flip - v = 30 + int(face[0]) #add face up number - elif gest == 4:# 180 flip + elif gest == 1: # shake + v = 10 + elif gest == 2: # Drop + v = 30 + elif gest == 3: # 90 flip v = 40 + int(face[0]) #add face up number - elif gest == 5:# push + elif gest == 4: # 180 flip v = 50 + int(face[0]) #add face up number - elif gest == 6:# double tap + elif gest == 5: # push v = 60 + int(face[0]) #add face up number - else:# Unknown - v = 80 + elif gest == 6: # double tap + v = 70 + int(face[0]) #add face up number + else: # Unknown + v = 0 if v == 0: kwarg['sValue'] = 'Off' From 6854e6a6d8f2dc6f11777e8048ba67f741845aa4 Mon Sep 17 00:00:00 2001 From: Sumd84 <131442913+Sumd84@users.noreply.github.com> Date: Sat, 22 Apr 2023 21:03:10 +0200 Subject: [PATCH 15/16] Add xompatibility with Aqara Cube T1 / T1 Pro Detect model id: - lumi.remote.cagl01: Xiaomi Aqara Cube T1 - lumi.remote.cagl02: Xiaomi Aqara Cube T1 Pro Assign new type: XCubeT1_C / XCubeT1_R New conversion functions: - ButtonconvertionXCUBET1: uses 'buttonevent' and 'gesture' - ButtonconvertionXCUBET1_R --- plugin.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/plugin.py b/plugin.py index e076b6f..07809b0 100644 --- a/plugin.py +++ b/plugin.py @@ -64,7 +64,7 @@ from fonctions import rgb_to_xy, rgb_to_hsv, xy_to_rgb from fonctions import Count_Type, ProcessAllState, ProcessAllConfig, First_Json, JSON_Repair, get_JSON_payload from fonctions import ButtonconvertionXCUBE, ButtonconvertionXCUBE_R, ButtonconvertionTradfriRemote, ButtonconvertionTradfriSwitch -from fonctions import ButtonconvertionXCUBEPROT1, ButtonconvertionXCUBEPROT1_R +from fonctions import ButtonconvertionXCUBET1, ButtonconvertionXCUBET1_R from fonctions import ButtonConvertion, VibrationSensorConvertion from fonctions import installFE, uninstallFE from widget import Createdatawidget @@ -642,12 +642,22 @@ def InitDomoticzDB(self,key,_Data,Type_device): #ignore ZHASwitch if vibration sensor if 'sensitivity' in ConfigList: return - #Used by Xiaomi Cube Pro T1 - if 'lumi.remote.cagl02' in Model: + #Used by Xiaomi Cube T1 + if 'lumi.remote.cagl01' in Model: if IEEE.endswith('-03-000c'): - Type = 'XCubeProT1_R' + Type = 'XCubeT1_R' elif IEEE.endswith('-02-0012'): - Type = 'XCubeProT1_C' + Type = 'XCubeT1_C' + else: + # Useless device + self.Devices[IEEE]['state'] = 'banned' + return + #Used by Xiaomi Cube T1 Pro + elif 'lumi.remote.cagl02' in Model: + if IEEE.endswith('-03-000c'): + Type = 'XCubeT1_R' + elif IEEE.endswith('-02-0012'): + Type = 'XCubeT1_C' else: # Useless device self.Devices[IEEE]['state'] = 'banned' @@ -1000,10 +1010,10 @@ def WebSocketConnexion(self,_Data): kwarg.update(ButtonconvertionXCUBE(state['buttonevent']) ) elif model == 'XCube_R': kwarg.update(ButtonconvertionXCUBE_R(state['buttonevent']) ) - elif model == 'XCubeProT1_C': - kwarg.update(ButtonconvertionXCUBEPROT1(state['buttonevent'], state['gesture']) ) - elif model == 'XCubeProT1_R': - kwarg.update(ButtonconvertionXCUBEPROT1_R(state['buttonevent']) ) + elif model == 'XCubeT1_C': + kwarg.update(ButtonconvertionXCUBET1(state['buttonevent'], state['gesture']) ) + elif model == 'XCubeT1_R': + kwarg.update(ButtonconvertionXCUBET1_R(state['buttonevent']) ) elif model == 'Tradfri_remote': kwarg.update(ButtonconvertionTradfriRemote(state['buttonevent']) ) elif model == 'Tradfri_on/off_switch': From 88d348f97ab20e99c2869c4dd3aebc0720eb4e5a Mon Sep 17 00:00:00 2001 From: Sumd84 <131442913+Sumd84@users.noreply.github.com> Date: Sat, 22 Apr 2023 21:15:29 +0200 Subject: [PATCH 16/16] Mutualize functions for Aqara Cube T1/T1 Pro Aqara Cube T1/T1 Pro uses ButtonconvertionXCUBET1_R and ButtonconvertionXCUBET1. Remove the face up digit for flips and tap gestures. --- fonctions.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fonctions.py b/fonctions.py index 324be8b..6551efc 100644 --- a/fonctions.py +++ b/fonctions.py @@ -756,7 +756,7 @@ def ButtonconvertionXCUBE_R(val): return kwarg -def ButtonconvertionXCUBEPROT1_R(val): +def ButtonconvertionXCUBET1_R(val): kwarg = {} kwarg['nValue'] = int(val) @@ -797,7 +797,7 @@ def ButtonconvertionXCUBE(val): return kwarg -def ButtonconvertionXCUBEPROT1(val, gesture): +def ButtonconvertionXCUBET1(val, gesture): kwarg = {} gest = int(gesture) face = str(val) @@ -810,13 +810,13 @@ def ButtonconvertionXCUBEPROT1(val, gesture): elif gest == 2: # Drop v = 30 elif gest == 3: # 90 flip - v = 40 + int(face[0]) #add face up number + v = 40 elif gest == 4: # 180 flip - v = 50 + int(face[0]) #add face up number + v = 50 elif gest == 5: # push - v = 60 + int(face[0]) #add face up number + v = 60 elif gest == 6: # double tap - v = 70 + int(face[0]) #add face up number + v = 70 else: # Unknown v = 0