rytilahti / python-miio

Python library & console tool for controlling Xiaomi smart appliances
https://python-miio.readthedocs.io
GNU General Public License v3.0
3.55k stars 543 forks source link

Support for pronto codes on chuangmi.remote.h102a03 #495

Open nicole-ashley opened 5 years ago

nicole-ashley commented 5 years ago

I have a model of the Xiaomi IR remote that reports as chuangmi.remote.h102a03. It works fine when capturing and replaying those captured raw commands, but any commands converted from Pronto do nothing - no flashing light, no response from the target device, but - quite puzzlingly - an ok response from the device's API.

Here is the device on Ali Express.

Here are some examples:

>>> ir.info()
DEBUG:miio.device:10.1.1.23:54321 >>: {'id': 3, 'method': 'miIO.info', 'params': []}
DEBUG:miio.device:10.1.1.23:54321 >>: {'id': 104, 'method': 'miIO.info', 'params': []}
DEBUG:miio.device:10.1.1.23:54321 (ts: 1970-01-30 15:52:36, id: 104) << {'result':
  {'life': 2562756, 'cfg_time': 0, 'token': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 
   'mac': 'xx:xx:xx:xx:xx:xx', 'fw_ver': '1.4.3_10', 'hw_ver': 'MC200', 
   'model': 'chuangmi.remote.h102a03', 'wifi_fw_ver': 'SD878x-14.76.36.p79-702.1.0-WM', 
   'ap': {'rssi': -63, 'ssid': 'xxxxxxxxx', 'bssid': 'xx:xx:xx:xx:xx:xx'}, 
   'netif': {'localIp': '10.1.1.23', 'mask': '255.255.255.0', 'gw': '10.1.1.1', 
             'gw_mac': 'xx:xx:xx:xx:xx:xx' },
  'mmfree': 56428, 'ot': 'otu', 'otu_stat': [325, 333, 3647, 125, 3134, 10], 
  'ott_stat': [19, 4, 3, 612]}, 'id': 104}
chuangmi.remote.h102a03 v1.4.3_10 (xx:xx:xx:xx:xx:xx) @ 10.1.1.23 - token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Works (previously recorded command):

>>> ir.play_raw('tllsNyt1am1Wp1Bo1ZodBoNDtVCoNBoNRoNrAFKtWcAQgAPAA8ADwAPBTKi0IFAgViooB53eg2cAsqiAWQCaUGg02g0kAsgIyAfOogZpPQ==')
DEBUG:miio.device:10.1.1.23:54321 >>: {'id': 2, 'method': 'miIO.ir_play', 
  'params': {'freq': 38400, 'code': 'tllsNyt1am1Wp1Bo1ZodBoNDtVCoNBoNRoNrAFKtWcAQgAPAA8ADwAPBTKi0IFAgViooB53eg2cAsqiAWQCaUGg02g0kAsgIyAfOogZpPQ=='}}
DEBUG:miio.device:10.1.1.23:54321 (ts: 1970-01-30 15:49:27, id: 2) << {'result': ['ok'], 'id': 2}
['ok']

# Doesn't work (Pronto code that should do the same):

>>> ir.play_pronto('0000 0067 0000 000D 0060 0018 0018 0018 0030 0018 0030 0018 0030 0018 0018 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 03F6')
DEBUG:miio.device:10.1.1.23:54321 >>: {'id': 419, 'method': 'miIO.ir_play', 
  'params': {'freq': 40244, 'code': 'Z6UzAFQCAACoBAAAUQkAAGxiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEBAQABAAEAAAAwAgABAQEAAQABAAAAMA=='}}
DEBUG:miio.device:10.1.1.23:54321 (ts: 1970-01-30 16:28:16, id: 419) << {'result': ['ok'], 'id': 419}
['ok']

>>> ir.play_raw('6UzAFQCAACoBAAAUQkAAGxiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEBAQABAAEAAAAwAgABAQEAAQABAAAAMA==', 40244)
DEBUG:miio.device:10.1.1.23:54321 >>: {'id': 420, 'method': 'miIO.ir_play', 
  'params': {'freq': 40244, 'code': '6UzAFQCAACoBAAAUQkAAGxiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEBAQABAAEAAAAwAgABAQEAAQABAAAAMA=='}}
DEBUG:miio.device:10.1.1.23:54321 (ts: 1970-01-30 16:28:39, id: 420) << {'result': ['ok'], 'id': 420}
['ok']

