Skip to content

Commit e3db7da

Browse files
authored
Merge pull request #1 from hasenradball/develop
Merge initial Version to main branch
2 parents 70d894f + 0baec02 commit e3db7da

14 files changed

Lines changed: 411 additions & 0 deletions

Readme.md

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
# rcSwitch-python
2+
3+
rcSwitch-python is a python based script to switch remote controlled sockets via 433 MHz.
4+
5+
This script is based on the following libraries:
6+
- rpi-rf
7+
- RPI.GPPIO
8+
9+
## Necessary Hardware
10+
- Raspberry Pi or any other board having digital GPIO</br>
11+
<img src="pics/pi4.jpg" alt="Pi4" width="300"/>
12+
13+
- 433 MHz transmitter (for sending -> send device)</br>
14+
<img src="pics/433_MHz_device.jpg" alt="433Device" width="300"/>
15+
16+
- 433 MHz controlled power socket, e.g. Brennenstuhl RCS 1000 N</br>
17+
<img src="pics/Brennenstuhl_RCS1000N.jpg" alt="RCS1000N" width="300"/>
18+
19+
---
20+
## Setting up the Hardware
21+
- Connect the `VCC-Pin` of the 433 MHz transmitter to any 5 V output pin of your board.</br>
22+
- The `GND-Pin` to a ground pin.</br>
23+
- And the `ATAD-Pin` or `Data-Pin` to any `GPIO` pin.</br>
24+
<img src="pics/433MHz_Sender.png" alt="Sender" width="300"/></br>
25+
In this example, GPIO 17 is used.
26+
27+
It is recommened to connect a (long) cable to the ANT pin of the 433 Mhz transmitter - this extends the range of the sender.
28+
29+
### Setup the Socket Device
30+
To define the relevant Codes you have to set the dip switches in the socket.
31+
See picture below:</br>
32+
<img src="pics/RCS1000N_switches.jpg" alt="Switches" width="300"/>
33+
34+
---
35+
## Installation
36+
### 1.) Installation of this Library
37+
>Lets assume you want to install the library in the following path on you Pi:</br>/usr/local/bin/python/rcSwitch-python
38+
39+
To install this library there you need to run the following commands:
40+
41+
Create the dir `python`:
42+
```
43+
cd /usr/local/bin
44+
sudo mkdir python
45+
cd python
46+
```
47+
Then install the library:
48+
49+
```
50+
git clone https://github.com/hasenradball/rcSwitch-python.git
51+
cd rcSwitch-python
52+
git checkout develop
53+
```
54+
---
55+
### 2.) Installation of dependencies
56+
Make sure that you have the latest packages on the Pi.
57+
58+
Do an update:
59+
```
60+
sudo apt update
61+
sudo apt upgrade
62+
```
63+
Also make sure that you have installed the `rpi-rf` library.
64+
65+
```
66+
python3 -m pip install rpi-rf
67+
```
68+
Optional:
69+
70+
- to be sure that the library is also available for `root` user, do this:
71+
72+
```
73+
sudo -i
74+
python3 -m pip install rpi-rf
75+
exit
76+
```
77+
Then you should make sure that the current `user` is in the `group` of the the `gpio` users.
78+
79+
```
80+
sudo usermod -a -G gpio $USER
81+
```
82+
If you have dose this steps, then you should be able to switch the sockets now.
83+
84+
---
85+
## Usage
86+
To Switch the socket you can do this for example via `cli` like:
87+
88+
```
89+
# make sure you are in the folder of the repo
90+
cd /usr/local/bin/python/rcSwitch-python
91+
92+
python3 ./switchSocket.py <SystemCode> <ButtonCode> <status>
93+
```
94+
This could look like this, if we assume the following codes:</br>
95+
SystemCode = 10000, ButtonCode = 10000, status = 1
96+
97+
```
98+
# using the Button Letter
99+
python3 ./switchSocket.py 10000 A 1
100+
```
101+
or this way:
102+
103+
```
104+
# usinf the integer ButtonCode
105+
python3 ./switchSocket.py 10000 16 1
106+
```
107+
or just like this way:
108+
109+
```
110+
# using the binary ButtonCode
111+
python3 ./switchSocket.py 10000 10000 1
112+
```
113+
114+
Where the following correlations for the `ButtonCode` can be described:
115+
116+
|Letter|int|binary|
117+
|------|---|------|
118+
| A / a| 16| 10000|
119+
| B / b| 8| 01000|
120+
| C / c| 4| 00100|
121+
| D / d| 2| 00010|
122+
| E / e| 1| 00001|
123+
124+
125+
---
126+
## Further informations
127+
---
128+
### Troubleshooting
129+
If you get an Error like:</br>
130+
>RuntimeError: No access to /dev/mem. Try running as root!
131+
132+
The user does not belong to the Group of `gpio`.
133+
Try to run with `sudo`.
134+
135+
---
136+
If you want to increase the range of the sender device, there are two possibilities to to that:</br>
137+
138+
- instead of 5 V at `VCC-Pin` you can set up to 12 V to the `VCC-Pin`</br>
139+
- use a long cable instead of the antenna
140+
---
141+
142+
143+
### Rasperry Pi GPIO Pins
144+
</br>
145+
<img src="pics/pi_gpios.png" alt="GPIOs" width="300"/>
146+
147+
---
148+
### Links
149+
For discussions see:</br>
150+
https://knx-user-forum.de/forum/supportforen/smarthome-py/39094-logic-und-howto-für-433mhz-steckdosen
151+
152+
---
153+
## Changelog
154+
155+
### v0.1
156+
* initial version
5.94 MB
Binary file not shown.

