Projekt IoT

From JoBaPedia
Jump to navigation Jump to search

IoT - Internet of Things

some project ideas and notes regarding Arduino, ESP8266, ESP32 and other micro controllers

  • Arduino Nano with 433 MHz data transfer
  • ESP-01 for shutter control
  • ESP-12 for LED switch
  • ESP-12 for laundry room air control
  • SonOff with own firmware and tasmota devices
 https://github.com/arendst/Sonoff-Tasmota/wiki

Arduino IDE Inofficial Boards

look here for an overview:

ATTiny

Most ATTinys: https://github.com/SpenceKonde/ATTinyCore

Wiring

https://startingelectronics.org/tutorials/AVR-8-microcontrollers/ATtiny2313-tutorial/P8-TC0-polled-timer/ATTINY2313-TC0-polled.png

  • Vcc can also be 3.3V
  • C1 can have bigger capacity for unstable voltage
  • R1 can be higher values

Programmer

I have an USBasp. Program with avrdude. Works integrated in Arduino IDE. Ignore warning "avrdude: warning: cannot set sck period. please check for usbasp firmware update.".

Numbering of Connector is

1 3 5 7 9
2 4 6 8 10

Need to connect Vcc, Gnd, Miso(1), Mosi, Reset and Sck

New chip needed 0.5MHz for correct timing with delay()

Needed to add this udev rule

echo 'SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", GROUP="dialout", MODE="0660"' | sudo sh -c 'cat >/etc/udev/rules.d/50-USBasp.rules'

Digistump

or compatible board with ATTiny85 and USB (P0-P5 and 5V/Gnd/Vin broken out)

SUBSYSTEMS=="usb", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0753", MODE:="0666"
KERNEL=="ttyACM*", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0753", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1"

if you update rules files, don't forget to

sudo udevadm control --reload-rules
  • Example platformio.ini
[env:attiny85]
platform = atmelavr
board = digispark-tiny
framework = arduino
; change microcontroller
; board_build.mcu = attiny85
; change MCU frequency
board_build.f_cpu = 8000000L
  • Example main.cpp blink sketch (different versions use pb0 or pb1 as internal onboard led)
#include <Arduino.h>

void setup() {
  pinMode(0, OUTPUT); //LED on Model B
  pinMode(1, OUTPUT); //LED on Model A   
}

void loop() {
  digitalWrite(0, HIGH);   // turn the LED on (HIGH is the voltage level)
  digitalWrite(1, HIGH);
  delay(500);              // wait for half a second
  digitalWrite(0, LOW);    // turn the LED off by making the voltage LOW
  digitalWrite(1, LOW); 
  delay(500);              // wait for half a second
}
  • Flash firmware

Start upload first, then plug in the device. Micronucleus finds the booting device automatically with the help of above udev rules.

ESP8266/ESP32

https://github.com/esp8266/Arduino

many boards come with a usb to serial adapter. To give them fixed device names like /dev/tty_esp32-1, udev rules can be used:

  • list currently used tty USB ports
ls /dev/tty[UA]*
  • Plug in the usb adapter or board
  • check name of port by listing ports again
  • list attributes of the adapter that can be used to uniquely identify it, e.g. for /dev/ttyUSB0 idVendor, idProduct and devpath
udevadm info -a /dev/ttyUSB0
  • create file like /etc/udev/rules.d/99-my-adapter.rule with this line using attributes like idProduct
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ATTRS{devpath}=="1", MODE:="0660", GROUP:="mq135", SYMLINK+="ttyUSB_mq135"
  • enable the new rule and trigger it
udevadm control --reload-rules
udevadm trigger

Now you should see /dev/ttyUSB_mq135 as link to /dev/ttyUSB0

if idProduct and idVendor is not enough, you may also use bus locations (devpath, if always plugged in the same port) or the serial (if the adapter reports a unique serial number).

Domoticz

This is a home automation system that is natively supported by tasmota devices via mqtt

Installation

