We use a 433MHz wireless switch to control the PC

Hi, Geektimes Habr.

I’ve got a bunch of 433 MHz wireless switches in my home, and I wondered if they could be used for any tasks, such as controlling a computer or integrating into a smart home system.

These switches are convenient for their low cost and stable operation, they look like this:



How it works, and what can be done with them (hussars to be silent :), details under the cut.

Theory


I will say right away how such a switch works, I don’t know, although I guess about it. So you need to do a little reverse engineering.

First of all, the signal must be received, for which we use the already well-known RTL-SDR receiver for many, often called simply a “whistle” for radio amateurs. This device costing only $ 10 allows you to receive radio signals in the range from about 50 to 1250 MHz, for us what we need. The topic is old, but if someone has not read it, read it .

We make the first step of the analysis - carefully look at the switch. We find out that the back of the case says “Made in China” (who would have thought?) And, more importantly, the frequency 433 MHz. Now you can connect the SDR receiver, run the SDR # and make sure that the data is actually transmitted.



The symmetry of the signal on the spectrum suggests the presence of AM modulation. By the way, a weaker “alien” signal is visible on the right — they can also be received and decoded, and we’ll tell you more about them separately. But back to the signal. We write it in the usual WAV format and press the buttons on the remote control - for example, I pressed the ON and OFF buttons on channel “1”.

Open the sound file in any audio editor, and use the other professional analytics tool, Paint, to compare the signals. We place 2 signals from different buttons one above the other to see the difference:



It is easy to see that we have the usual bit sequence, the difference in which is just one bit corresponding to the ON or OFF button. While the button is pressed, the switch simply cycles through this sequence at a rate of 20 times per second. Cheap and easy, even if one sequence is distorted during transmission, the other will be accepted.

From this, by the way, one important conclusion can be made - the signals of such switches (talking about cheap models) are transmitted on the air “as is”, without any authentication, protection or encryption. Such a switch or a wireless socket with such a switch should not be used for some important functions, for example, to turn on powerful heaters or even more so to open the front door or garage. The point here is not even in hackers (the chance that someone will break into my house wirelessly, I estimate less than the chance of falling on my ISS house), but the fact that a neighbor may accidentally buy the same switch and their codes can match ( however on the switch there is a choice between 4 channels). In my experience of using, 2-3 times a year, the switch did turn on “itself”, or an interference, or a distant signal from the same model was actually received.

Of course, this does not apply to more complex systems, such as Lora or Philips Hue, there is nothing wrong with encryption.

However, back to our problem. You can write a decoder of such signals yourself, but fortunately, this has already been done before us, in a project called “rtl_433”. Initially, the program was created for Linux, the Windows version can be downloaded from the Linux version; it can be downloaded from GitHub .

Run the program from the command line: "rtl_433.exe -F json"



We received the data, it remains to write a program to process them.

Raspberry pi


The first thing that is interesting to consider is the Raspberry Pi. To install rtl_433 on Raspbian, unpack the archive and execute the following commands.

sudo apt-get install libtool libusb-1.0.0-dev librtlsdr-dev rtl-sdr build-essential autoconf cmake pkg-config cd rtl_433/ autoreconf --install ./configure make make install 

The second step is to write a program that will receive this data and, depending on it, perform the necessary actions. The Python code is quite simple:

 from __future__ import print_function import os, sys, io import json import subprocess print("RTLSDR listening started") transmitter_name = "Waveman Switch Transmitter" transmitter_channel = 1 proc = subprocess.Popen(["rtl_433 -F json"], stdout=subprocess.PIPE, shell=True) while True: try: line = proc.stdout.readline().encode('ascii','ignore') proc.poll() data = json.loads(line) print(data) m,st,ch,btn= data['model'],data['state'],data['channel'],data['button'] if m==transmitter_name and ch==transmitter_channel and btn==1 and st=='on': print("ON") elif m==transmitter_name and ch==transmitter_channel and btn==1 and st=='off': print("OFF") except KeyboardInterrupt: break except: pass print("RTLSDR listening done") 

To run the code, you need to save it in a file (for example, rtl_listen.py) and run it with the command “python rtl_listen.py”.

As you can see, the program starts the process using subprocess.Popen and reads data from it. Then everything is simple, the code is quite readable, and it will not be difficult to make changes. In this example, when you press the “1” button, a print (“ON”) message is displayed, you can instead do something else, for example, activate the GPIO pin, turn on the relay, send data to the server, etc. Before using, you will need to change name transmitter_name for the name of the console model to be used.

By the way, the RTL-SDR receiver itself, compared to the Raspberry Pi, looks like this:



Windows


Unfortunately, under Windows 10, the above code did not work. But as prompted by a search on github, asynchronous reading of data from a separate stream works. Why so, it was too lazy to find out, just give the working code under the spoiler.