# From specs (also does nothing):

>>> ir.play_pronto('0000 006C 0022 0002 015B 00AD 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0041 0016 0041 0016 0041 0016 0041 0016 0041 0016 0041 0016 0041 0016 0016 0016 0016 0016 0041 0016 0016 0016 0041 0016 0016 0016 0016 0016 0016 0016 0016 0016 0041 0016 0016 0016 0041 0016 0016 0016 0041 0016 0041 0016 0041 0016 0041 0016 0622 015B 0057 0016 0E6C')
DEBUG:miio.device:10.1.1.23:54321 >>: {'id': 524, 'method': 'miIO.ir_play', 
  'params': {'freq': 38381, 'code': 'Z6VHAD0CAACdBgAA2ggAAJsRAABQIwAAyZ8AAMF3AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAAAAAAAAAQEBAQEBAQAAAQABAAAAAAEAAQABAQEBBQJGA='}}
DEBUG:miio.device:10.1.1.23:54321 (ts: 1970-01-30 16:42:56, id: 524) << {'result': ['ok'], 'id': 524}
['ok']

>>> ir.play_raw('Z6VHAD0CAACdBgAA2ggAAJsRAABQIwAAyZ8AAMF3AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAAAAAAAAAQEBAQEBAQAAAQABAAAAAAEAAQABAQEBBQJGA=', 38381)
DEBUG:miio.device:10.1.1.23:54321 >>: {'id': 526, 'method': 'miIO.ir_play', 
  'params': {'freq': 38381, 'code': 'Z6VHAD0CAACdBgAA2ggAAJsRAABQIwAAyZ8AAMF3AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAAAAAAAAAQEBAQEBAQAAAQABAAAAAAEAAQABAQEBBQJGA='}}
DEBUG:miio.device:10.1.1.23:54321 (ts: 1970-01-30 16:43:58, id: 526) << {'result': ['ok'], 'id': 526}
['ok']

Unfortunately I don't have a clue where to start, or I'd tinker with the code myself. I'm happy to work with you if you need to test things on my device.

syssi commented 5 years ago

Could you try to play pronto codes with 38400 baud? Could you provide the mDNS name of the device? I would like to add it to the list of supported/discoverable devices:

https://github.com/rytilahti/python-miio/blob/master/miio/discovery.py#L53

nicole-ashley commented 5 years ago

Thanks for your quick response!

I assume you mean a raw converted from the Pronto code? The Pronto method doesn't have a baud/frequency parameter.

# My code 
>>> ir.play_raw('6UzAFQCAACoBAAAUQkAAGxiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEBAQABAAEAAAAwAgABAQEAAQABAAAAMA==', 38400)
['ok']

# From specs
>>> ir.play_raw('Z6VHAD0CAACdBgAA2ggAAJsRAABQIwAAyZ8AAMF3AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAAAAAAAAAQEBAQEBAQAAAQABAAAAAAEAAQABAQEBBQJGA=', 38400)
['ok']

Same thing - no flashing, no transmission.

The mDNS name as far as I can tell is chuangmi-remote-h102a03_miio108732461, so I'm guessing a good identifier would be chuangmi-remote-h102a03_.

EDIT: I realise I wasn't in debug mode for these two tests - let me know if you want me to run them again with debug logging on.

rezmus commented 5 years ago

following methods are also present in firmware:

get_indicatorLamp set_indicatorLamp ir_play_batch

i can share firmware file in case you are interested for analyze.

nicole-ashley commented 5 years ago

get_indicatorLamp and set_indicatorLamp probably refer to the option in the Xiaomi app to disable the blue LED on the front.

syssi commented 5 years ago

@yawor Do you like to provide some support here? It's about pronto codes ;-)

syssi commented 5 years ago

It looks like the LED of the devices can be controlled by:

# current status
miiocli device --ip IP --token TOKEN raw_command get_indicatorLamp "[]"

# Disable the indicator LED and query the current status
miiocli device --ip IP --token TOKEN raw_command set_indicatorLamp "['off']"
miiocli device --ip IP --token TOKEN raw_command get_indicatorLamp "[]"

# Enabled the indicator LED and query the current status
miiocli device --ip IP --token TOKEN raw_command set_indicatorLamp "['on']"
miiocli device --ip IP --token TOKEN raw_command get_indicatorLamp "[]"

If somebody likes to test these commands I will extend python-miio afterwards.