Old Repo
sudo /usr/sbin/useradd -U -g domoticz -m -r domoticz
  • Edit section Service in /usr/lib/systemd/system/domoticz.service (ports, logging, db)
[Service]
ExecStart=/opt/domoticz/domoticz -notimestamps -syslog -www 8888 -sslwww 4343 -dbase domoticz.db
WorkingDirectory=/home/domoticz
User=domoticz
Group=domoticz
Restart=always
  • Activate new service file, start domoticz and check status
sudo systemctl daemon-reload
sudo systemctl enable domoticz
sudo systemctl start domoticz
sudo systemctl status domoticz
Self Compiled

domoticz.service

[Unit]
Description=Domoticz 4 (JoBa Edition)
Wants=nss-lookup.target
After=network.target

[Service]
PIDFile=/run/domoticz/domoticz.pid
#ExecStart=/opt/domoticz/domoticz -daemon -syslog -log /var/log/domoticz.log -www 8080 -sslwww 8443
ExecStart=/opt/domoticz/domoticz -daemon -syslog -log /var/log/domoticz.log -pidfile /run/domoticz/domoticz.pid -www 8888 -sslwww 8443
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -KILL $MAINPID
User=domoticz
Group=domoticz

[Install]
WantedBy=multi-user.target

In domoticz.spec adapt APPVERSION, APPHASH and Version prefix

#
# spec file for package domoticz
#
# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
# Copyright (c) 2014-2016 Guillaume GARDET <guillaume@opensuse.org>
# Copyright (c) 2018 Joachim Banzhaf <joachim.banzhaf@gmail.com>
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.

# Please submit bugfixes or comments via http://bugs.opensuse.org/
#

#
# Hash can be found on Github, select tag, look for "Last commit xxxx" under the Clone/Download button
#

%define APPVERSION 9700
%define APPHASH 2772d9f

Name: domoticz
Summary: Domoticz is a very light weight Home Automation System
Version: 4.%{APPVERSION}
Release: 0
License: GPL-3.0+
Group: Productivity/Other
Url: http://www.domoticz.com/
Source0: %{name}-%{version}.tar.gz
Source1: domoticz.service
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: cmake
BuildRequires: gcc-c++
BuildRequires: pkgconfig
BuildRequires: fdupes
BuildRequires: openssl-devel
BuildRequires: python3-devel
BuildRequires: boost-devel >= 1.55
BuildRequires: curl-devel
BuildRequires: libusb-devel
BuildRequires: openzwave
BuildRequires: libopenzwave-devel
BuildRequires: libudev-devel
BuildRequires: git
BuildRequires: sqlite
BuildRequires: sqlite-devel
BuildRequires: python3-devel
Requires: sqlite
Requires: python3-devel
BuildRequires: systemd-rpm-macros
%{?systemd_requires}

%description
Domoticz is a very light weight Home Automation System that lets you monitor and
configure various devices like: Lights, Switches, various sensors/meters like
Temperature, Rain, Wind, UV, Electra, Gas, Water and much more.
Notifications/Alerts can be sent to any mobile device. Supported platforms:
Package for openSUSE 42.2 by Joachim.Banzhaf@gmail.com

Unix/Linux, (openSUSE, Raspberry Pi/Cubieboard recommended) Windows 


%prep
%setup -q

%build
cat > appversion.default << EOL
#define APPVERSION %{APPVERSION}
#define APPHASH "%{APPHASH}"
#define APPDATE `date +%s`
EOL
#
mkdir build/
pushd build/
cmake .. \
    -DCMAKE_BUILD_TYPE=Release \
    -DUSE_STATIC_BOOST=OFF \
    -DUSE_STATIC_OPENZWAVE=OFF
make
popd

%install
pushd build/
%make_install
popd
install -m 0644 -D %{SOURCE1} %{buildroot}/%{_unitdir}/%{name}.service
#
# Cleanup
#
rm -f %{buildroot}/opt/domoticz/scripts/dzVents/runtime/tests/scandir/.f3.lua.swp
#
%fdupes -s %{buildroot}/opt
#
# Setup system
#
mkdir -p %{buildroot}/run/domoticz
mkdir -p %{buildroot}/var/log
touch %{buildroot}/var/log/domoticz.log

