-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3a85d18
commit 3948cc1
Showing
21 changed files
with
1,444 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
dev_* | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#!/bin/bash | ||
# RX INSTALL | ||
port=$1 | ||
echo "+-------------- Installing RX via ${port} --------------+" | ||
# Get all existing files | ||
files=$(mpremote connect "$port" ls | grep '.py') | ||
echo "$files" | ||
|
||
# Remove all files | ||
while IFS= read -r file || [[ -n $file ]]; do | ||
fileCut=$(echo "$file" | grep -oP '(?<=\S\s).*') | ||
fileCut=${fileCut//[$'\n\r']/} | ||
echo "$(mpremote connect "$port" rm "$fileCut")" | ||
done < <(printf '%s' "$files") | ||
|
||
# Copy files | ||
cd src/rx | ||
echo "$(mpremote connect "$port" cp main.py :main.py)" | ||
echo "$(mpremote connect "$port" cp rx_config.py :rx_config.py)" | ||
|
||
# Start shell | ||
echo "DONE!" | ||
echo "+-------------- Executing RX script on the µC --------------+" | ||
mpremote connect ${port} reset | ||
mpremote connect ${port} repl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#!/bin/bash | ||
# TX INSTALL | ||
port=$1 | ||
echo "+-------------- Installing TX via ${port} --------------+" | ||
# Get all existing files | ||
files=$(mpremote connect "$port" ls | grep '.py') | ||
echo "$files" | ||
|
||
# Remove all files | ||
while IFS= read -r file || [[ -n $file ]]; do | ||
fileCut=$(echo "$file" | grep -oP '(?<=\S\s).*') | ||
fileCut=${fileCut//[$'\n\r']/} | ||
echo "$(mpremote connect "$port" rm "$fileCut")" | ||
done < <(printf '%s' "$files") | ||
|
||
# Copy files | ||
cd src/tx | ||
echo "$(mpremote connect "$port" cp boot.py :boot.py)" | ||
echo "$(mpremote connect "$port" cp main.py :main.py)" | ||
echo "$(mpremote connect "$port" cp tx_config.py :tx_config.py)" | ||
echo "$(mpremote connect "$port" cp fernotron.py :fernotron.py)" | ||
echo "$(mpremote connect "$port" cp nanoweb.py :nanoweb.py)" | ||
assetsPath="assets" | ||
echo "$(mpremote connect "$port" mkdir "$assetsPath")" | ||
echo "$(mpremote connect "$port" cp "$assetsPath"/index.html :"$assetsPath"/index.html)" | ||
echo "$(mpremote connect "$port" cp "$assetsPath"/style.css :"$assetsPath"/style.css)" | ||
echo "$(mpremote connect "$port" cp "$assetsPath"/remote.js :"$assetsPath"/remote.js)" | ||
|
||
# Start shell | ||
echo "DONE!" | ||
echo "+-------------- Starting FernoPy (You can exit the shell now if you want) --------------+" | ||
mpremote connect ${port} reset | ||
mpremote connect ${port} repl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
|
||
|
||
# Protocol documentation (work in progress) | ||
|
||
## Properties | ||
|
||
| Property | Value | | ||
| ----------------------------- | ----------------- | | ||
| Product name | FernoTron | | ||
| Frequency | 433,92 MHz | | ||
| Modulation | ASK (OOK) | | ||
| Bit length | 400µs | | ||
| Bits per symbol | 3 or 8 bits | | ||
| Pause between blocks | 3,2ms (8 bit) | | ||
| Pause between messages | ~ 60ms (148 bits) | | ||
| Encryption / Authentication | None | | ||
| Communication characteristics | Unidirectional | | ||
|
||
## General functionality | ||
|
||
|
||
|
||
|
||
|
||
## Physical layer | ||
|
||
The basic characteristics of the signal can be found in the properties table. The beginning of each message is introduced by a preamble. It is a 12 bit long repeating sequence of 1 and 0. After the preamble 12 blocks follow which are interrupted by pauses. A block is 30 bit (12ms) long and ends with a pause of 8 bit. | ||
*Figure [1]* shows the analog waveform of a FernoTron message: | ||
![](img/analog.png) | ||
|
||
*Figure [2]* shows the same message, except that it has already been demodulated. More precisely, the restored digital signal is shown here, which includes the appropriate information of the message in binary form. | ||
![](img/digital.png) | ||
|
||
Note that these bits do not directly correspond to the actual transmitted data! Multiple bits correspond to a single symbol. In total there are 3 different symbols as shown in the table and figure below. The symbols represent the actual information of the message. Since a block is 30 bits long, 10 symbols (actual data bits) can be transmitted per block. This means that 120 symbols (data bits) are transmitted per message. | ||
|
||
| Bits | Symbol | | ||
| -------- | ------ | | ||
| 100 | 1 | | ||
| 110 | 0 | | ||
| 10000000 | Pause | | ||
|
||
*Figure [3]* shows the conversion from bits to symbols of a message block. Orange represents the symbol *0* and blue the symbol *1*. Green shows the *Pause* symbol between the individual blocks. | ||
|
||
![](img/bits-symbols.png) | ||
|
||
## Logic / Application layer | ||
|
||
|
||
|
||
Pressing a button on the original FernoTron remote control briefly transmits two messages. If the button is held down, messages are transmitted continuously. | ||
|
||
|
||
|
||
## Application layer | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,245 @@ | ||
# FernoPy | ||
<p align="center"> | ||
<img alt="FernoPy Logo" src="img/logo.png" style="zoom: 33%;" /> | ||
</p> | ||
<h1 align="center">FernoPy</h1> | ||
|
||
**FernoPy** enables the control of Rademacher FernoTron devices (shutters) conveniently via a web interface and REST-API. | ||
|
||
## Features | ||
|
||
- Responsive web interface | ||
- REST-API | ||
- Unlimited number of devices | ||
- The fernotron remote control can be used alongside FernoPy | ||
- Quick and easy to set up | ||
- Cheap (total cost of only about 10€) | ||
- ESP32 / ESP8266 support | ||
- Written in MicroPython | ||
- **[Protocol documentation](PROTOCOL.md)** | ||
|
||
> :information_source: Only the basic control of devices is supported (up / down / stop). If you want to program devices please use: [tronferno-mcu](https://github.com/zwiebert/tronferno-mcu) | ||
## Overview | ||
|
||
![](img/interface-device.png) | ||
|
||
The web interface is provided directly via the web server of the ESP. The design and functionality of the interface is based on the original FernoTron remote control. | ||
|
||
- The upper left button switches between light and dark mode (*dark mode is not yet implemented*) | ||
- The upper right button is used to switch between multiple remote controls. You can configure as many remote controls as you like, allowing you to control an unlimited number of devices via FernoPy. However, the maximum number of groups and participants per remote control still exist in FernoPy (7 groups with 7 devices each). | ||
- The left two buttons control the group number and the right ones the device number (**also called member**). Each group and device can be assigned a name. | ||
- The lower three buttons are used to control the shutters. | ||
|
||
### REST-API | ||
|
||
Using the REST API, you can easily integrate FernoPy with other programs. You can also control the shutters via central smart home systems such as Home Assistant, ioBroker or openHAB. | ||
|
||
#### `/api/config` | ||
|
||
Using the GET method, you can query all the available remote controls with their groups and the respective devices. More specifically, the data of the *fernotron* dictionary in the *tx_config.py* file is returned (without the device types and id). | ||
```shell | ||
$ curl -X GET http://<YOUR_ESP_IP>/api/config | ||
{"remotes": [ | ||
[ | ||
{"name": "All", "members": ["All"]}, | ||
{'name': 'Living room', 'members': ['North', 'East', 'South', 'West']}, | ||
... | ||
], | ||
[ | ||
... | ||
], | ||
]} | ||
``` | ||
|
||
#### `/api/cmd` | ||
|
||
The individual devices can be controlled via POST method. Requests with the content-type `application/json` and `application/x-www-form-urlencoded` are supported. Group and member numbers 0-7, where 0 represents all. The available commands are up, down and stop. | ||
```shell | ||
# application/json | ||
$ curl -d '{"remote":0, "member":2, "group":5, "cmd":"down"}' -H "Content-Type: application/json" -X POST http://<YOUR_ESP_IP>/api/cmd | ||
|
||
# application/x-www-form-urlencoded | ||
$ curl -d 'remote=0&member=2&group=5&cmd="down"' -X POST http://<YOUR_ESP_IP>/api/cmd | ||
``` | ||
|
||
## Hardware requirements | ||
|
||
You only need an ESP32 / ESP8266 and a 433 MHz transmitter + receiver set. The functionality of FernoPy was tested with a Wemos D1 mini clone and the cheapest transmitter + receiver set from amazon. | ||
|
||
| Part | Amazon query | Cost | Specific type | Data sheet | | ||
| ------------------------------ | --------------------------------------------------- | ---- | ----------------------------- | ------------------------------------------------------------ | | ||
| 433 MHz receiver + transmitter | [DE](https://www.amazon.de/s?k=433+mhz+transmitter) | 2€ | XY-MK-5V / XD-RF-5V / FS1000A | [Archive](https://web.archive.org/web/20231016150458/https://www.mantech.co.za/datasheets/products/HFY-J18_HFY-FST.pdf) | | ||
| Wemos D1 mini (ESP8266) | [DE](https://www.amazon.de/s?k=wemos+d1+mini) | 4€ | - | [Archive](https://web.archive.org/web/20230316032550/https://www.wemos.cc/en/latest/d1/d1_mini.html) | | ||
|
||
When buying the transmitter + receiver set, there is something to consider: | ||
The transmitters in each set are basically the same and all work equally well. However, there are differences with the receivers. There are ones with a tunable inductor (small coil with a screw) and ones with a crystal oscillator (small metallic box). Receivers with a tunable inductor have a greater noise component, which makes it more difficult to receive a valid messages. However, testing has shown that these are sufficient for FernoPy, especially considering that the receiver is only needed once for the initial setup and not for normal operation. Receivers with a crystal oscillator (also called superheterodyne) can nevertheless simplify the initiation phase in some cases. | ||
|
||
## Installation (Linux) | ||
|
||
### 0. Flash MicroPython | ||
|
||
Before FernoPy can be installed, the MicroPython firmware must be flashed onto the micro controller. If MicroPython is already running on your micro controller you can skip this step. A more detailed tutorial can be found [here](https://docs.micropython.org/en/latest/esp8266/tutorial/intro.html). | ||
|
||
1. Install the [esptool](https://github.com/espressif/esptool/) CLI. | ||
|
||
```shell | ||
pip install esptool | ||
``` | ||
|
||
2. Download the appropriate firmware for the micro controller [here](https://micropython.org/download/). The file must be in binary format (.bin). | ||
|
||
3. Connect the micro controller to your PC. | ||
|
||
4. Now find out which device file is used to communicate with the micro controller. By default it should be `/dev/ttyUSB0`. Alternatively, you can also determine it via the command: `sudo dmesg | grep tty`. The output should look similar like this and give you information about the used file. | ||
|
||
```shell | ||
$ sudo dmesg | grep tty | ||
[435144.714226] usb 1-1: ch341-uart converter now attached to ttyUSB0 | ||
``` | ||
|
||
5. Erase the flash of the micro controller. | ||
|
||
```shell | ||
esptool.py --port /dev/ttyUSB0 erase_flash | ||
``` | ||
|
||
6. Flash the MicroPython firmware. | ||
|
||
```shell | ||
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect -fm dout 0 ESP8266_GENERIC-20231005-v1.21.0.bin | ||
``` | ||
|
||
Port and the name of the firmware should of course be changed by you as needed. | ||
|
||
### 1. Obtain the device ID | ||
|
||
#### 1.1 Prepare FernoPy | ||
|
||
1. Install the [mpremote](https://docs.micropython.org/en/latest/reference/mpremote.html) CLI. | ||
|
||
```shell | ||
pip install --user mpremote | ||
``` | ||
|
||
2. Clone the FernoPy repository. | ||
|
||
``` | ||
git clone https://github.com/prefixFelix/fernopy.git | ||
``` | ||
|
||
3. Connect the micro controller to your PC. | ||
|
||
4. Verify that MicroPython is running properly on your micro controller by accessing the REPL prompt. | ||
|
||
``` | ||
mpremote connect /dev/ttyUSB0 | ||
``` | ||
|
||
#### 1.2 Sniff the device ID | ||
|
||
The shutters are normally controlled by a 2411 Rademacher remote control. The remote has a unique identification number, which is required for the operation of FernoPy. | ||
|
||
1. Connect the micro controller to the 433 MHz receiver as shown below: | ||
|
||
| Micro controller | 433 MHz receiver | | ||
| ---------------- | ---------------- | | ||
| GND | GND | | ||
| 5V | VCC | | ||
| GPIO5 | DATA | | ||
|
||
GPIO5 is the standard pin for the data connection. If you want to use another one you have to change it in the file `/src/rx/rx_config.py`. | ||
|
||
2. Connect the micro controller to your PC. | ||
|
||
3. Run the sniffing install script and follow the given instructions. | ||
```shell | ||
chmod +x 1-rx-install.sh | ||
./1-rx-install.sh /dev/ttyUSB0 | ||
``` | ||
|
||
> :warning: The recording should ideally not take place in the vicinity of possible sources of interference, such as radio weather stations that also transmit on 433 MHz. The distance between the PC and the micro controller should also be maximized for the same reason (what the USB cable can offer). Also micro controller and receiver should not be next to each other. **Compare your setup with [this illustration](img/setup.png)**. | ||
> :warning: The antenna of the receiver should be parallel to the left side of the remote control. Vertically, the antenna should be in the lower third to half of the remote control. The distance between the remote control and the antenna should be as small as possible (they can also touch each other). **Compare your placement with [this illustration](img/remote.png)**. | ||
> :information_source: If the recording does not work even after multiple position changes, you can activate the *debug* settings in the config file and alter the *margin* value. For the changes to take effect, the install script must be rerun. | ||
> :information_source: If a `MemoryError` occurs you can reduce the *n_edges* value in the config. You may also need to enable *debug* output there. | ||
##### Alternative: Sniff via an SDR and Universal Radio Hacker (For experienced users) | ||
|
||
If you have a SDR on hand, such as an RTL-SDR, you can also sniff the ID by using the software [Universal Radio Hacker](https://github.com/jopohl/urh). You can find a prepared project in the `urh` folder. It contains predefined message types and a custom decoder for the FernoTron protocol. The program also allows you to better understand the protocol structure. | ||
|
||
### 2. Install FernoPy | ||
|
||
1. Open the tx configuration file in an editor of your choice. | ||
``` | ||
nano /src/tx/tx_config.py | ||
``` | ||
|
||
Enter the ESSID of your home network and the password in the general dict. | ||
```python | ||
# General device configuration | ||
general = { | ||
'symbol_length': 300, # in µs | ||
'tx_pin': 5, # GPIO! | ||
'tx_repeat': 4, # MSGs transmitted per command | ||
'essid': 'YOUR_NETWORK_ESSID', | ||
'password': 'YOUR_NETWORK_PASSWORD', | ||
'html_assets': 'assets' # Path to web assets | ||
} | ||
``` | ||
|
||
> :information_source: The symbol length of FernoTron is actually 400µs, but 300µs are used because of the latency of the MC. You may have to adjust this value. | ||
Next, the configuration of your FernoTron remote control must be entered into the fernotron list. Start by entering for each remote the type and id you got from the previous step. | ||
```python | ||
fernotron = [ | ||
{ | ||
# Remote 0 | ||
'device_type': 0x80, # Add information from the RX scipt here! | ||
'device_id': 0x1234, # Add information from the RX scipt here! | ||
... | ||
``` | ||
|
||
Now enter all groups and their devices with their respective names. The index of the groups and devices corresponds to that of the remote control. | ||
|
||
> :warning: The first group of a remote control is always the *All* group! This must not be removed! Likewise, the first device of a group (index 0) must always be *All*! You can translate the name into your own language if you wish. | ||
|
||
```json | ||
... | ||
'groups': [ | ||
{ | ||
# Default group. Do not remove! | ||
'name': 'All', | ||
'members': ['All'] | ||
}, | ||
{ | ||
# Group 1 - Example | ||
'name': 'Living room', # Group name | ||
'members': ['All', 'North', 'East', 'South', 'West'] # Group member names | ||
}, | ||
{ # Group 2 - Example | ||
'name': 'Kitchen', | ||
'members': ['All', 'Street', 'Garden'] | ||
}, | ||
... | ||
``` | ||
|
||
2. Connect the micro controller to the 433 MHz transmitter as as described above in section 1.2. | ||
|
||
3. Connect the micro controller to your PC. | ||
|
||
4. Run the FernoPy install script. | ||
```shell | ||
chmod +x 2-tx-install.sh | ||
./2-tx-install.sh /dev/ttyUSB0 | ||
``` | ||
|
||
5. Open the web interface by entering the displayed IP in your browser. | ||
|
||
> :information_source: If you open FernoPy in your smartphone's web browser, you can create a short cut for your home screen. | ||
|
||
## Credits | ||
|
||
Protocol documentation - https://github.com/zwiebert/tronferno-mcu | ||
Logo - https://www.flaticon.com/free-icons |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.