Raspberry Pi as AP with Rsensor Server

This is a collection of notes on how to configure a Raspberry Pi as IOT node.

Initial Setup

Prepare Image

Configure Image

  • login to raspi (console or with ssh pi@<RASPI-IP>)

  • expand file system and reboot:

    sudo raspi-config
    "7 Advanced ..." / "A1 Expand Filesystem"
    "Finish" / "Reboot" => YES
    
  • wait until reboot is finished and login again

Install Software

Do the following steps:

sudo apt update
sudo apt upgrade # optional, may take longer

sudo apt install mosquitto

Prepare a virtual environment that runs uracoli-rsensor:

sudo bash
cd /opt
mkdir -p rsensor
apt install python-pip
python3 -m pip2 install virtualenv
python3 -m virtualenv ve_rsensor
ve_rsensor/bin/pip install uracoli-rsensor

To install alternatively the latest development version, run this command:

/opt/rsensor/ve_rsensor/bin/pip install -e git+https://gitlab.com/uracoli-project/uracoli-rsensor.git

Write a config file /opt/rsensor/rsensor.cfg, e.g.:

mqtt:
 - host: 10.65.87.1
   port: 1883
   prefix: 'mkawdt'

database:
    dbtype: mysql
    dbname: rsensor
    dbuser: rsensor
    dbpasswd: rsensor
    dbhost: 172.16.1.20

Writing a SystemD-Daemon Script

To collect sensor data over a long time, the script mqtt_to_db can run as Daemon-service on a Linux server, e.g.on a Raspberry-Pi.

Create a file /etc/systemd/system/rsensor.service with the following contents:

[Unit]
Description=MqttToDb Service
After=network-online.target

[Service]
Type=simple
User=pi
Group=pi
WorkingDirectory=/opt/rsensor
ExecStart=/opt/rsensor/ve_rsensor/bin/mqtt_to_db -C /opt/rsensor/rsensor.cfg -L ERROR
SyslogIdentifier=rsensor
StandardOutput=syslog
StandardError=syslog
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

If you choose another location then /opt/rsensor, then adapt in the file above adapt the path-names (see also section python-ve) . Also note the option -L ERROR, which reduces the amount of messages written to the system-log. In case of problems, change it temporarily to -L DEBUG

The script rsensor.service is activated with the following commands:

systemctl daemon-reload
systemctl enable rsensor.service
systemctl start rsensor.service

The status of the script can be verified with these commands:

# see if the script is running or it is crashed.
systemctl status rsensor.service

# see all log messages from the beginning of the log.
journalctl -u rsensor.service

# see actual incoming messages
journalctl -u rsensor.service -f

The script can be stopped with:

systemctl stop rsensor.service

Configure Raspi Rsensor AP

Follow the article How to use your Raspberry Pi as a wireless access point (https://thepi.io) and skip the bridge settings in this article, they are not needed for the sensor network. (alternativly see also Raspberry Pi als WLAN-Router einrichten)

Use raspi-config and set country code to “DE” or the country where the raspi will be operated.

Software to install:

sudo apt install hostapd dnsmasq

Before Edit cofig, stop daemons:

sudo systemctl stop hostapd
sudo systemctl stop dnsmasq

Here are the current used configuration files.

/etc/dhcpcd.conf:

hostname
clientid
persistent
option rapid_commit
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes
option interface_mtu
require dhcp_server_identifier
slaac private
interface wlan0
static ip_address=10.65.87.1/24
denyinterfaces eth0
denyinterfaces wlan0

/etc/dnsmasq.conf:

interface=wlan0
  dhcp-range=10.65.87.100,10.65.87.200,255.255.255.0,24h

/etc/hostapd/hostapd.conf:

interface=wlan0
#bridge=br0
hw_mode=g
channel=7
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
ssid=MyRsensorAP
wpa_passphrase=sovershennosekretno

/etc/default/hostapd:

DAEMON_CONF="/etc/hostapd/hostapd.conf"

/etc/sysctl.conf:

net.ipv4.ip_forward=1

/etc/rc.local:

#!/bin/sh -e
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi
# appended iptables-restore for AP, generated by:
#       sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
#       sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
iptables-restore < /etc/iptables.ipv4.nat
exit 0

Note

Also check the permissions of /etc/rc.local. It needs to be executable. -rwxr-xr-x 1 root root 306 Apr  4  2017 /etc/rc.local

Enable and restart the services:

systemctl enable hostapd dnsmask
systemctl unmask hostapd dnsmask
systemctl start hostapd dnsmask

Bind USB Stick to fixed interface address

Adapt udev rules:

cat /etc/udev/rules.d/72-xxx.rules
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="b8:27:eb:31:22:db", NAME="wlan0"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="b8:27:eb:64:77:8e", NAME="eth0"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="d0:37:45:70:c6:88", NAME="wlan1"

Wifi Issues

Be carefull with trouble shooting, the trouble always shoots back.

Note

After hours of wasted time, the use of the Wifi stick WN722N was abondoned.

After a week of operation, the WN722N blinked more frequently then before and a setup of the AP was not possible, even not after cold start or normal reboot.

Also switchin back to the internal Wlan0 does not bring back wifi AP. Hence the SD Card was somehow damaged and was installed again from scratch.

Not sure if this was the reason, but I used an IOT device which frequently reconnects to the AP because of deep sleep (the error occured after > 2500 reconnects).

In case of an error message from hostapd:

>> journalctl -u hostapd.service
-- Logs begin at Sat 2020-06-06 12:17:01 CEST, end at Sat 2020-06-06 13:16:17 CEST. --
Jun 06 12:46:06 gretel systemd[1]: Starting Advanced IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP Authenticator...
Jun 06 12:46:07 gretel hostapd[379]: Configuration file: /etc/hostapd/hostapd.conf
Jun 06 12:46:07 gretel hostapd[379]: nl80211: Driver does not support authentication/association or connect commands
Jun 06 12:46:07 gretel hostapd[379]: nl80211: deinit ifname=wlan0 disabled_11b_rates=0

If a Wifi-USB stick like TP-LINK TL-WN722N is used, you need to install new drivers. Easy way is using MrEngmans precompiled modules. (https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=62371&sid=97f79dbe9f8ac40727b1c4ba236c9454)

Do this steps on Raspberry:

sudo wget http://downloads.fars-robotics.net/wifi-drivers/install-wifi -O /usr/bin/install-wifi
sudo chmod +x /usr/bin/install-wifi
sudo /usr/bin/install-wifi -h
sudo /usr/bin/install-wifi

After reboot the error should have been gone.

Write Protect SD Card

Finaly, after finishing the configuration, the SD card is write protected with an overlay file system. Write protection can be enabled with:

sudo raspi-config
"7 Advanced Options"
"AB Overlay FS"
"Would you like the overlay file system to be enabled? " => yes
"Enable overlay file system on boot partition" => yes

Now the system is protected and withstands even sporadic power losses. All changes to the file system during runtime are lost at reboot or power cycle, because they are stored in the RAM overlay section.