# install /usr/lib/tmpfiles.d/domoticz.conf
mkdir -p %{buildroot}%{_tmpfilesdir}
cat > %{buildroot}%{_tmpfilesdir}/domoticz.conf <<EOF
# domoticz needs existing /run/domoticz/ to create domoticz.pid there
# See tmpfiles.d(5) for details

d /run/domoticz 0755 domoticz domoticz -
EOF

%pre
getent group domoticz >/dev/null || groupadd -r domoticz
getent passwd domoticz >/dev/null || \
useradd -r -g domoticz -d %{_sharedstatedir}/domoticz -s /sbin/nologin \
        -c "domoticz daemon account" domoticz
%if 0%{?_unitdir:1}
    %service_add_pre domoticz.service
%endif

%post
%if 0%{?_unitdir:1}
    %service_add_post domoticz.service
%endif

%preun
%if 0%{?_unitdir:1}
        %service_del_preun domoticz.service
%endif

%postun
%if 0%{?_unitdir:1}
    %service_del_postun domoticz.service
%endif

%files
%defattr(-,root,root)
%dir %attr(0755,domoticz,domoticz) /opt/domoticz/
%dir %attr(0755,domoticz,domoticz) /run/domoticz/
%attr(-,domoticz,domoticz) /opt/domoticz/*
%{_tmpfilesdir}/domoticz.conf
%{_unitdir}/%{name}.service
%attr(0644,domoticz,domoticz) /var/log/domoticz.log

%changelog

Add to /usr/share/cmake/Modules/FindOpenSSL.cmake after failing find_library() calls

set(OPENSSL_SSL_LIBRARY "/usr/lib64/libssl.so")
set(OPENSSL_CRYPTO_LIBRARY "/usr/lib64/libcrypto.so")

Commands to download, build, update and install

v=4.9700
zypper in libopenzwave-devel libopenssl-devel libcrypto41
mkdir -p /home/joachim/rpmbuild/SPECS /home/joachim/rpmbuild/SOURCES
wget -O domoticz.zip https://github.com/domoticz/domoticz/archive/${v}.zip
unzip domoticz.zip
tar czf /home/joachim/rpmbuild/SOURCES/domoticz-$v.tar.gz domoticz-${v}/
rpmbuild -ba /home/joachim/rpmbuild/SPECS/domoticz.spec
sudo rpm -Uhv /home/joachim/rpmbuild/RPMS/x86_64/domoticz-${v}-0.x86_64.rpm
sudo systemctl start domoticz.service

Commands for git version (modify spec as above, and I used git clone --recursive, not sure it is needed...)

v=5.0000
git clone https://github.com/domoticz/domoticz.git domoticz-$v
tar czf /home/joachim/rpmbuild/SOURCES/domoticz-$v.tar.gz domoticz-${v}/
rpmbuild -ba /home/joachim/rpmbuild/SPECS/domoticz.spec
sudo rpm -Uhv /home/joachim/rpmbuild/RPMS/x86_64/domoticz-${v}-0.x86_64.rpm
sudo systemctl start domoticz.service
Update to git release

Optional: download compile and install latest (or specific) python version, move to domoticz and install modules. If you do that, the python environment during build and run must be the same version!

sudo su - domoticz
getpy.sh 3.12.1
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/python-3.12.1/lib
. ~/python-3.12.1/venv/base/bin/activate

Modify line in domoticz.service file, so modules installed for a venv are found

Environment="LD_LIBRARY_PATH=/home/domoticz/python-3.12.1/lib:$LD_LIBRARY_PATH" "PATH=/home/domoticz/python-3.12.1/bin:/home/domoticz/bin:/usr/local/bin:/usr/bin:/bin" "PYTHONHOME=/home/domoticz/python-3.12.1" "PYTHONPATH=/home/domoticz/python-3.12.1/lib/python3.12:/home/domoticz/python-3.12.1/venv/base/lib:/home/domoticz/python-3.12.1/venv/base/lib64/python3.12/site-packages:home/domoticz/python-3.12.1/lib/python3.12/lib-dynload:/home/domoticz/python-3.12.1/venv/base/lib/python3.12/lib-dynload"

Install required modules

pip install sseclient requests bluepy

Update git repo to desired release (yyyy.n or main or...)

cd ~/git/domoticz
git fetch
git checkout 2023.2
git submodule update --recursive --remote

Create buildfiles, check for missing prerequisites, install them, then repeat

rmdir -rf cbuild && mkdir cbuild && cd cbuild
cmake -DCMAKE_BUILD_TYPE=Release -DPython3_ROOT_DIR=~/python-3.12.1 -DCMAKE_INSTALL_PREFIX=/opt/domoticz -DUSE_STATIC_BOOST=OFF ..

Build

make -j3
make install
# testrun
/opt/domoticz/domoticz -www 8888 -sslwww 8443
# update python version in service file if needed
sudo vi /etc/systemd/system/domoticz.service
sudo systemctl restart domoticz.service

Backup

Backups of domoticz database in /opt/domoticz/backups, or copy /opt/domoticz/domoticz.db yourself.

Configuration

https://github.com/arendst/Sonoff-Tasmota/wiki/Domoticz

  • On setup/hardware page create mqtt connection (host job4, port 1883, option flat/out) and one Dummy device for virtual switches
  • For each tasmota device function (switch, temp/hum, ...) click on "virtual sensor" (on hardware page at dummy device entry)
  • On setup/devices page look at idx values for the virtual sensor devices and configure tasmota device with them.

Cura Build

Prerequisites

git clone https://github.com/Ultimaker/Cura.git
git clone https://github.com/Ultimaker/cura-build

Follow instructions for CentOS in cura-build/README.md and try to adapt for opensuse 42.2

sudo zypper in gcc-fortran python3 python3-pyserial python3-numpy python3-opengl python3-setuptools libstdc++-devel openssl openblas-devel gtk3-devel webkit2gtk3-devel gstreamer-devel python-wxWidgets-3_0 python-wxWidgets-3_0-devel
# pip3 install F2PY

F2PY not found -> build may fail

Installation

cmake fails because it needs python 3.5 while opensuse 42.2 only has 3.4 - end of story for now :(

Use app container for now (but how to use core functions directly?)

Feinstaubsensor

https://luftdaten.info/feinstaubsensor-bauen/

  • NodeMCU
  • SDS011
  • optional: BME280 (probably needs code change since they use DHT22)
  • USB powersupply
  • USB cable
  • 2 x Marley HT DN75, 87°
  • Gaze als Insektenschutz
  • 3 x Kabelbinder lang (für Gaze an Marley, Fixierung an Pfosten o.ä.) und kurz (Kabel/NodeMCU/SDS011/BME280) fixieren
  • ~20cm Plastikröhrchen Innendurchmesser 6mm (dunkel)

Cost ~25€

RFID Demo

https://github.com/miguelbalboa/rfid/blob/master/examples/AccessControl/AccessControl.ino

What is needed for an access control demo (might send mqtt status):

  • ESP8266 as central unit
  • RFID reader/writer
  • 1 RFID Card (Master)
  • n RFID Tags (ID "Cards")
  • USB Cable MicroUSB
  • LED for access granted or added: green
  • LED for access denied or removed or error: red (red+green: master mode)
  • Dupont cabling for reader (~10 f-f)
  • Breadboard

Cost ~5€

RF-Link

RF-Link is a gateway transceiver for many 433MHz (and other frequencies) controlled devices, like weather stations and remote controlled plugs.

You need an Atmega 2560, an RF receiver and sender of the desired frequency (e.g. an RXB6 and an FS-1000a) and wire it as described here: http://www.rflink.nl/blog2/wiring (should be below 15€).

  • Download RF-Link Firmware from here: http://www.rflink.nl/blog2/download
  • Unzip it to an empty folder and cd to the directory containing RFLink.cpp.hex
  • Upload with Arduino IDE supplied avrdude (or find it elsewhere...). Adjust serial port as needed
~/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino9/bin/avrdude -C~/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino9/etc/avrdude.conf -patmega2560 -cstk500v2 -P/dev/ttyUSB1 -b115200 -D -Uflash:w:RFLink.cpp.hex:i

Now connect the Atmega usb serial with a pc, start a terminal program with that port at 57600 baud and read what is in the air. Some commands to try are here: http://www.rflink.nl/blog2/protref

Domoticz home automation can integrate an RF-Link via serial and via ethernet (not tested, sernet? ehternet shield?). It autodetects available devices (enable for 5min in settings) and can control switches after "learning" them. Basically all devices I already owned did work, good coverage. Currently I have one issue with this: domoticz can only use the device if I open it before with a terminal program - no idea why...

Antennas for 433MHz can be thick single wire of 16.8cm length. It should point in a direction 90 degrees from the direction to the device most problematic to communicate with. I could communicate with devices outside the house, ~5m away and also inside but one floor down or up, ~12m away.

Mosquitto MQTT Broker

Basic setup is easy, getting secure TLS to work not quite so.

Preparation

With leap 15 mosquitto is provided with the standard repositories. Older suse versions need to add a repo (e.g. http://download.opensuse.org/repositories/network:/messaging:/mqtt/openSUSE_Leap_42.2/)

Installation

sudo zypper in mosquitto mosquitto-clients
systemctl enable mosquitto

Configuration

Provide a file /etc/mosquitto/conf.d/tls.conf

# for my local unencrypted clients anonymous is ok
allow_anonymous          true
# This would require the cert cn or username in the passwd file
# allow_anonymous          false
# password_file /etc/mosquitto/passwd
port 1883

# additional listener for TLS
listener 8883

# my own ca so the broker can trust my clients
cafile /etc/mosquitto/ca_certificates/ca.crt

# my official lets encrypt cert so clients can trust the broker
certfile /etc/letsencrypt/live/banzhaf.chickenkiller.com/fullchain.pem
keyfile /etc/letsencrypt/live/banzhaf.chickenkiller.com/privkey.pem

# TLS needs client certificate (of my ca) to allow access
require_certificate      true
use_identity_as_username true

use_username_as_clientid true 

# additional listener. Some clients only talk websockets
listener 9001
protocol websockets

Start Mosquitto Service

systemctl start mosquitto

Example Usage

  • Subscribe to all topics of local mosquitto broker
mosquitto_sub -v -t \#
  • Publish message "hello" to topic "world" on local mosquitto broker
mosquitto_pub -m hello -t world
  • Publish securely via TLS
mosquitto_pub -h banzhaf.chickenkiller.com -p 8883 -m hello -t safeworld \\
  --cafile /etc/ssl/certs/DST_Root_CA_X3.pem \\
  --cert mqtt1@banzhaf.chickenkiller.com.crt \\
  --key mqtt1@banzhaf.chickenkiller.com.key
    • banzhaf.chickenkiller.com is the broker server with a valid Lets Encrypt server certificate
    • 8883 is the TLS listening port of the broker
    • hello is the published message
    • safeworld is the topic (category) where the message is published
    • /etc/ssl/certs/DST_Root_CA_X3.pem is the CA certificate of Lets Encrypt
    • mqtt1@banzhaf.chickenkiller.com.crt is a client certificate issued by my own CA
    • mqtt1@banzhaf.chickenkiller.com.key is the encryption key of the client certificate

Common Errors

  • Every TLS client needs its own certificate, because else they disconnect eachother
  • Don't forget to restart the broker if there is a new server certificate (every 90 days)
  • On errors with the server certificate, you loose connection with this message (server log says: GET_CLIENT_HELLO:unknown protocol)
Error: The connection was lost.
  • On errors with the client certificate, you loose connection with this message (server log says: peer did not return a certificate)
Error: A TLS error occurred.

Sonoff Basic Tasmota Config for I2C

just noticed I did not note that anywhere else: my Sonoff basic is configured like this:

  • serial log off
  • serial out GPIO 1 -> SDA
  • serial in GPIO 3 -> SCL

Tasmota Build

First fork github tasmota repo or merge a pull request to an existing fork, then replace MyPw below and add other -e options if needed

       WLAN_PW="MyPw"
       git clone git@github.com:joba-1/Tasmota.git
       cd Tasmota/
       cp tasmota/user_config_override_sample.h tasmota/user_config_override.h 
       sed -i "s/YourWifiPassword/$WLAN_PW/" tasmota/user_config_override.h 
       sed -i -e's/YourSSID/job.fritz.ssid/' -e 's/your-mqtt-server.com/192.168.1.4/' -e 's/MY_IP/0.0.0.0/' tasmota/user_config_override.h 
       PLATFORMIO_BUILD_FLAGS=-DUSE_CONFIG_OVERRIDE pio run -e tasmota-sensors -e tasmota-minimal
       for f in .pioenvs/*/firmware.bin; do g="${f/\/firmware}"; gzip <"$f" >"/srv/www/htdocs/${g/.pioenvs\/}.gz"; done
       for f in .pio/build/*/firmware.bin; do g="${f/\/firmware}"; gzip <"$f" >"/srv/www/htdocs/${g/.pio\/build\/}.gz"; done

Now compiled variants are accessible with the local webserver. If you don't have a webserver running, just do "cd /srv/www/htdocs/ && python3 -m http.server 8000" and you have one.

Longan Nano Bits of Wisdom

use PlatformIO :)

OpenOcd

Discover board correctly

You see this during upload or debug with sipeed jtag :

Info : JTAG tap: riscv.cpu tap/device found: 0x1000563d (mfg: 0x31e (Andes Technology Corporation), part: 0x0005, ver: 0x1)
Warn : JTAG tap: riscv.cpu       UNEXPECTED: 0x1000563d (mfg: 0x31e (Andes Technology Corporation), part: 0x0005, ver: 0x1)
Error: JTAG tap: riscv.cpu  expected 1 of 1: 0x1e200a6d (mfg: 0x536 (Nuclei System Technology Co.,Ltd.), part: 0xe200, ver: 0x1)
Info : JTAG tap: auto0.tap tap/device found: 0x790007a3 (mfg: 0x3d1 (GigaDevice Semiconductor (Beijing)), part: 0x9000, ver: 0x7)
Error: Trying to use configured scan chain anyway...
  • vi ~/.platformio/packages/tool-openocd-gd32v/share/openocd/scripts/target/gd32vf103.cfg
  • Change expexted id at the end of line "jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1e200a6d" to "0x1000563d"

Errormessage should be gone. No idea if it actually changes any behaviour...

Enable Longan-Nano/GD32VF103 reset via jtag adapter

as far as I understand it, the gd32vf103 has no normal way to be reset via jtag. If you upload and debug: all fine. But if you upload and want to run the target without debug: nothing happens. Reset button is not functional. This can be remedied with a manual power cycle, but that is not convenient...

This is a gist provides a solution: https://gist.github.com/elfmimi/1deb9c94b0f0900ae8a9df740b62bcd6

  • Replace file ~/.platformio/packages/tool-openocd-gd32v/share/openocd/scripts/target/gd32vf103.cfg with the gist version
  • Modify ~/.platformio/platforms/gd32v/builder/main.py: change the whole line containig 'program {$SOURCE}' with ' "-c", "program {$SOURCE} verify reset exit"'

This is the openocd command to flash the Longan Nano, firmware path relative to the project directory:

FW=.pio/build/sipeed-longan-nano/firmware.elf
OCD=~/.platformio/packages/tool-openocd-gd32v
$OCD/bin/openocd -s $OCD/share/openocd/scripts -f interface/ftdi/sipeed-rv-debugger.cfg -f target/gd32vf103.cfg -c "init; halt;" -c "program $FW verify reset exit"