cRcSocketSwitch/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/python3
2+
# -*- coding: utf-8 -*-
3+
4+
from .cRcSocketSwitch import RCS1000N

cRcSocketSwitch/cRcSocketSwitch.py

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#!/usr/bin/python3
2+
# -*- coding: utf-8 -*-
3+
4+
from rpi_rf import RFDevice
5+
import logging
6+
7+
class RCS1000N:
8+
'''
9+
class for switching remote socket devices as:
10+
Brennenstuhl RCS 1000 N
11+
I calculated the corresponding send code in decimal value
12+
and uses the library rpi-rf to send the command via 433 MHz send device
13+
'''
14+
15+
def __init__(self, gpio_pin = 17):
16+
'''
17+
Constructor for GPIO Pin and Configuration
18+
'''
19+
self.gpio = gpio_pin
20+
self.config = {'code': None, 'tx_proto': 1, 'tx_pulselength': 320, 'tx_length': 24}
21+
logging.info("Brennenstuhl RCS1000 N object created with GPIO pin {}".format(self.gpio))
22+
23+
def prepareCodes(self, SystemCode_raw, ButtonCode_raw, status):
24+
'''
25+
this method prepares the codes and checks the imput format in case
26+
of different usecases
27+
'''
28+
button_list = ['a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'e', 'E']
29+
button_mapping = {'A':16, 'B':8, 'C':4, 'D':2, 'E':1}
30+
# check if the input for the ButtonCode is in the Case 'A', 'B', etc...
31+
if ButtonCode_raw in button_list:
32+
ButtonCode_raw = ButtonCode_raw.upper()
33+
ButtonCode = button_mapping[ButtonCode_raw]
34+
ButtonCode = '{:05b}'.format(ButtonCode)
35+
logging.info("Buttoncode: {}\n".format(ButtonCode))
36+
37+
# check if the ButtonCode is an integer like 1, 2, 3, etc...
38+
elif isinstance(ButtonCode_raw, int):
39+
logging.info("ButtonCode_raw is of type int")
40+
ButtonCode = '{:05b}'.format(ButtonCode_raw)
41+
logging.info("Buttoncode: {}\n".format(ButtonCode))
42+
43+
# assume the code is in the way '01000' check the length (5)
44+
elif isinstance(ButtonCode_raw, str):
45+
logging.info("ButtonCode_raw is of type str")
46+
# check length of 5
47+
if len(ButtonCode_raw) == 5:
48+
ButtonCode = ButtonCode_raw
49+
logging.info("Buttoncode: {} - {}\n".format(ButtonCode, type(ButtonCode)))
50+
else:
51+
ButtonCode = None
52+
logging.error("ERROR: wrong len of ButtonCode_raw!")
53+
54+
# check now the lenght of the SystemCode
55+
if len(SystemCode_raw) == 5:
56+
SystemCode = SystemCode_raw
57+
logging.info("SystemCode: {} - {}\n".format(SystemCode, type(SystemCode)))
58+
else:
59+
SystemCode = None
60+
logging.error("ERROR: wrong len of SystemCode_raw!")
61+
62+
# check the status
63+
if isinstance(status, bool):
64+
if status:
65+
status = 1
66+
else:
67+
status = 0
68+
return (SystemCode, ButtonCode, status)
69+
70+
71+
def calcTristateCode(self, SystemCode, ButtonCode, status):
72+
'''
73+
calculate the corresponding Tristate Code in the same way as the library
74+
wiringPi does it in c-code
75+
return value is the TriState String Code
76+
'''
77+
code = ""
78+
for c in SystemCode:
79+
if c == '0':
80+
code += 'F'
81+
else:
82+
code += '0'
83+
84+
for c in ButtonCode:
85+
if c == '0':
86+
code += 'F'
87+
else:
88+
code += '0'
89+
90+
if status:
91+
code += '0F'
92+
else:
93+
code += 'F0'
94+
return code
95+
96+
97+
def calcBinaryCode(self, strCode):
98+
'''
99+
calculate the Binary Code of the switch command in the same way as th library
100+
wiringPi does it in c-code
101+
return value is then a decimal value of the switch command
102+
'''
103+
code = 0
104+
len = 0
105+
for c in strCode:
106+
code <<= 2
107+
#print(c, type(c))
108+
#print(bin(code))
109+
if c == '0':
110+
# bit pattern 00
111+
pass
112+
elif c == 'F':
113+
# bit pattern 01
114+
code += 1
115+
elif c =='1':
116+
# bit pattern 11
117+
code += 3
118+
len += 2
119+
logging.info("Length of code: {}\n".format(len))
120+
logging.info("code: {}\n".format(int(code)))
121+
return code
122+
123+
124+
def calc_DecimalCode_python_style(self, SystemCode, ButtonCode, status):
125+
'''
126+
calculate the decimal Code in a python style
127+
this combines the methods:
128+
calcTristateCode + calcBinaryCode in on step
129+
'''
130+
code = str(SystemCode + ButtonCode)
131+
help = code.replace('0', 'F').replace('1', '0')
132+
if status:
133+
help += '0F'
134+
else:
135+
help += 'F0'
136+
logging.info("Py - TriState code: {}\n".format(help))
137+
code = help.replace('0','00').replace('F', '01')
138+
binstr = '0b' + code
139+
logging.info("binary string: {}\n".format(binstr))
140+
return int(binstr, 2)
141+
142+
def send(self, systemCode, btn_code, status):
143+
'''
144+
Method to prepare the codes and send it to the actuator
145+
'''
146+
try:
147+
rfdevice = RFDevice(self.gpio)
148+
rfdevice.enable_tx()
149+
rfdevice.tx_repeat = 10
150+
values = self.prepareCodes(systemCode, btn_code, status)
151+
send_code = self.calc_DecimalCode_python_style(*values)
152+
self.config['code'] = send_code
153+
rfdevice.tx_code(**self.config)
154+
155+
finally:
156+
rfdevice.cleanup()

pics/433MHz_Sender.png

3.16 MB
Loading

pics/433_MHz_device.jpg

18.8 KB
Loading

pics/Brennenstuhl_RCS1000N.jpg

22.8 KB
Loading

pics/RCS1000N_switches.jpg

88.2 KB
Loading

pics/RCS1000N_switches.png

58.9 KB
Loading

pics/pi4.jpg

144 KB
Loading

0 commit comments

Comments
 (0)