Closed lprhodes closed 5 years ago
Just to make sure I understand, the flow is:
Send 0x6a, 0x19 Send 0x6a, 0x1a until you get an 0x01 Send 0x6a, 0x1b until you get an 0x01 Send 0x6a, 0x04 to get the response
Is there any need to call 0x6a, 0x03 (the enter_learning command that's used for IR)? Does the orange LED turn on at any point in this process?
Hello @mjg59 ,
I can confirm that the orange LED turns on, directly after entering learning "Sweep Frequency" (0x19, I guess). And it stays on during both steps.
First step is Learning frequency (0x1a ?), a long press on button until it´s done. Second step is Learning Code (0x1b ?). and is only a short press, like with IR code.
Maybe not much help, but love to get this working.
I ended up adding it to the JS version - it should help you work things out https://github.com/lprhodes/broadlinkjs-rm/blob/master/index.js
@lprhodes Afraid not - it's still not clear what the correct sequence of events is. Is my understanding in https://github.com/mjg59/python-broadlink/issues/87#issuecomment-299725918 correct?
is it possible to try this?
Could someone test https://github.com/mjg59/python-broadlink/tree/rf_experiment ? I don't have any RF equipment to test it with.
@mjg59, I made a test and it works on python3 (3.6.3). But on python 2.7 I get a timeout when I run device.check_data(). After that all the calls receive a timeout and I need to reconnect to the device. Otherwise, on python3 works as expected. I also used the returned code (device.send_data(ir_packet)) and I could control the end device.
I used this cheap RF remote to test it: https://www.amazon.com/Lerway-Controller-Wireless-Control-R106/dp/B00AHU2U7O
@mjg59 Tested with some RF remotes and I get None
on devices[0].check_data()
Here is example code that I use. May be I missed something
import broadlink
broadlink.setup('ssid', 'password', 3)
devices = broadlink.discover(timeout=5)
devices[0].auth()
devices[0].enter_learning()
devices[0].sweep_frequency()
print("learning")
while 1:
found = devices[0].check_frequency()
if found:
print('Found')
break
while 1:
found = devices[0].find_rf_packet()
if found:
print(devices[0].check_data())
@masarliev , try increasing your timeout to 120.
I got this timeout error also on the master branch, but after I increased it, the device was found.
If the device was already setup, and you know the IP and mac, you don't need to run discover.
Just create a device object by using:
dev = broadlink.gendevice(DEVICE_TYPE_HERE, ("DEVICE_IP_HERE",80), mac=bytearray.fromhex("DEVICE_MAC_HERE"))
You can get your device type from here:
https://github.com/mjg59/python-broadlink/blob/master/broadlink/__init__.py#L16
It's the devtype hex.
I don't have problem on device discovery. I don't receive the RF code
Something goes wrong... i've created a loop with "sweep freq (0x19)", sleep, "check freq (0x1a)" until 0x04 == 1 then find rf packet (0x1b) returns 0x04 == 1, but get learned data (0x22, 0x23) returns error...
btw in some cases i can receive rf codes, even if check_frequency is false. i didn't use sweep, find_rf_packet packets.....only learn
@brentavery Get rf scan learning working in CLI tool (#87) : I had this RF code learn method working in a Vera plugin I wrote, with an RM Pro (type 0x2787) and as of about early Feb 2018, it stopped working. I now always get (@laviua) learned data (0x22, 0x23) returns an error: where the error is always 0xfff6. Note then when doing an IR learn, the BroadLink device also returns the 0xfff6 error on get data, until it has an IR code to return.
Vera plugin: https://github.com/a-lurker/Vera-Plugin-BroadLink-Mk2/blob/master/Luup_device/L_BroadLink_Mk2_1.lua
So do BroadLink do OTA updates automatically or do you have to manually update its firmware (note I don't use e_Control)? Maybe the firmware has changed? Is there a command to retrieve the firmware version information?
It's worthwhile running the RF code learn method without clicking on any RF remote control button. In my case I get the command: "check freq (0x1a)"; 0x04 == 0x04 when it gives up looking for a RF remote command. That is, when the LED goes out. So I interpret this as "Given up on getting an RF code"
Also using the RF code learn method without clicking on any RF remote control button, I sometimes get spurious: check freq (0x1a)"; 0x04 == 0x01 indicating an RF frequency was found. It's perhaps possible the BroadLink device is picking up misc signals from around the local environment?
It also seems strange that the protocol requires a stop RF learn method when the actual device either times out (LED goes out) with no code found or stops immediately it determines a code (LED goes out). Regardless that's maybe just how its programmed.
I can confirm that the test code from @masarliev works perfectly to pick up the RF remote for my electric gate (which requires sweep mode). Naturally you need to use the code on the https://github.com/mjg59/python-broadlink/tree/rf_experiment branch.
Hooked it up to the Google assistant (My code is all Python 3), I can now open the gate using voice control when half a mile away ('Open Sesame!'). By the time I drive up it is fully opened.
Saves me from reaching out to the RF remote and wait till I am in range. Saves me a good 10 - 15 seconds a day :smiley:
Is this change expected to be merged and packaged up any time soon?
The code from @masarliev didn't work for me.... but I got it to work with my AC114-01B RF transmitter for my projection screen, as follows:
(I have to say that this is the first time I've used Python, so maybe its an issue of code versions, and I also can't figure out strings and bytearrays yet :-( ).
Two points:
if payload[0x04] == 1:
return True
which never triggers. I replaced it with
bb = bytearray(payload)
if bb[4] == 1 :
return True
and that works for me.
So it looks like this:
rm_sweep_frequency() # LED will be red
check_frequency() # call until true (see #1), 1 sec intervals, requires 5-10 RF button clicks
# frequency is now found, and LED turns off
find_rf_packet() # call only once, LED will turn on (just like with IR enter_learning())
check_data() # call until result is not empty, usually requires only 1-2 RF button clicks
# LED will turn off, and data can be used for send_data()
I can share the code if somebody would like it...
My request: I have this on my Pi, and now I'd like to trigger it with Alexa...
Thanks, that looks like enough detail for me to implement this.
okaapi - this looks good but I'm wondering how does one detect when no frequency is found or no button is pushed after a frequency is found. And what to do at those points.
@a-lurker -
1 - when no frequency is found:
You are in a loop with check_frequency(), and you can obviously break after so many seconds. Also, the infamous \x04 position (which goes to 1 when a frequency is found) is set to 4 after 20 seconds or so, that may be a timeout. I changed my check_frequency() to return \x04 - 0, 1, or 4.
2 - if no button is pushed after the frequency is found: At this point you're in a loop with check_data(), and you can break after, say, 10 seconds.
In both cases, the LED is still red and to get the device out of that state, cancel_learning() to the rescue!!!
def cancel_learning(self):
packet = bytearray(16)
packet[0] = 0x1e;
self.send_packet(0x6a, packet)
(I found the 0x1e command in this code https://github.com/lprhodes/broadlinkjs-rm/blob/master/index.js thank you @lprhodes )
Here's my code... rf_experiment.txt broadlink.txt
Regarding Alexa. I have the RM send_data() in a web server on the Pi which responds to simple GET commands to read the codes and send them to the rm. In parallel I have fauxmo talking to Alexa, and sending Get commands to the webserver (https://github.com/makermusings/fauxmo). It all works great for now!
I was able to successfully read RF code using provided branch rf-experiment
using python 3 (did not testest on python 2) with the following code snippet (edited version of @okaapi rf_experiment.txt):
import broadlink
import time
device = broadlink.rm(host=("192.168.1.100", 80), mac=bytearray.fromhex("3333333333"))
device.auth()
device.sweep_frequency()
print("sweeping...; LED should be RED")
i = 0
while True:
f = device.check_frequency()
if not (f == 0):
break
i = i + 1
time.sleep(1)
print("check frequency... ", i)
if f == 1:
print("frequency found! check LED, should be off")
else:
device.cancel_learning()
print("frequency not found... ")
exit()
time.sleep(1)
print("learning command")
device.find_rf_packet()
i = 0
while True:
data = device.check_data()
if data:
break
elif i > 10:
device.cancel_learning()
print("command not learned")
exit()
i = i + 1
time.sleep(1)
print("check command... ", i)
print("command learned")
encodedData = ''.join(format(x, '02x') for x in bytearray(data))
print(encodedData)
fname = "learn_code.txt"
text_file = open(fname, "w")
text_file.write(encodedData)
text_file.close()
execute RF code which has been written to learn_code.txt
:
#!/usr/bin/python
import broadlink
device = broadlink.rm(host=("192.168.1.100", 80), mac=bytearray.fromhex("3333333333"))
device.auth()
file = open("./learn_code.txt", 'r')
myhex = file.read()
print(myhex)
print(bytearray.fromhex(myhex))
device.send_data(bytearray.fromhex(myhex))
I can share the code if somebody would like it... My request: I have this on my Pi, and now I'd like to trigger it with Alexa... [experiment.txt](https://github.com/mjg59/python-broadlink/files/2186468/experiment.txt)
Hi @okaapi is it possible to share the codes for this remote? I have been struggling for a while now to get working codes. Thanks in advance
Hey madrose,
I can send it no problem, but you might be better off starting with @sprilukin (just one or two posts up) - I have not checked his stuff yet, but it seems to work, and I'll replace my local version with his also so we're all in sync soon :-)
If that doesn't work - or you insist! - I'll send you my files.
Hey madrose,
I can send it no problem, but you might be better off starting with @sprilukin (just one or two posts up) - I have not checked his stuff yet, but it seems to work, and I'll replace my local version with his also so we're all in sync soon :-)
If that doesn't work - or you insist! - I'll send you my files.
Actually I got @sprilukin version to work, and I got some code from my RM. Thanks, but I am wondering how can I convert those codes to something I can use in Home Assistant. I believe that is base64 code (not sure ??)
Hi... congrats for getting the RM stuff working. I am not familiar with Home Assistant. I combined the RM code with a some other code that lets me control it via Alexa.
On Tue, Dec 4, 2018 at 1:35 PM madrose notifications@github.com wrote:
Hey madrose,
I can send it no problem, but you might be better off starting with @sprilukin https://github.com/sprilukin (just one or two posts up) - I have not checked his stuff yet, but it seems to work, and I'll replace my local version with his also so we're all in sync soon :-)
If that doesn't work - or you insist! - I'll send you my files.
Actually I got @sprilukin https://github.com/sprilukin version to work, and I got some code from my RM. Thanks, but I am wondering how can I convert those codes to something I can use in Home Assistant. I believe that is base64 code (not sure ??)
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/mjg59/python-broadlink/issues/87#issuecomment-444267336, or mute the thread https://github.com/notifications/unsubscribe-auth/ABkSF7ETmRiYkJiFMpW1GWnx6Sy8871oks5u1uqRgaJpZM4NK_Da .
This looks like it has the potential to solve the massive headaches I have been encountering trying to learn RF codes for my RM Pro Plus 3. I am a little unclear on the status of this. These fixes haven't been integrated into the code yet? Is there a low pain way to try out the feature?
@rwa, in order to try out you can check out my test branch (steps are for linux and pip):
$ sudo apt-get install python-setuptools python-dev
pycrypto
: $ sudo pip install pycrypto
git clone git@github.com:sprilukin/python-broadlink.git
cd python-broadlink
git checkout -b rf_experiment_v0.9 origin/rf_experiment_v0.9
cd python-broadlink
python3 setup.py sdist
sudo pip3 install .
python-broadlink/cli/broadlink_cli --device @<path-to-file-with-device-settings> --rfscanlearn --learnfile <path-to-file/filename>
python-broadlink/cli/broadlink_cli --device @<path-to-file-with-device-settings> --send @<path-to-file/filename>
It worked! Not well, I had to learn the code 6 times and got a different one every single time, but one of them did work.
This really should get into a release asap.
hi @sprilukin ;
I tried the above method and I am receiving this:
Learning...
No data received...
Traceback (most recent call last):
File "./broadlink_cli", line 186, in
edit: i am using a rm pro plus 3
I'm sorry, not sure how I can help. I just needed that stuff to work, so I digged into the code and was in the context 4 months ago. Now I completely forgot how it works ) I do not have that environment set up to check.
Traceback (most recent call last):
File "C:/Users/medy1/PycharmProjects/broadlink/RFFINALSEND.py", line 32, in <module>
ir_packet = devices[0].check_data()
File "C:\Users\medy1\PycharmProjects\untitled1\venv\lib\site-packages\broadlink\__init__.py", line 631, in check_data
check_error(response[0x22:0x24])
File "C:\Users\medy1\PycharmProjects\untitled1\venv\lib\site-packages\broadlink\exceptions.py", line 97, in check_error
raise exception(error_code)
broadlink.exceptions.ReadError: Read error
when running the script from @sprilukin
using a broadlink pro plus_300
and the master branch
then switching out check data method to the one from the rf_experiment branch
made things work gg
def check_data(self):
packet = bytearray(16)
packet[0] = 4
response = self.send_packet(0x6a, packet)
err = response[0x22] | (response[0x23] << 8)
if err == 0:
payload = self.decrypt(bytes(response[0x38:]))
return payload[0x04:]
Hi @mjg59
I have the full details on what happens when you press "Sweep Frequency" now.
These payloads are all sent with 0x6a commands.
Start Sweep Frequency: 0x19
Check for found frequency part 1 (repeat once per second): 0x1a Wait for 0x01 as position 0x04 response: 0x1a000000010000000000000000000000
Check for found frequency part 2 (repeat once every second): 0x1b Wait for 0x01 as position 0x04 response: 0x1b000000010000000000000000000000
Use the standard check data (release once per second): 0x04 Wait for hex code response as you would on the normal check data