Source
 from __future__ import print_function import os, sys import subprocess import time import threading import Queue import json class AsynchronousFileReader(threading.Thread): # Helper class to implement asynchronous reading def __init__(self, fd, queue): assert isinstance(queue, Queue.Queue) assert callable(fd.readline) threading.Thread.__init__(self) self._fd = fd self._queue = queue def run(self): # The body of the tread: read lines and put them on the queue. for line in iter(self._fd.readline, ''): self._queue.put(line) def eof(self): # Check whether there is no more content to expect return not self.is_alive() and self._queue.empty() def replace(string): while ' ' in string: string = string.replace(' ', ' ') return string def read_rtl_data(): process = subprocess.Popen(["rtl_433.exe", "-F", "json"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Launch the asynchronous readers of stdout and stderr. stdout_queue = Queue.Queue() stdout_reader = AsynchronousFileReader(process.stdout, stdout_queue) stdout_reader.start() stderr_queue = Queue.Queue() stderr_reader = AsynchronousFileReader(process.stderr, stderr_queue) stderr_reader.start() transmitter_name = "Waveman Switch Transmitter" transmitter_channel = 1 # Check the queues if we received some output while not stdout_reader.eof() or not stderr_reader.eof(): # Show what we received from standard output. while not stdout_queue.empty(): line = stdout_queue.get() print("Line1:", repr(line)) data = json.loads(line) # print("Data:", repr(line)) m,st,ch,btn= data['model'],data['state'],data['channel'],data['button'] if m==transmitter_name and ch==transmitter_channel and btn==1 and st=='on': print("ON") elif m==transmitter_name and ch==transmitter_channel and btn==1 and st=='off': print("OFF") # Show what we received from standard error. while not stderr_queue.empty(): line = replace(stderr_queue.get()) print("Line2:", line) # Sleep a bit before asking the readers again. time.sleep(0.1) stdout_reader.join() stderr_reader.join() # Close subprocess' file descriptors. process.stdout.close() process.stderr.close() if __name__ == '__main__': print("RTLSDR listening started") read_rtl_data() print("RTLSDR listening done") 


With this code, we can use any actions in the handler, the logic is the same as in the code on Raspberry Pi.

Example : let's say we have a computer dedicated to home theater, and we want to turn it off by pressing a button from the remote. Replace the 'print ("OFF")' code with

  os.system('shutdown -s') sys.exit(0) 

After that, the computer will turn off by pressing the corresponding button. Of course, in addition to “shutdown -s” you can use any other Windows command, you just have to take into account that the commands will be sent repeatedly, while the remote control button is pressed, in order to avoid such duplication, you need to improve the code.

Conclusion


As you can see, everything is pretty simple, and there is a place for experimentation. Finally, a small bonus for those who read to here. At 433 MHz, a large number of different devices work that rtl_433 can decode, you can just leave the program running for several hours and see what it gets. Under the spoiler an example of such a log, recorded earlier:

Log
2018-01-10 21:15:17 : Prologue sensor : 5 : 15
Channel: 1
Battery: OK
Button: 0
Temperature: 6.00 C
Humidity: 11 %

2018-01-10 21:15:28 : inFactory sensor
ID: 71
Temperature: 6.67 °C
Humidity: 99 %

2018-01-10 21:16:07 : Toyota : TPMS : 61511475 : 60e5006b : CRC

2018-01-10 21:20:33 : Prologue sensor : 5 : 15
Channel: 1
Battery: OK
Button: 0
Temperature: 6.00 C
Humidity: 11 %
: Waveman Switch Transmitter
id: A
channel: 2
button: 1
state: on
: Waveman Switch Transmitter
id: A
channel: 2
button: 1
state: on
: Waveman Switch Transmitter
id: A
channel: 2
button: 1
state: on

2018-01-10 21:21:21 : Akhan 100F14 remote keyless entry
ID (20bit): 0x41
Data (4bit): 0x4 (Mute)
: Waveman Switch Transmitter
id: A
channel: 2
button: 1
state: off

2018-01-10 21:32:31 : Ford : TPMS : 00268b1f : a34a0e : CHECKSUM
2018-01-10 21:32:32 : Ford : TPMS : 00268a5c : 9c440e : CHECKSUM
2018-01-10 21:32:37 : Ford : TPMS : 016dbfce : 99430e : CHECKSUM
2018-01-10 21:32:39 : Ford : TPMS : 002671a0 : 9c4a0e : CHECKSUM


There is some interesting data, such as tire pressure at a neighbor's car (TPMS, tire-pressure monitoring monitoring system), or an external temperature of +6 from someone’s sensor. This allows, for example, to display the outside temperature if the neighbors accidentally have a weather station compatible with this protocol.

All successful experiments.

Disclaimer : Obviously, using SDR and digital processing to read OOK modulation signals is essentially gun shooting at sparrows. Perhaps there are ready $ 1-2 receivers on aliexpress that do the same thing, with a lower price and less power consumption. If anyone knows such models, write in the comments.

Source: https://habr.com/ru/post/414285/


All Articles