Wechselrichter Statistik mit einem Raspberry Pi (als AP und Webserver)

Der Raspberry Pi ist ein Einplatinencomputer der Raspberry Pi Foundation, der sich u.a. hervorragend für kleine Projekte eignet. In meinem Fall als Visualisierung der Daten eines PIKO-Wechselrichters.
Für den Raspberry Pi gibt es verschiedene Betriebssysteme. In dieser Beschreibung geht es um raspbian.

Raspbian Lite Installation

Download:
$ wget https://downloads.raspberrypi.org/raspbian_lite_latest

Als Medium kommt eine Micro SD-Karte (ab 4GB) zum Einsatz. Als WLAN-USB-Stick wird Odroid WiFi Module 4 (MediaTek(Ralink) RT5572N) verwendet. Als Erweiterungsboard kommt PiFace RTC zum Einsatz.

Kopieren des Image auf die SD-Karte:
$ dd bs=4M if=2017-11-29-raspbian-stretch.img of=/dev/sdX status=progress conv=fsync

Vorhandene Nutzer sind pi und root. pi nutzt raspberry als Passwort. SSH muss über eine leere Datei namens ssh in der boot Partition aktiviert werden (falls im headless Betrieb).

$ dpkg-reconfigure tzdata
$ dpkg-reconfigure locale
$ timedatectl set-local-rtc 0
$ hostnamectl set-hostname myhostname
$ localectl set-locale LANG=de_DE.UTF-8
$ localectl set-keymap de-latin1

weitere Pakete

$ apt-get --no-install-recommends install vim mc lsof
$ apt-get install apache2 libapache2-mod-php php-sqlite3 php-curl dnsmasq hostapd i2c-tools
$ apt-get purge avahi-daemon samba-common nfs-common alsa-utils triggerhappy dphys-swapfile
$ apt autoremove

Accesspoint

/etc/hostapd/hostapd.conf
interface=wlan0
driver=nl80211
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
ssid=RaspberryPi
country_code=DE
ieee80211d=1
hw_mode=g
channel=1
beacon_int=100
dtim_period=2
max_num_sta=255
rts_threshold=2347
fragm_threshold=2346
macaddr_acl=0
auth_algs=1
wmm_enabled=1
wmm_ac_bk_cwmin=4
wmm_ac_bk_cwmax=10
wmm_ac_bk_aifs=7
wmm_ac_bk_txop_limit=0
wmm_ac_bk_acm=0
wmm_ac_be_aifs=3
wmm_ac_be_cwmin=4
wmm_ac_be_cwmax=10
wmm_ac_be_txop_limit=0
wmm_ac_be_acm=0
wmm_ac_vi_aifs=2
wmm_ac_vi_cwmin=3
wmm_ac_vi_cwmax=4
wmm_ac_vi_txop_limit=94
wmm_ac_vi_acm=0
wmm_ac_vo_aifs=2
wmm_ac_vo_cwmin=2
wmm_ac_vo_cwmax=3
wmm_ac_vo_txop_limit=47
wmm_ac_vo_acm=0
ieee80211n=1
eapol_key_index_workaround=0
own_ip_addr=127.0.0.1
wpa=2
wpa_passphrase=<dein_passwort>
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
rsn_pairwise=CCMP
/etc/dnsmasq.conf
address=/wechselrichter.deine.domain.home/192.168.1.1
interface=wlan0
no-dhcp-interface=eth0
domain=deine.domain.home
dhcp-range=192.168.1.100,192.168.1.150,255.255.255.0,2h
dhcp-option=3
/etc/dhcpcd.conf
denyinterfaces wlan0
hostname
clientid
persistent
option rapid_commit
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes
option ntp_servers
option interface_mtu
require dhcp_server_identifier
slaac private
profile static_eth0
static ip_address=192.168.1.2/24
interface eth0
fallback static_eth0
/etc/network/interfaces.d/wlan0_hostapd
allow-hotplug wlan0
iface wlan0 inet static
	address 192.168.1.1
	netmask 255.255.255.0
	network 192.168.1.0
	broadcast 192.168.1.255
/lib/systemd/scripts/my-accesspoint.sh:
#!/bin/bash

while getopts ":abc" opt; do
  case $opt in
    a)
      /sbin/ifup wlan0
      /bin/systemctl start hostapd.service
      /bin/systemctl start dnsmasq.service
      ;;
    b)
      /bin/systemctl stop dnsmasq.service
      /bin/systemctl stop hostapd.service
      /sbin/ifdown wlan0
      ;;
    c)
      /bin/systemctl status dnsmasq.service
      /bin/systemctl status hostapd.service
      /sbin/ifconfig wlan0
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      echo "a - start"
      echo "b - stop"
      echo "c - status"
      ;;
  esac
done
/lib/systemd/system/my-accesspoint-up.service:
[Unit]
Description=Accesspoint Up
After=network.target

[Service]
Type=oneshot
ExecStart=/lib/systemd/scripts/my-accesspoint.sh -a