rezmus commented 5 years ago

"chuangmi-remote-h102a03_": ChuangmiIr,

you should remove underscore.

syssi commented 5 years ago

I used the underscore as separator here.

rezmus commented 5 years ago

for all miio wifi devices you can get model name like this:

$model = str_replace("-",".",stristr($ssid,"_",true));

so underscore should be redundant here.

syssi commented 5 years ago

If another model is called "chuangmi-remote-h102a03b" and incompatible with the ChuangmiIr implementation it shouldn't be reported as supported because "chuangmi-remote-h102a03" is matching. The underscore does a good job in this case.

rezmus commented 5 years ago

OK, but with this logic you might as well add underscore to any device listed in discovery.py, because if they release for example zhimi-airpurifier-v10 (match zhimi-airpurifier-v1) it shouldn't be reported as supported ;) or model matching should be done like i wrote above, it's how miio sdk does it and how mi home builds model string to compare with model list for selected region.

anyway it's fine for me, one underscore is not worth an argue ;)

syssi commented 5 years ago

You are totally right. Any input is appreciated! :-) Feel free to provide additional feedback and/or PRs. :-)

nicole-ashley commented 5 years ago

@syssi My suspicions were correct, this is the blue LED on the front which is usually on all the time and flashes when a command is sent. It's the light I'm referring to "not flashing" when the codes above are not understood. If you turn it off, it's off all the time even when successfully playing commands.

This corresponds to the setting in the app called "Instruction light", but I think "Indicator light" is a more accurate English name.

Screenshot_20190414-101101~2 IMG_20190414_102814~2

$ miiocli device raw_command get_indicatorLamp "[]"
Running command raw_command
['on']
$ miiocli device raw_command set_indicatorLamp "['off']"
Running command raw_command
['ok']
$ miiocli device raw_command get_indicatorLamp "[]"
Running command raw_command
['off']

Screenshot_20190414-101744~2 IMG_20190414_102845~2

$ miiocli device raw_command set_indicatorLamp "['on']"
Running command raw_command
['ok']
$ miiocli device raw_command get_indicatorLamp "[]"
Running command raw_command
['on']

Screenshot_20190414-101101~2 IMG_20190414_102814~2

yawor commented 5 years ago

