Closed uzlonewolf closed 1 year ago
thank you for the patch! it looks like work but sometimes i see this error on console. idk if it is about this or not.
DEBUG:Network connection error in _send_receive() - retry 1/5
Traceback (most recent call last):
File "C:\Users\ANAR\AppData\Local\Programs\Python\Python310\lib\site-packages\tinytuya\core.py", line 795, in _send_receive
rmsg = self._receive()
File "C:\Users\ANAR\AppData\Local\Programs\Python\Python310\lib\site-packages\tinytuya\core.py", line 712, in _receive
data = self._recv_all(header_len+ret_end_len)
File "C:\Users\ANAR\AppData\Local\Programs\Python\Python310\lib\site-packages\tinytuya\core.py", line 690, in _recv_all
newdata = self.socket.recv(length)
ConnectionResetError: [WinError 10054] an existing connection was forcibly closed by the remote host
@anar4732 Yeah, sometimes the devices just close the connection for no apparent reason. I have no idea why they do that, but tinytuya sees it and retries automatically so it's not a big deal.
@uzlonewolf Sorry for the ping, but how hard would it be to add support for RF devices? Based on https://github.com/tuya-cloudcutter/tuya-cloudcutter.github.io/blob/3736ae997a30db7e8c379dd5472521922f6cd43f/devices/tuya-generic-ir-rf-universal-remote-controller-v2.0.8.json they must use the same DPS for RF as well.
@Xmister I'm not sure if you're asking about cloud or local. Local already works for both Zigbee and Bluetooth sub-devices so I would expect it to work for RF devices as well. Does https://github.com/jasonacox/tinytuya/blob/master/examples/zigbee_gateway.py do anything?
@uzlonewolf I'm talking about local, but I was more interested in learning/sending raw 433MHz codes, like how this IR module does, instead of interacting with an already set up gw-child pair. (My ir-rf gateway is cut from the cloud, so I can't set up subdevices anymore)
Ah, I see what you mean now. I was thinking they were RF devices similar to how the Zigbee ones work.
It shouldn't be too hard to add, though I'm going to need a packet capture and/or a firmware dump to figure out the protocol. I know yours is cut from the cloud, but does it have any RF devices stored?
Sadly, no. I was trying libretuya-esphome on it, but didn't realise it doesn't yet support spi on these devices, so communicating with the SH4 radio module is not possible. I was able to get a factory app firmware without the device specific bits, so I can use tinytuya now for local control. Would this firmware help in any way? I've ordered a similar device for the same reason, so that I might be able to sniff the protocol somehow. But it will be weeks until it arrives.
As long as it has the JSON parsing bits in it it should work. I'm currently digging through my universal hub firmware dump to see if it knows about the RF commands, and I have a IR+RF gateway coming from Amazon in a couple days https://www.amazon.com/gp/product/B0BY2C68BJ/
Thanks. Here is the one I'm using right now: https://github.com/tuya-cloudcutter/tuya-cloudcutter.github.io/files/11353905/Tuya-Generic_IR---RF-Universal-Remote-Controller-v2.0.8.bin.zip You can find a few different in the commit comments over https://github.com/tuya-cloudcutter/tuya-cloudcutter.github.io/commit/3736ae997a30db7e8c379dd5472521922f6cd43f
Making some progress. Looks like if you set the key rf_type
(any value, it's not actually looked at) it puts the parser into RF mode. The command is then in the control
key with the options rf_study
, rfstudy_exit
, rfstudy_send
, send_pair
, and send_cmd
. Still looking into what data those commands expect.
Since, this is a 2 band RF controller, I guess rf_study_feq
would set the actual frequency to listen/send over. (315 vs 433). I've also seen rf_shortstudy
when running strings
over the binary.
How do you set rf_type
is that over the 201
DP as well?
If you wish I can open a port for you to connect to my device with tinytuya until you have your own.
201 takes a JSON string so you just send {"rf_type": ..., "control": "...", ...}
Unfortunately I need to see the traffic between the SmartLife app and the device, so just the device won't help. Mine is showing delivery tomorrow so it won't be too long.
Ok, my device came in and I was able to get some packet captures.
First, I added 2 random curtains to see what "known device" data looks like:
to 'eb####tb' v3.3 cmd: 13 (0D) len(543) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"mode\\":8,\\"key1\\":{\\"code\\":\\"ffffc01fa4934924924924924d34924da4936db0\\",\\"delay\\":0,\\"intervals\\":0,\\"times\\":5},\\"feq\\":0,\\"rate\\":0,\\"cfg\\":{\\"b\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,96,255,0,0,31,16],\\"c\\":[0,102,236,28,240,128,20,8,145,2,2,208],\\"s\\":[174,224,53,0,0,244,16,226,66,32,0,129],\\"d\\":[63,30,128,204,0,0,0,0,0,0,0,41,192,218,33,75,5,0,80,45,0,1,5,5],\\"t\\":[81,154,12,0,12,176,0,31,4,63,127],\\"f\\":[66,113,206,28,66,91,28,28]},\\"control\\":\\"send_pair\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(575) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"mode\\":2,\\"key1\\":{\\"code\\":\\"924924fffcd349369249249249249269249a4924924924924d369a6d36c000\\",\\"delay\\":0,\\"intervals\\":0,\\"times\\":6},\\"feq\\":0,\\"rate\\":0,\\"cfg\\":{\\"b\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,96,255,2,0,31,16],\\"c\\":[0,102,236,28,240,128,20,8,145,2,2,208],\\"s\\":[174,224,53,0,0,244,16,226,66,32,0,129],\\"d\\":[71,34,144,204,0,0,0,0,0,0,0,41,192,223,29,91,7,0,80,45,0,1,6,6],\\"t\\":[81,38,3,0,10,176,0,31,4,63,127],\\"f\\":[66,166,231,28,66,144,53,28]},\\"control\\":\\"send_pair\\"}"}}'
After that I mashed the buttons a bit:
to 'eb####tb' v3.3 cmd: 13 (0D) len(543) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"mode\\":8,\\"key1\\":{\\"code\\":\\"ffffc01fa4934924924924934934924da4926930\\",\\"delay\\":0,\\"intervals\\":0,\\"times\\":5},\\"feq\\":0,\\"rate\\":0,\\"cfg\\":{\\"b\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,96,255,0,0,31,16],\\"c\\":[0,102,236,28,240,128,20,8,145,2,2,208],\\"s\\":[174,224,53,0,0,244,16,226,66,32,0,129],\\"d\\":[63,30,128,204,0,0,0,0,0,0,0,41,192,218,33,75,5,0,80,45,0,1,5,5],\\"t\\":[81,154,12,0,12,176,0,31,4,63,127],\\"f\\":[66,113,206,28,66,91,28,28]},\\"control\\":\\"send_cmd\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(543) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"mode\\":8,\\"key1\\":{\\"code\\":\\"ffffc01fa4934924924924924db4924da4936d30\\",\\"delay\\":0,\\"intervals\\":0,\\"times\\":5},\\"feq\\":0,\\"rate\\":0,\\"cfg\\":{\\"b\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,96,255,0,0,31,16],\\"c\\":[0,102,236,28,240,128,20,8,145,2,2,208],\\"s\\":[174,224,53,0,0,244,16,226,66,32,0,129],\\"d\\":[63,30,128,204,0,0,0,0,0,0,0,41,192,218,33,75,5,0,80,45,0,1,5,5],\\"t\\":[81,154,12,0,12,176,0,31,4,63,127],\\"f\\":[66,113,206,28,66,91,28,28]},\\"control\\":\\"send_cmd\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(543) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"mode\\":8,\\"key1\\":{\\"code\\":\\"ffffc01fa4934924924924934d34924da4926db0\\",\\"delay\\":0,\\"intervals\\":0,\\"times\\":5},\\"feq\\":0,\\"rate\\":0,\\"cfg\\":{\\"b\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,96,255,0,0,31,16],\\"c\\":[0,102,236,28,240,128,20,8,145,2,2,208],\\"s\\":[174,224,53,0,0,244,16,226,66,32,0,129],\\"d\\":[63,30,128,204,0,0,0,0,0,0,0,41,192,218,33,75,5,0,80,45,0,1,5,5],\\"t\\":[81,154,12,0,12,176,0,31,4,63,127],\\"f\\":[66,113,206,28,66,91,28,28]},\\"control\\":\\"send_cmd\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(543) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"mode\\":8,\\"key1\\":{\\"code\\":\\"ffffc01fa4934924924924934934924da4926930\\",\\"delay\\":0,\\"intervals\\":0,\\"times\\":5},\\"feq\\":0,\\"rate\\":0,\\"cfg\\":{\\"b\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,96,255,0,0,31,16],\\"c\\":[0,102,236,28,240,128,20,8,145,2,2,208],\\"s\\":[174,224,53,0,0,244,16,226,66,32,0,129],\\"d\\":[63,30,128,204,0,0,0,0,0,0,0,41,192,218,33,75,5,0,80,45,0,1,5,5],\\"t\\":[81,154,12,0,12,176,0,31,4,63,127],\\"f\\":[66,113,206,28,66,91,28,28]},\\"control\\":\\"send_cmd\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(543) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"mode\\":8,\\"key1\\":{\\"code\\":\\"ffffc01fa4934924924924934d34924da4926db0\\",\\"delay\\":0,\\"intervals\\":0,\\"times\\":5},\\"feq\\":0,\\"rate\\":0,\\"cfg\\":{\\"b\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,96,255,0,0,31,16],\\"c\\":[0,102,236,28,240,128,20,8,145,2,2,208],\\"s\\":[174,224,53,0,0,244,16,226,66,32,0,129],\\"d\\":[63,30,128,204,0,0,0,0,0,0,0,41,192,218,33,75,5,0,80,45,0,1,5,5],\\"t\\":[81,154,12,0,12,176,0,31,4,63,127],\\"f\\":[66,113,206,28,66,91,28,28]},\\"control\\":\\"send_cmd\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(543) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"mode\\":8,\\"key1\\":{\\"code\\":\\"ffffc01fa49349249249249249b4924da49369b0\\",\\"delay\\":0,\\"intervals\\":0,\\"times\\":5},\\"feq\\":0,\\"rate\\":0,\\"cfg\\":{\\"b\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,96,255,0,0,31,16],\\"c\\":[0,102,236,28,240,128,20,8,145,2,2,208],\\"s\\":[174,224,53,0,0,244,16,226,66,32,0,129],\\"d\\":[63,30,128,204,0,0,0,0,0,0,0,41,192,218,33,75,5,0,80,45,0,1,5,5],\\"t\\":[81,154,12,0,12,176,0,31,4,63,127],\\"f\\":[66,113,206,28,66,91,28,28]},\\"control\\":\\"send_cmd\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(543) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"mode\\":8,\\"key1\\":{\\"code\\":\\"ffffc01fa49349249249249249b4924da49369b0\\",\\"delay\\":0,\\"intervals\\":0,\\"times\\":5},\\"feq\\":0,\\"rate\\":0,\\"cfg\\":{\\"b\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,96,255,0,0,31,16],\\"c\\":[0,102,236,28,240,128,20,8,145,2,2,208],\\"s\\":[174,224,53,0,0,244,16,226,66,32,0,129],\\"d\\":[63,30,128,204,0,0,0,0,0,0,0,41,192,218,33,75,5,0,80,45,0,1,5,5],\\"t\\":[81,154,12,0,12,176,0,31,4,63,127],\\"f\\":[66,113,206,28,66,91,28,28]},\\"control\\":\\"send_cmd\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(543) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"mode\\":8,\\"key1\\":{\\"code\\":\\"ffffc01fa4934924924924924db4924da4936d30\\",\\"delay\\":0,\\"intervals\\":0,\\"times\\":5},\\"feq\\":0,\\"rate\\":0,\\"cfg\\":{\\"b\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,96,255,0,0,31,16],\\"c\\":[0,102,236,28,240,128,20,8,145,2,2,208],\\"s\\":[174,224,53,0,0,244,16,226,66,32,0,129],\\"d\\":[63,30,128,204,0,0,0,0,0,0,0,41,192,218,33,75,5,0,80,45,0,1,5,5],\\"t\\":[81,154,12,0,12,176,0,31,4,63,127],\\"f\\":[66,113,206,28,66,91,28,28]},\\"control\\":\\"send_cmd\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(543) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"mode\\":8,\\"key1\\":{\\"code\\":\\"ffffc01fa4934924924924934d34924da4926db0\\",\\"delay\\":0,\\"intervals\\":0,\\"times\\":5},\\"feq\\":0,\\"rate\\":0,\\"cfg\\":{\\"b\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,96,255,0,0,31,16],\\"c\\":[0,102,236,28,240,128,20,8,145,2,2,208],\\"s\\":[174,224,53,0,0,244,16,226,66,32,0,129],\\"d\\":[63,30,128,204,0,0,0,0,0,0,0,41,192,218,33,75,5,0,80,45,0,1,5,5],\\"t\\":[81,154,12,0,12,176,0,31,4,63,127],\\"f\\":[66,113,206,28,66,91,28,28]},\\"control\\":\\"send_cmd\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(543) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"mode\\":8,\\"key1\\":{\\"code\\":\\"ffffc01fa4934924924924934934924da4926930\\",\\"delay\\":0,\\"intervals\\":0,\\"times\\":5},\\"feq\\":0,\\"rate\\":0,\\"cfg\\":{\\"b\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,96,255,0,0,31,16],\\"c\\":[0,102,236,28,240,128,20,8,145,2,2,208],\\"s\\":[174,224,53,0,0,244,16,226,66,32,0,129],\\"d\\":[63,30,128,204,0,0,0,0,0,0,0,41,192,218,33,75,5,0,80,45,0,1,5,5],\\"t\\":[81,154,12,0,12,176,0,31,4,63,127],\\"f\\":[66,113,206,28,66,91,28,28]},\\"control\\":\\"send_cmd\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(543) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"mode\\":8,\\"key1\\":{\\"code\\":\\"ffffc01fa4934924924924934d34924da4926db0\\",\\"delay\\":0,\\"intervals\\":0,\\"times\\":5},\\"feq\\":0,\\"rate\\":0,\\"cfg\\":{\\"b\\":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,96,255,0,0,31,16],\\"c\\":[0,102,236,28,240,128,20,8,145,2,2,208],\\"s\\":[174,224,53,0,0,244,16,226,66,32,0,129],\\"d\\":[63,30,128,204,0,0,0,0,0,0,0,41,192,218,33,75,5,0,80,45,0,1,5,5],\\"t\\":[81,154,12,0,12,176,0,31,4,63,127],\\"f\\":[66,113,206,28,66,91,28,28]},\\"control\\":\\"send_cmd\\"}"}}'
Then I learned a 2-button remote. After learning each key it had me test them:
to 'eb####tb' v3.3 cmd: 13 (0D) len(127) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"control\\":\\"rf_study\\",\\"study_feq\\":\\"433\\",\\"ver\\":\\"2\\"}"}}'
from 'eb####tb' v3.3 cmd: 8 (08) len(319) b'...{"dps":{"202":"eyJudW0iOjEsInZlciI6IjIiLCJzdHVkeV9mZXEiOiI0MzMiLCJkYXRhMCI6InRpU2RBek1CTXdHZEE1MERNd0V6QVowRG5RTXpBVE1CblFNekFaMERNd0dkQTUwRE13RXpBWjBEblFNekFaMERNd0V6QVowRE13R2RBek1CblFPZEF6TUJuUU16QVRNQm5RT2RBek1CTXdHZEF6TUJuUU16QVowRE13R2RBNTBETXdFekFRPT0iLCJsdiI6WzBdfQ=="},"t":1683050684}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(127) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"control\\":\\"rfstudy_exit\\",\\"study_feq\\":\\"433\\",\\"ver\\":\\"2\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(127) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"control\\":\\"rfstudy_exit\\",\\"study_feq\\":\\"433\\",\\"ver\\":\\"2\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(463) b'...{"dps":{"201":"{\\"ver\\":\\"2\\",\\"rf_type\\":\\"sub_2g\\",\\"control\\":\\"rfstudy_send\\",\\"study_feq\\":\\"433\\",\\"key1\\":{\\"code\\":\\"eyJudW0iOjEsInZlciI6IjIiLCJzdHVkeV9mZXEiOiI0MzMiLCJkYXRhMCI6InRpU2RBek1CTXdHZEE1MERNd0V6QVowRG5RTXpBVE1CblFNekFaMERNd0dkQTUwRE13RXpBWjBEblFNekFaMERNd0V6QVowRE13R2RBek1CblFPZEF6TUJuUU16QVRNQm5RT2RBek1CTXdHZEF6TUJuUU16QVowRE13R2RBNTBETXdFekFRPT0iLCJsdiI6WzBdfQ==\\",\\"times\\":6,\\"delay\\":0,\\"intervals\\":0}}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(463) b'...{"dps":{"201":"{\\"ver\\":\\"2\\",\\"rf_type\\":\\"sub_2g\\",\\"control\\":\\"rfstudy_send\\",\\"study_feq\\":\\"433\\",\\"key1\\":{\\"code\\":\\"eyJudW0iOjEsInZlciI6IjIiLCJzdHVkeV9mZXEiOiI0MzMiLCJkYXRhMCI6InRpU2RBek1CTXdHZEE1MERNd0V6QVowRG5RTXpBVE1CblFNekFaMERNd0dkQTUwRE13RXpBWjBEblFNekFaMERNd0V6QVowRE13R2RBek1CblFPZEF6TUJuUU16QVRNQm5RT2RBek1CTXdHZEF6TUJuUU16QVowRE13R2RBNTBETXdFekFRPT0iLCJsdiI6WzBdfQ==\\",\\"times\\":6,\\"delay\\":0,\\"intervals\\":0}}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(127) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"control\\":\\"rfstudy_exit\\",\\"study_feq\\":\\"433\\",\\"ver\\":\\"2\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(127) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"control\\":\\"rf_study\\",\\"study_feq\\":\\"433\\",\\"ver\\":\\"2\\"}"}}'
from 'eb####tb' v3.3 cmd: 8 (08) len(319) b'...{"dps":{"202":"eyJudW0iOjEsInZlciI6IjIiLCJzdHVkeV9mZXEiOiI0MzMiLCJkYXRhMCI6Ind5U2RBelFCTkFHZEE1MEROQUUwQVowRG5RTTBBVFFCblFNMEFaMEROQUdkQTUwRE5BRTBBWjBEblFNMEFaMEROQUUwQVowRE5BR2RBelFCblFPZEF6UUJuUU5YQVRRQm5RT2RBelFCTkFHZEF6UUJuUU0wQVowRG5RTlhBVFFCblFNMEFRPT0iLCJsdiI6WzBdfQ=="},"t":1683050700}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(127) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"control\\":\\"rfstudy_exit\\",\\"study_feq\\":\\"433\\",\\"ver\\":\\"2\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(127) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"control\\":\\"rfstudy_exit\\",\\"study_feq\\":\\"433\\",\\"ver\\":\\"2\\"}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(463) b'...{"dps":{"201":"{\\"ver\\":\\"2\\",\\"rf_type\\":\\"sub_2g\\",\\"control\\":\\"rfstudy_send\\",\\"study_feq\\":\\"433\\",\\"key1\\":{\\"code\\":\\"eyJudW0iOjEsInZlciI6IjIiLCJzdHVkeV9mZXEiOiI0MzMiLCJkYXRhMCI6Ind5U2RBelFCTkFHZEE1MEROQUUwQVowRG5RTTBBVFFCblFNMEFaMEROQUdkQTUwRE5BRTBBWjBEblFNMEFaMEROQUUwQVowRE5BR2RBelFCblFPZEF6UUJuUU5YQVRRQm5RT2RBelFCTkFHZEF6UUJuUU0wQVowRG5RTlhBVFFCblFNMEFRPT0iLCJsdiI6WzBdfQ==\\",\\"times\\":6,\\"delay\\":0,\\"intervals\\":0}}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(463) b'...{"dps":{"201":"{\\"ver\\":\\"2\\",\\"rf_type\\":\\"sub_2g\\",\\"control\\":\\"rfstudy_send\\",\\"study_feq\\":\\"433\\",\\"key1\\":{\\"code\\":\\"eyJudW0iOjEsInZlciI6IjIiLCJzdHVkeV9mZXEiOiI0MzMiLCJkYXRhMCI6Ind5U2RBelFCTkFHZEE1MEROQUUwQVowRG5RTTBBVFFCblFNMEFaMEROQUdkQTUwRE5BRTBBWjBEblFNMEFaMEROQUUwQVowRE5BR2RBelFCblFPZEF6UUJuUU5YQVRRQm5RT2RBelFCTkFHZEF6UUJuUU0wQVowRG5RTlhBVFFCblFNMEFRPT0iLCJsdiI6WzBdfQ==\\",\\"times\\":6,\\"delay\\":0,\\"intervals\\":0}}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(463) b'...{"dps":{"201":"{\\"ver\\":\\"2\\",\\"rf_type\\":\\"sub_2g\\",\\"control\\":\\"rfstudy_send\\",\\"study_feq\\":\\"433\\",\\"key1\\":{\\"code\\":\\"eyJudW0iOjEsInZlciI6IjIiLCJzdHVkeV9mZXEiOiI0MzMiLCJkYXRhMCI6Ind5U2RBelFCTkFHZEE1MEROQUUwQVowRG5RTTBBVFFCblFNMEFaMEROQUdkQTUwRE5BRTBBWjBEblFNMEFaMEROQUUwQVowRE5BR2RBelFCblFPZEF6UUJuUU5YQVRRQm5RT2RBelFCTkFHZEF6UUJuUU0wQVowRG5RTlhBVFFCblFNMEFRPT0iLCJsdiI6WzBdfQ==\\",\\"times\\":6,\\"delay\\":0,\\"intervals\\":0}}"}}'
to 'eb####tb' v3.3 cmd: 13 (0D) len(127) b'...{"dps":{"201":"{\\"rf_type\\":\\"sub_2g\\",\\"control\\":\\"rfstudy_exit\\",\\"study_feq\\":\\"433\\",\\"ver\\":\\"2\\"}"}}'
Oddly enough, decoding that base64 results in another JSON string:
{"num":1,"ver":"2","study_feq":"433","data0":"wySdAzQBNAGdA50DNAE0AZ0DnQM0ATQBnQM0AZ0DNAGdA50DNAE0AZ0DnQM0AZ0DNAE0AZ0DNAGdAzQBnQOdAzQBnQNXATQBnQOdAzQBNAGdAzQBnQM0AZ0DnQNXATQBnQM0AQ==","lv":[0]}
Decoding that base64 and displaying the result as hex results in:
00000000 c3 24 9d 03 34 01 34 01 9d 03 9d 03 34 01 34 01 |.$..4.4.....4.4.|
00000010 9d 03 9d 03 34 01 34 01 9d 03 34 01 9d 03 34 01 |....4.4...4...4.|
00000020 9d 03 9d 03 34 01 34 01 9d 03 9d 03 34 01 9d 03 |....4.4.....4...|
00000030 34 01 34 01 9d 03 34 01 9d 03 34 01 9d 03 9d 03 |4.4...4...4.....|
00000040 34 01 9d 03 57 01 34 01 9d 03 9d 03 34 01 34 01 |4...W.4.....4.4.|
00000050 9d 03 34 01 9d 03 34 01 9d 03 9d 03 57 01 34 01 |..4...4.....W.4.|
00000060 9d 03 34 01 |..4.|
Looks great! Can you show me the messages for the curtain pairing as well? With rf_study, I can get an encoded code, but sending back the same with rfstudy_send
doesn't work. I wonder if curtain pairing somehow returns a similar data structure to your first 2 messages.
There wasn't any pairing, just Add -> Curtain -> [select random brand] -> [select random model] -> "Does it work? [y/n]". Those 2 commands I posted above are the only ones it sent.
What does your send function look like? It should be something like:
import json
import tinytuya
d = tinytuya.Device(..., persist=True)
cmd = {
"rf_type": "sub_2g",
"control": "rfstudy_exit",
"study_feq": "433",
"ver": "2"
}
d.set_value( 201, json.dumps(cmd).replace(" ", "") )
cmd = {
"ver": "2",
"rf_type": "sub_2g",
"control": "rfstudy_send",
"study_feq": "433",
"key1": {
"code":"eyJudW0iOjEsInZlciI6IjIiLCJzdHVkeV9mZXEiOiI0MzMiLCJkYXRhMCI6Ind5U2RBelFCTkFHZEE1MEROQUUwQVowRG5RTTBBVFFCblFNMEFaMEROQUdkQTUwRE5BRTBBWjBEblFNMEFaMEROQUUwQVowRE5BR2RBelFCblFPZEF6UUJuUU5YQVRRQm5RT2RBelFCTkFHZEF6UUJuUU0wQVowRG5RTlhBVFFCblFNMEFRPT0iLCJsdiI6WzBdfQ==",
"times": 6,
"delay": 0,
"intervals": 0
}
}
d.set_value( 201, json.dumps(cmd).replace(" ", "") )
With that "code" replaced with what rfstudy returned in 202.
I was trying the following way:
d._send_receive(d.generate_payload(tinytuya.CONTROL, {201: json.dumps({"rf_type": "sub_2g", "control": "send_cmd", "ver": "2", "key1": {"code": "eyJudW0iOjEsInZlciI6IjIiLCJzdHVkeV9mZXEiOiI0MzMiLCJkYXRhMCI6ImlSNU1FbUFGVVFIV0FvSUIxZ0xXQWxFQjFnSlJBZFlDVVFIV0FsRUIxZ0pSQWRZQ2dnSFdBbEVCMWdLQ0FZSUIxZ0tDQWRZQ2dnSFdBdFlDZ2dIV0FsRUJnZ0hXQXRZQ1VRR0NBZFlDMWdKUkFZSUIxZ0xXQW9JQjFnS0NBWUlCMWdLQ0FkWUNnZ0hXQW9JQjFnS0NBZFlDZ2dIV0FvSUIxZ0xXQW9JQlVRSFdBdFlDZ2dGUkFkWUMxZ0pSQVlJQjFnTFdBb0lCZ2dIV0F0WUNVUUdDQWRZQzFnST0iLCJsdiI6WzBdfQ==", "times": "6", "delay": "0", "intervals": "0"}}).replace(" ", "")}))
It did flash the light, so I thought it's working fine. However your code actually moves the curtain, so thank you for that.
Glad it's working.
Looking at the command you were sending, it looks like the differences are "rfstudy_send" vs "send_cmd", the inclusion of "study_feq", key1 numbers as integers vs strings, and the DP ID as a string vs integer (d.set_value()
casts it to a string as that's what devices normally expect).
Now that you have it working, where do we go from here? Is a new device type still needed/useful?
Well, I did try with rfstudy_send
as well in the same format without luck, so it's possible that the field types was the issue.
I mean, I can use it the way it is now, but I think a similar RFRemoteControlDevice
would be helpful for a lot of folks
I don't mind making it, though I have my doubts that "lots" of people will use it. What functions do you want it to have? At this point I think I only have enough info to implement .receive_button()
and .send_button()
.
I think that's good enough for start. Good RF bridges are high in demand, this class could make these devices a simple one.
Added in #343
Also adds
set_multiple_values()
to core as the newer devices require everything to be in one packet. I also updated turn_on() and turn_off() to return the received data instead of just dropping it on the floor while I was in there.Documentation for new format converters and head/key sending in examples/Contrib/IRRemoteControlDevice-example.py
Closes #225 and I'm also going to say Closes #74 and Closes #27