[Install]
WantedBy=multi-user.target
/lib/systemd/system/my-accesspoint-down.service:
[Unit]
Description=Accesspoint Down
After=network.target

[Service]
Type=oneshot
ExecStart=/lib/systemd/scripts/my-accesspoint.sh -b

[Install]
WantedBy=multi-user.target
/lib/systemd/system/my-accesspoint-up.timer:
[Unit]
Description=Accesspoint Up Timer
After=my-piface-rtc.service

[Timer]
# Time of day to run the unit
OnCalendar=08:30
# Service to start
Unit=my-accesspoint-up.service

[Install]
WantedBy=multi-user.target
/lib/systemd/system/my-accesspoint-down.timer:
[Unit]
Description=Accesspoint Down Timer
After=my-piface-rtc.service

[Timer]
# Time of day to run the unit
OnCalendar=21:30
# Service to start
Unit=my-accesspoint-down.service

[Install]
WantedBy=multi-user.target
$ systemctl enable my-accesspoint-up.timer
$ systemctl enable my-accesspoint-down.timer

Webserver

Auszug aus /etc/php/php.ini:
[PHP]
open_basedir = /srv/www:/var/lib/php:/usr/share/php:/usr/share/php7.0-common:/usr/share/php7.0-curl:/usr/share/php7.0-json:/usr/share/php7.0-opcache:/usr/share/php7.0-readline:/usr/share/php7.0-sqlite3:/var/spool/mail
disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,system,exec,shell_exec,passthru,phpinfo,show_source,proc_open,popen
file_uploads = Off
allow_url_fopen = Off
allow_url_include = Off

Uhrzeit

PiFace RTC

Folgende Zeile in /boot/config.txt aktivieren:
dtparam=i2c_arm=on
/etc/modules-load.d/piface-rtc.conf:
i2c-dev
i2c:mcp7941x
i2c-bcm2708
/lib/systemd/scripts/my-piface-rtc.sh:
#!/bin/bash

# setup rtc
echo mcp7941x 0x6f > /sys/class/i2c-dev/i2c-1/device/new_device
# set time from hwclock
hwclock -s
/lib/sytemd/system/my-piface-rtc.service:
[Unit]
Description=Run /lib/systemd/scripts/my-piface-rtc.sh
After=systemd-modules-load.service

[Service]
Type=oneshot
#RemainAfterExit=yes
ExecStart=/lib/systemd/scripts/my-piface-rtc.sh

[Install]
WantedBy=multi-user.target
$ systemctl enable my-piface-rtc.service

Webinterface

Abhängigkeiten: highcharts jquery jquery-ui-datepicker (php: sqlite3 curl)

Apache Reverse Proxy

/etc/apache2/mods-available/proxy_http.conf:
<IfModule proxy_http_module>
	ProxyRequests Off

	# Reverse Proxy PVServer / Piko Solar Wechselrichter
	<LocationMatch "^/rproxy/pvserver/(.*)$">
		ProxyPassMatch "http://192.168.1.3/$1"
		Require ip 192.168
	</LocationMatch>

</IfModule>
Ergänzung /etc/apache2/mods-available/proxy.conf:
<IfModule proxy_module>
ProxyPass "/pvserver" "http://pvserver/"
ProxyPassReverse "/pvserver" "http://pvserver/"
<Proxy "*">
  Require ip 192.168
</Proxy>
</IfModule>

Readonly SD-Karte

Verschiedene Tasks von cron entweder deaktivieren (z.b. durch Entfernen der Ausführbarkeit) darunter z.B. dpkg/apt/aptitude backups und man-db.

Auszug aus /etc/apache2/envvars (ggf. Log Dateinamen mit apache2_ prefix versehen - dann aber nicht vergessen logrotate anzupassen):
export APACHE_LOG_DIR=/var/log$SUFFIX
Dateisystem vorbereiten:
$ rm -rf /var/lib/dhcp/ /var/lib/dhcpcd5 /var/lib/misc /etc/resolv.conf
$ ln -s /tmp /var/lib/dhcp
$ ln -s /tmp /var/lib/dhcpcd5
$ ln -s /tmp /var/lib/misc
$ ln -s /tmp/resolv.conf /etc/resolv.conf
/etc/fstab:
# /etc/fstab

proc                  /proc           proc    defaults             0       0
/dev/mmcblk0p1        /boot           vfat    ro,defaults          0       2
/dev/mmcblk0p1        /               ext4    ro,defaults,noatime  0       1
/dev/sda1             /srv            ext4    defaults,noatime     0       0

tmpfs                 /var/spool      tmpfs   nodev,nosuid         0       0
tmpfs                 /var/log        tmpfs   nodev,nosuid         0       0
tmpfs                 /var/tmp        tmpfs   nodev,nosuid         0       0
tmpfs                 /tmp            tmpfs   nodev,nosuid         0       0
An /boot/cmdline.txt anhängen:
fastboot noswap

 
© 2001 - 2020 Frank Remetter