@syssi this is not definitive as I've only glimpsed on what @nikrolls posted, but it seems that the IR format has changed. If I'm correct then this needs to be reverse engineered like the previous format for chuangmi. For that I need some reference signal to be able to understand the new format. @nikrolls can you share more info regarding the equipment for which you've recorded the signal that works (the one you've posted in opening post)? Manufacturer, device type and model, maybe even which function on the remote you've used to record that signal. --edit Upon further inspection, I'm certain that this is now a different format. Until now every signal (in raw binary form, not the base64 string) started with 0xA567. This one starts with 0xB659 (I'd need to see more recorded signals for this new format to know if this value is constant or not). The next two bytes should contain number of edges but it doesn't seem to be true for the posted signal as it would then need to have 14188 edges recorded :open_mouth:

yawor commented 5 years ago

@nikrolls do you have an universal remote control by any chance? If yes it would be helpful to program it to a device of a known protocol, parameters and commands.

rezmus commented 5 years ago

chuangmi.ir.v2 does not support led methods, chuangmi.remote.v2 does.

nicole-ashley commented 5 years ago

@yawor These were recorded off the universal remote that I have - an Xbox One with Kinect. I can enter a 4-digit TV code and it will play discreet codes for power on and off. I'm testing on a Sony Brava 32V4000, but codes as low level as these are standard across most Sony TVs.

Raw codes below are captured using the Chuangmi H102A03, Pronto codes are according to an apparently reliable source on Remote Central.

# Power on (discreet code from Xbox Universal Remote)
Raw: tllsNyt1am1Wp1Bo1ZodBoNDtVCoNBoNRoNrAFKtWcAQgAPAA8ADwAPBTKi0IFAgViooB53eg2cAsqiAWQCaUGg02g0kAsgIyAfOogZpPQ==
Pronto: 0000 0067 0000 000D 0060 0018 0018 0018 0030 0018 0030 0018 0030 0018 0018 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 03F6

# Power off (discreet code from Xbox Universal Remote)
Raw: tllsNyt1am1Wp1Bo1nodBoNDqtCoNBoNVoNroNBptGsgBRAAeAB4AHgAfQ6DUaLQqDUaCCsVFAPO70GzgHmAWQCaAzFQaSAeYD61EDNJ6A==
Pronto: 0000 0067 0000 000D 0060 0018 0030 0018 0030 0018 0030 0018 0030 0018 0018 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 03DE

I also have other codes I captured from the TV's own remote:

# Volume up
Raw: tllsNyt1am1Wt1Bo1BodBoNDnNCoNBoNloNroNBplKtoBRAAeAB4AHgAeCmVFAGIAN6Dd6DZ6CDEYAb0Gm0Gk0Gg1EAggA3ogGf0Ggg=
Pronto: 0000 0067 0000 000D 0060 0018 0018 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 0426

# Volume down
Raw: tllsNyt1am1Wp1Bos0odBoNEoVCoNBoNkoNroNBotSAEKhXStAHkAB4AHgAeABVDoNRooAxABvQbvQbPRQYjADeg1Gg0mhACEAQYAa0Ggz0=
Pronto: 0000 0067 0000 000D 0060 0018 0030 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 040E

# Input select
Raw: tllsNyt1am1XsVBp1joVBoNBqlBs9BoNYs9JoNBp9jodBoNDooChzaogKFQ5xSqDQaFdq0AeVto9RAFIADwAPAAS20qiUG10m00m10mp1G00m00uhUq01G00qh0UAMgEzpNpsdqqoD5ANkA+QCZWik1ik20B8gM6o4GbUkDNQESs9prIGZ3cDNaLaaTZ6TPQ
Pronto: 0000 0067 0000 000D 0060 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 040E (I think)

# Arrow up
Raw: tllsNyt1am1XoVBoc0odBoNCsNBs9BoNtqNRoNBotrpVBoNBsNZAPIADwAPAA8ACqpRalQanRalSanRbRSajRalRqFRbxQajRbRRQDzAXKg1Ko1Km1IB8qkAelootSotFooGZAPlQgM0qVFoQGaAPkBm1CoNSoNRns9A
Pronto: 0000 0067 0000 000D 0060 0018 0030 0018 0018 0018 0018 0018 0018 0018 0030 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 040E

# Arrow down
Raw: tllsNyt1am1XsVBo13odBoNCrFCoNBoNvu9RoNBotZpVBoNEqNYu4CBAAeAB4AHgATRKDZ6CCuVJoVBs9JAOIF0ruAOVRATKz0UBcgCjpoD5gEFSaGAYQO5AZ+Bn4GdWcDNqDQZ6
Pronto: 0000 0067 0000 000D 0060 0018 0018 0018 0030 0018 0018 0018 0018 0018 0030 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 040E

# Enter
Raw: tllsNyt1am1XsVBolJodBoNCrFBs9BoNuu9RoNBolZpQB5VahgFFS6PSaCAB4AHgAeAA1VotooNTotSotTotopNSotSoVRot4AHK0AIlaKSAudSqtSqIA5AJlQgDyAXOrUUDP6lRqEBmdBAzmhU0DM6iBmoC5VGiz0A=
Pronto: 0000 0067 0000 000D 0060 0018 0030 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 040E

I should be able to set the Xbox to any other TV with a four digit code and capture at least power commands (and possibly volume commands) from it for reference.

yawor commented 5 years ago

@nikrolls awesome. This should be enough to attempt reversing the format if it's not encrypted or compressed in any complicated way.

nicole-ashley commented 5 years ago

Great! Also let me know if you want me to set my Xbox to a specific model and capture power codes.

yawor commented 5 years ago

@nikrolls you could record few signals for example for LG and Samsung. I've glimpsed over the vol up and vol down for Sony and they only differ on one position in Pronto, but the data from your chuangmi device is totally different. I know that they shouldn't be almost identical as recording a signal is a tricky business (the transmitter is usually not 100% stable and difference in clocks between transmitter and receiver - all this causes that the timings have some jitter), but these seem to have no obvious correlation with pronto signals. What's interesting is that first 9 bytes are identical. That's why I would like to see raw data of signals with different protocols to see if these are always the same or change depending on the signal in some way. It's too late for me today, need to get some sleep. I'll try tomorrow.

nicole-ashley commented 5 years ago

Great - I'll record some from other manufacturers. I can also try recording the above signals again a few times to see if they change a lot every time. If they do, I wonder if there's some kind of hashing or encryption over a temporal value going on?

I probably won't get any recordings done in the next 24 hours, but I'll try after that.

rezmus commented 5 years ago

you should probably check libcompression.so from plugin lib folder, that's where decode/encode is done.

yawor commented 5 years ago

@rezmus that was awesome tip. It would take a lot longer if I had to do full analysis of the disassembled/decompiled code, but fortunately they've left names of functions which directed me to a heatshrink compression library. It is based on LZSS compression and has really low memory footprint so it's ideal for embedded applications like this. I've cloned and built https://github.com/atomicobject/heatshrink and used the resulting binary to decompress binary data (after decoding base64 string) and I can confirm that this is it. The format is still not the same as before, but now I can work out the structure. I've also found a python library (it's called heatshrink) which provides bindings to the above C library, but the problem is really poor Py3 compatibility. I've tried to use it with python versions from 3.5 to 3.7 and it fails on import. I'll try looking into the problem and maybe provide some PRs for them so we could use it. --edit Just to be sure I've installed the library under python 2.7 and it works properly and correctly decompresses the IR signal data. --edit Just for information, the heatshrink library uses cython to build native python extension. This means the target system needs to have a compiler and python-dev (header files) packages installed. I don't know if this is an issue for us, because python-miio already uses cryptography package, which also provides a native extension which needs to be built during installation. --edit There's already a pending PR with Py3 fixes in the pyheatshrink project but it's hard to tell when it's going to be merged. The last activity of the author was in December. We could just fork the repo, apply the PR and add dependency on that forked repository.

yawor commented 5 years ago

@rezmus BTW you can delete the link to the file. It's better not to keep it here longer than necessary (in case of some legal issues).

yawor commented 5 years ago

Good news! At the bottom level, the format is still the same as before. Here's what they did here:

So all we need to do is to add the 2 last steps to the current pronto conversion to add support for this device.

nicole-ashley commented 5 years ago

Fantastic news! That was quick 😊

yawor commented 5 years ago

My proposition is to subclass ChuangmiIr class by creating ChuangmiRemote(ChuangmiIr) class. It would override the pronto_to_raw classmethod by applying extra steps. This way we don't need to change the API in any way. We can also move ChuangmiRemote specific methods (the indicator LED related ones) into the new class. Everything else can be inherited from the base class.

yawor commented 5 years ago

@nikrolls can you try these? volume up: tllsNyt1am1VvVBo1RodBoNDt9CoNBoNVqNroNBoVStwBRAAeAB4AHgAeCmVFAGIAN6Dd6DZ6CDEYAb0Gm0Gez0= with frequency set to 40244 volume down: tllsNyt1am1VvVBo1RodBoNDt9CoNBoNVqNroNBptCAEIADwAPAA8AD6DQ6DUaKAMQAb0G70Gz0UGIwA3oNNoM9noA== with frequency also set to 40244

yawor commented 5 years ago

@nikrolls I've created a PR. You can try installing the library with it and test any pronto code by yourself.

nicole-ashley commented 5 years ago

@yawor Your PR works perfectly, thank you! I've tried with a bunch of pronto codes for this TV including many discreet ones and everything works as expected. I also tested it with other devices (eg my Xbox which can receive IR commands) and it works there as well.

pmtcrespo commented 5 years ago

I own a chuangmi.ir.v2 and just received two more units but i found out that the codes weren't working.

I bumped into this thread and so i thought i had received the chuangmi.remote.h102a03 but i was wrong. It appears that i received yet another model, the chuangmi.remote.v2

miiocli device --ip XXX.XXX.XXX.XXX --token XXXXXXX raw_command miIO.info []`

Running command raw_command {'wifi_fw_ver': 'v1.0-3169-g79af9a5-dirty', 'fw_ver': '1.3.1_0014', 'mac': 'XX:XX:XX:XX:XX:XX', 'mmfree': 38908, 'hw_ver': 'ESP32', 'uid': 1813652162, 'life': 239345, 'netif': {'mask': '255.255.255.0', 'localIp': 'XX.XX.XX.XX', 'gw': 'XX.XX.XX.XX'}, 'ap': {'ssid': 'XXXXXX', 'primary': 6, 'bssid': 'XX:XX:XX:XX:XX:XX', 'rssi': -19}, 'token': 'XXXXXXXX', 'model': 'chuangmi.remote.v2'}

In essence:

I tried to issue a command from my chuangmi.ir.v2 and capture it with the chuangmi.remote.v2

Sent from chuangmi.ir.v2: Z6V3ALcAAADUAAAABQIAAOYFAAAdBgAAvwsAAJAjAAAlOwAAONQCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABxgGVCIiIiIiIiIiJCIiJCQiJCIkJCQkJCQkJCIiIiQkJCQkJCIiIiIiIyQiIiIiIiQiIiIiIiQkJCQgI=

Received on chuangmi.remote.v2: mUxmEsmM4mkwlkzmE2mEsnMwmswlk1AIKYzWZzCWTYBspoAOU1AUOYABlOAD2AgIA9ACzAH8CdwMzAPKYzWZAYLNAFCAHebASFMQCEAhMCpAGfAIMEOQjDAZcJ6AljAa0AhAgXmM0m4YSgNKGWYJ5hh0Au4FKArSH9YIigv4CbAPLAD2EkYUaAD0C7wpbgFkIlYqcBPuG4gnZDCQBB4wlBkeBywmOgItMIAA

Also tried to reverse this command by using @yawor 's method, figured out that the "learn" appendix isn't there, but Heatshrink seems to be able to decode the command. I can't understand the result. Maybe someone can?

import base64 import heatshrink

captured_command='mUxmEsmM4mkwlkzmE2mEsnMwmswlk1AIKYzWZzCWTYBspoAOU1AUOYABlOAD2AgIA9ACzAH8CdwMzAPKYzWZAYLNAFCAHebASFMQCEAhMCpAGfAIMEOQjDAZcJ6AljAa0AhAgXmM0m4YSgNKGWYJ5hh0Au4FKArSH9YIigv4CbAPLAD2EkYUaAD0C7wpbgFkIlYqcBPuG4gnZDCQBB4wlBkeBywmOgItMIAA' decoded_command=heatshrink.decode(base64.b64decode(captured_command)).decode() print(decoded_command)

Gives the following results:

210,1840,3060,9050,560,1530,610,430,550,500,580,430,560,500,530,500,530,500,530,500,580,450,530,1520,560,480,560,480,600,1480,630,1450,560,480,600,1480,600,450,530,1530,600,1480,560,1530,550,1530,600,1480,600,1500,580,1470,610,1480,610,450,580,430,560,480,610,1470,560,1530,560,1530,610,1470,600,1480,600,1480,610,430,600,430,600,430,550,480,550,480,550,1470,560,1530,550,500,530,480,560,480,560,500,580,430,550,1520,610,430,560,500,580,430,560,500,530,480,610,1470,560,1520,600,1480,560,1520,600,0

Does anyone understand these results? Is there any chance to support this device in the pronto conversion?

I am pretty unhappy with this chuangmi.remote.v2 because it is not being able to successfully capture and reproduce a command that the chuangmi.ir.v2 could without issues.. I can comment on this later, maybe someone can help me out.

yawor commented 5 years ago

@pmtcrespo it seems this uses a different signal encoding scheme. It compresses an ascii, comma separated list of edge timings. I need to compare both signals (from both devices) to be sure, but it shouldn't be very hard to add support for this scheme too.

yawor commented 5 years ago

@pmtcrespo I've updated my PR #501 with a support for your device. Please test it if it works for you.

pmtcrespo commented 5 years ago

Thank you for the quick update! I'll give it a try as soon as i can!

pmtcrespo commented 5 years ago

@yawor didn't have much time but i tested two pronto commands

Samsung TV Turn On

ir.play_pronto('0000 006D 0000 0022 00AC 00AB 0015 0041 0015 0041 0015 0041 0015 0016 0015 0016 0015 0016 0015 0016 0015 0016 0015 0041 0015 0041 0015 0041 0015 0016 0015 0016 0015 0016 0015 0016 0015 0016 0015 0041 0015 0016 0015 0016 0015 0041 0015 0041 0015 0016 0015 0016 0015 0041 0015 0016 0015 0041 0015 0041 0015 0016 0015 0016 0015 0041 0015 0041 0015 0016 0015 0689')

Samsung TV Turn Off

ir.play_pronto('0000 006D 0000 0022 00AC 00AB 0015 0041 0015 0041 0015 0041 0015 0016 0015 0016 0015 0016 0015 0016 0015 0016 0015 0041 0015 0041 0015 0041 0015 0016 0015 0016 0015 0016 0015 0016 0015 0016 0015 0016 0015 0016 0015 0016 0015 0041 0015 0041 0015 0016 0015 0016 0015 0041 0015 0041 0015 0041 0015 0041 0015 0016 0015 0016 0015 0041 0015 0041 0015 0016 0015 0689')

Both commands worked! I'll try a few more tomorrow but it's looking good!

However my issue with the chuangmi.remote.v2 is a different matter.. @yawor maybe you could help me out with this one as well ;)

I have captured my AC Turn Off command with the chuangmi.ir.v2 which works when played back (raw) The following was the chuangmi.ir.v2 captured command:

Z6XnAA4CAABuBQAArAUAAOcFAAAeBgAAowsAAF0jAAB8IwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlQAAAAAAAAAAAQAAAAAAAQEBAQEAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAEAAMEAAAAAAAAAQdUAAAAAAAAAAAEAAAEAAQEAAQEBAQEAwIDAAAABAQEBAQEAAAAAAAEBAAAAAAAAwAAAAAAAAAEBAAA==

However when i capture the same command with the chuangmi.remote.v2 it does not work when i play it back (raw) The following was the chuangmi.remote.v2 captured command:

mcwmEwlk5mEzmEsmoBBTGbACFNZqAGUymEsmk3AHKbAHsAuYDbzQAMgMDAjKazEA9gB7AjKYgGIBw4A7gmGBAYHjAwIA2YGEBBHNZyCUsxA2cBHgAzBEMFhwrWCN8KXArbCQsAd5wEZQG7gd+C/QRGhu+KWwC8BIeCQQbcA4uCjICjTGaB6GH7ANbixUE5YXkADkBwgKRzMAwpnMAHSnMwFb8OCB1vmMwgA=

Is there any difference between these two commands? I cant seem to understand why chuangmi.ir.v2 works and chuangmi.remote.v2 doesn't..

Can you understand why? Thanks!

yawor commented 5 years ago

The second signal is much shorter than the first one, but I've compared them edge by edge (up to the shorter one's end) and there are differences up to 50 microseconds (which is insignificant).

The issue seems to be that the second signal is cut short and doesn't contain all the data for the AC to accept the command. To be more accurate, the first signal contains two separate commands (each has 58 pairs of pulse/gap times, the whole recorded signal has 116 pairs). If I compare both commands in the signal, they are different. This could mean that the AC's remote actually sends multiple commands one after another. For some reason the chuangmi.remote.v2 hasn't captured whole transmission but cut it short just after 6 pairs of the second command.

There's nothing I can do on the python-miio side to fix the capture logic in the chuangmi.remote.v2.

yawor commented 5 years ago

I've created a quick script for you to convert from chuangmi-ir raw to chuangmi-remote-v2 raw:

import base64
from sys import argv

import heatshrink
from miio.chuangmi_ir import ChuangmiIrSignal

def convert(data):
    signal = ChuangmiIrSignal.parse(base64.b64decode(data))
    times = []
    for pair in signal.edge_pairs:
        times.append(signal.times_index[pair.pulse])
        times.append(signal.times_index[pair.gap])
    times = '{}\x00'.format(','.join(map(str, times)))
    return base64.b64encode(heatshrink.encode(times.encode()))

if __name__ == '__main__':
    print(convert(argv[1]))

Just save this as a python file and run within a virtualenv where you have the python-miio installed. The heatshrink also needs to be installed. You need to pass raw string as an argument.

pmtcrespo commented 5 years ago

@yawor just tested the script and it works! Thank you so much!

Let me know if there's any more testing required for this device but i believe you've nailed it perfectly!

rezmus commented 5 years ago

there is new one chuangmi.remote.h102c01

http://static.home.mi.com/app/image/get/file/developer_1554789490wm8pqzoc.png

zon2004 commented 5 years ago

Hello. I have a version chuangmi-remote-v2. She controls the TV but cannot control the air conditioner. When I copy a command and send it back can be seen on the LED that they do not give a full package of commands

cvladan commented 5 years ago

Ha? These new models are popping everywhere! I thought I was going nuts...

MarkFlemingNZ commented 5 years ago

Yes... I have one as well. I've tried using @yawor's script to convert some V1 codes I'm hoping will work, but am getting the below: Traceback (most recent call last): File "ConvertIR.py", line 19, in <module> print(convert(argv[1])) File "ConvertIR.py", line 9, in convert signal = ChuangmiIrSignal.parse(base64.b64decode(data)) File "/usr/local/lib/python3.5/dist-packages/construct-2.9.45-py3.5.egg/construct/core.py", line 304, in parse File "/usr/local/lib/python3.5/dist-packages/construct-2.9.45-py3.5.egg/construct/core.py", line 316, in parse_stream File "/usr/local/lib/python3.5/dist-packages/construct-2.9.45-py3.5.egg/construct/core.py", line 328, in _parsereport File "/usr/local/lib/python3.5/dist-packages/construct-2.9.45-py3.5.egg/construct/core.py", line 1979, in _parse File "/usr/local/lib/python3.5/dist-packages/construct-2.9.45-py3.5.egg/construct/core.py", line 328, in _parsereport File "/usr/local/lib/python3.5/dist-packages/construct-2.9.45-py3.5.egg/construct/core.py", line 2540, in _parse construct.core.ConstError: parsing expected 42343 but parsed 38

Anyone know what is going on there and able to help?

schilea commented 4 years ago

Hi, I got a similar error. Any clue?

MarkFlemingNZ commented 4 years ago

Sorry for not leaving an update... @yawor's script was spot on, the parse error I was getting was due to me feeding the script a code which was not correct (it wasn't a chuangmi-remote-v1 code).

I was lucky enough to have a friend who had a chuangmi-remote-v1. I got them to record the codes from my IR remote on that, and then converted those codes to v2 codes using the script.

My chuangmi-remote-v2 plays the converted codes back fine, I just can't record them on it!

schilea commented 4 years ago

Hi, thanks for the answer. I tried the examples above and the script works. The problem I have is that I tried to use the Broadlink RM 3 mini working raw codes as not having v1 remote. I was wrongly assumed that raw base 64 from Broadlink is the same as chuangmi-remote-v1 but seems not.

So the question is: how should I proceed to translate from Broadlink raw to chuangmi.remote.v2?

schilea commented 4 years ago

Sending working "off" AC command from Broadlink RM mini 3:

JgBAAGcAAUYRNBASDxMPEw81EBEQEw8TDzUPNRASEBIPEhASEBIQEhASEBIPExASEBIQNBASDzUQERATEBIQNBEADQUAAAAAAAAAAA== 2600400067000146113410120f130f130f35101110130f130f350f35101210120f12101210121012101210120f1310121012103410120f35101110131012103411000d050000000000000000

Learning on HA with "xiaomi_miio.remote_learn_command" on chuangmi.remote.v2:

ms2mEsmM1mkwlk0nMwlk1ADKZziYSybTEAdpqAmUwAgObgEFMwJCAHYAtAMDA4MEE5sBKU0AtKYzaZAEEB0U1AMIBA5qAWQFKAQEBygA9gVkCCgF7gumB+YAZBBGB+gCZAjwAmUxmwNxAgQE3AJJgYmAWYNpAYoBQQTaAdGA4cwgAA==

Trying command in HA for chuangmi.remote.v2 and not working.

Sending back the learned command from chuangmi.remote.v2 with "remote.send_command":

entity_id: remote.mi_living_room_remote device: 32756745 command: ms2mEsmM1mkwlk0nMwlk1ADKZziYSybTEAdpqAmUwAgObgEFMwJCAHYAtAMDA4MEE5sBKU0AtKYzaZAEEB0U1AMIBA5qAWQFKAQEBygA9gVkCCgF7gumB+YAZBBGB+gCZAjwAmUxmwNxAgQE3AJJgYmAWYNpAYoBQQTaAdGA4cwgAA== num_repeats: 1 delay_secs: 0.75 hold_secs: 2.5

Learning IR command on Broadlink RM mini 3

IR Infrared Learning mode is enabled. OnRawData : 26003C000E3211120D140B161133120F12110F1210340F350E130E1410111110111112110F1310100D150F120E140E3610111035111010130E130E3511000D05000000000000000000000000 OnRawData Base64 : JgA8AA4yERINFAsWETMSDxIRDxIQNA81DhMOFBARERARERIRDxMQEA0VDxIOFA42EBEQNREQEBMOEw41EQANBQAAAAAAAAAAAAAAAA==

Trying the received command in HA for Broadlink RM mini 3 and not working.

mpsOxygen commented 3 years ago

@rezmus could you give a link to the firmware pls?

rezmus commented 3 years ago

which model?

mpsOxygen commented 3 years ago

chuangmi.remote.v2

mpsOxygen commented 3 years ago

Thank you!