Raspberry Pi - MCP Relay Control & Monitor

Part 1: General setup

  • run raspbian-ua-netinst on SD card (default install - server packages of debian wheezy)
  • SSH in as root…
passwd
> /etc/motd
echo rpi-relaycontrol > /etc/hostname
sed -i s/pi/rpi-relaycontrol/g /etc/hosts
echo "America/Chicago" > /etc/timezone
dpkg-reconfigure -f noninteractive tzdata
sed -i -e 's/^# en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen
dpkg-reconfigure -f noninteractive locales
apt-get update
apt-get --no-install-recommends install aptitude
#aptitude install linux-image-rpi-rpfv raspberrypi-bootloader-nokernel
#cp /boot/vmlinuz-* /boot/kernel.img
# the rpi foundation version is less buggy, although distributed in a more annoying way
# however, the installer pins the non-foundation version, so we have to get rid of that
# commenting out lines in apt preferences files seems to be problematic, so we just delete it
rm /etc/apt/preferences.d/01vcgencmd.pref
aptitude install raspberrypi-bootloader
echo 'blacklist spi-bcm2708' > /etc/modprobe.d/raspi-blacklist.conf
echo 'blacklist i2c-bcm2708' >> /etc/modprobe.d/raspi-blacklist.conf
echo 'blacklist snd-soc-bcm2708-i2s' >> /etc/modprobe.d/raspi-blacklist.conf
sed -i -e 's/^snd-bcm2835/#snd-bcm2835/g' /etc/modules
echo 'vm.min_free_kbytes = 4096' > /etc/sysctl.d/raspi-eth0_fix.conf # see http://wiki.gentoo.org/wiki/Raspberry_Pi#Troubleshooting
aptitude install raspi-copies-and-fills
aptitude install libraspberrypi-bin fbset
# this is a default config.txt file - just comments, no settings:
wget -O /boot/config.txt https://raw.githubusercontent.com/Evilpaul/RPi-config/master/config.txt
sed -i 's/#boot_delay=0/boot_delay=0/g' /boot/config.txt
aptitude install netcat-traditional screen rsync psmisc file patch ethtool strace tcpdump vim
aptitude --without-recommends install dnsutils
aptitude install dosfstools

aptitude install watchdog
sed -i -e 's/^watchdog_module="none"/watchdog_module="bcm2708_wdog"/g' /etc/default/watchdog
sed -i -e 's/^#watchdog-device/watchdog-device/g' /etc/watchdog.conf
sed -i -e 's/^#max-load-1\t/max-load-1\t/g' /etc/watchdog.conf
echo "# Raspberry Pi doesn't work with the default timeout of 60; set it to 10 instead" >> /etc/watchdog.conf
echo $'watchdog-timeout\t= 10' >> /etc/watchdog.conf

aptitude --without-recommends install kbd

adduser tdobes
adduser tdobes adm

Part 2: Wireless

aptitude --without-recommends install ifplugd wpasupplicant
aptitude install ifmetric iw wireless-tools
sed -i -e 's/raspbian wheezy main firmware$/raspbian wheezy main firmware non-free/g' /etc/apt/sources.list
aptitude update
aptitude forget-new
aptitude install firmware-ralink firmware-atheros
sed -i -e 's/^REGDOMAIN=$/REGDOMAIN=US/g' /etc/default/crda
sed -i -e 's/^INTERFACES=""/INTERFACES="eth0"/g' /etc/default/ifplugd
#we don't set HOTPLUG_INTERFACES because wireless interfaces are already handled by udev
#sed -i -e 's/^HOTPLUG_INTERFACES=""/HOTPLUG_INTERFACES="all"/g' /etc/default/ifplugd
sed -i -e 's/^auto eth0/#allow-hotplug eth0/g' /etc/network/interfaces
# this is needed so that we don't run an ifplugd for the lo interface while using HOTPLUG_INTERFACES:
echo 'SUBSYSTEM=="net", KERNEL!="lo", RUN+="ifplugd.agent"' > /etc/udev/rules.d/60-ifplugd.rules
/etc/init.d/ifplugd restart

echo 'allow-hotplug wlan0' >> /etc/network/interfaces
echo 'iface wlan0 inet manual' >> /etc/network/interfaces
echo 'wpa-driver nl80211,wext' >> /etc/network/interfaces
echo 'wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf' >> /etc/network/interfaces
echo '# not supported on realtek dongle:' >> /etc/network/interfaces
echo '#pre-up iwconfig $IFACE power off' >> /etc/network/interfaces
echo 'iface mcp inet dhcp' >> /etc/network/interfaces
echo 'metric 1' >> /etc/network/interfaces
cat > /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
  ssid="mcp-2.4"
  scan_ssid=1
  psk="***PASSWORD***"
  priority="9"
  id_str="mcp"
}

network={
  ssid="mcp-5.8"
  scan_ssid=1
  psk="***PASSWORD***"
  priority="10"
  id_str="mcp"
}
^D

Part 3: Relay Control

sed -i -e 's/^blacklist i2c-bcm2708/#blacklist i2c-bcm2708/g' /etc/modprobe.d/raspi-blacklist.conf
echo >> /etc/modules
echo i2c-bcm2708 >> /etc/modules
echo i2c-dev >> /etc/modules

aptitude install python-smbus
aptitude install mosquitto-clients python-mosquitto

** put files in /opt/mqtt_relay_control

echo '[Unit]' > /etc/systemd/system/mqtt_relay_control.service
echo 'Description=Monitor and control relays through MQTT' >> /etc/systemd/system/mqtt_relay_control.service
echo 'After=network.target' >> /etc/systemd/system/mqtt_relay_control.service
echo >> /etc/systemd/system/mqtt_relay_control.service
echo '[Service]' >> /etc/systemd/system/mqtt_relay_control.service
echo 'ExecStart=/opt/mqtt_relay_control/relay_power_app.py' >> /etc/systemd/system/mqtt_relay_control.service
echo 'WorkingDirectory=/opt/mqtt_relay_control' >> /etc/systemd/system/mqtt_relay_control.service
echo 'User=root' >> /etc/systemd/system/mqtt_relay_control.service # TODO: figure out how to run do smbus communication as non-root
echo 'Environment=PYTHONUNBUFFERED=1' >> /etc/systemd/system/mqtt_relay_control.service
#echo 'RuntimeDirectory=mqtt_relay_control' >> /etc/systemd/system/mqtt_relay_control.service
#echo 'RuntimeDirectoryMode=0755' >> /etc/systemd/system/mqtt_relay_control.service
echo >> /etc/systemd/system/mqtt_relay_control.service
echo 'Restart=always' >> /etc/systemd/system/mqtt_relay_control.service
echo 'RestartSec=1' >> /etc/systemd/system/mqtt_relay_control.service
echo 'StartLimitInterval=10s' >> /etc/systemd/system/mqtt_relay_control.service
echo 'StartLimitBurst=10' >> /etc/systemd/system/mqtt_relay_control.service
echo >> /etc/systemd/system/mqtt_relay_control.service
echo '[Install]' >> /etc/systemd/system/mqtt_relay_control.service
echo 'WantedBy=multi-user.target' >> /etc/systemd/system/mqtt_relay_control.service

systemctl enable mqtt_relay_control
systemctl start mqtt_relay_control

# only exists while program is running; /run/ subdirectory created by systemd through RuntimeDirectory directive
#ln -sf /run/mqtt_relay_control/relay_status.txt /var/www/relay_status.txt

# TODO: After upgrading systemd, uncomment RuntimeDirectory lines and symlink from /run/... remove symlink from /tmp/ below and update python source code to use new location

ln -sf /tmp/relay_status.txt /var/www/relay_status.txt




# MCP Apt Proxy
echo 'Acquire::http { Proxy "http://apt.mcp.lcl:3142"; };' > /etc/apt/apt.conf.d/mcp-proxy

** add quiet to the end of /boot/cmdline.txt

Part 4: Temperature Logger

aptitude install picocom python-serial usbutils
** put files in /opt/temperature_logger

TODO: FINISH ME



Part 5: General systemd + Wheezy hacks

aptitude install systemd dbus
** add init=/bin/systemd to the end of /boot/cmdline.txt
reboot

## NOTE:  Most of these hacks won't be needed in Jessie.

ln -s `which systemd-journalctl` /usr/local/bin/journalctl

echo '[Unit]' > /etc/systemd/system/cron.service
echo 'Description=Regular background program processing daemon' >> /etc/systemd/system/cron.service
echo >> /etc/systemd/system/cron.service
echo '[Service]' >> /etc/systemd/system/cron.service
echo 'ExecStart=/usr/sbin/cron -f' >> /etc/systemd/system/cron.service
echo >> /etc/systemd/system/cron.service
echo '[Install]' >> /etc/systemd/system/cron.service
echo 'WantedBy=multi-user.target' >> /etc/systemd/system/cron.service
echo '[Unit]' > /etc/systemd/system/ntp.service
echo 'Description=Network Time Protocol daemon' >> /etc/systemd/system/ntp.service
echo 'After=network.target' >> /etc/systemd/system/ntp.service
echo >> /etc/systemd/system/ntp.service
echo '[Service]' >> /etc/systemd/system/ntp.service
echo 'ExecStart=/usr/sbin/ntpd -n -g -u ntp:ntp' >> /etc/systemd/system/ntp.service
echo >> /etc/systemd/system/ntp.service
echo '[Install]' >> /etc/systemd/system/ntp.service
echo 'WantedBy=multi-user.target' >> /etc/systemd/system/ntp.service
echo '[Unit]' > /etc/systemd/system/ssh.service
echo 'Description=OpenBSD Secure Shell server' >> /etc/systemd/system/ssh.service
echo 'After=network.target auditd.service' >> /etc/systemd/system/ssh.service
echo 'ConditionPathExists=!/etc/ssh/sshd_not_to_be_run' >> /etc/systemd/system/ssh.service
echo >> /etc/systemd/system/ssh.service
echo '[Service]' >> /etc/systemd/system/ssh.service
echo 'EnvironmentFile=-/etc/default/ssh' >> /etc/systemd/system/ssh.service
echo 'ExecStart=/usr/sbin/sshd -D $SSHD_OPTS' >> /etc/systemd/system/ssh.service
echo 'ExecReload=/bin/kill -HUP $MAINPID' >> /etc/systemd/system/ssh.service
echo 'KillMode=process' >> /etc/systemd/system/ssh.service
echo 'Restart=on-failure' >> /etc/systemd/system/ssh.service
echo >> /etc/systemd/system/ssh.service
echo '[Install]' >> /etc/systemd/system/ssh.service
echo 'WantedBy=multi-user.target' >> /etc/systemd/system/ssh.service
echo 'Alias=sshd.service' >> /etc/systemd/system/ssh.service
echo '[Unit]' > /etc/systemd/system/ssh\@.service
echo 'Description=OpenBSD Secure Shell server per-connection daemon' >> /etc/systemd/system/ssh\@.service
echo 'After=auditd.service' >> /etc/systemd/system/ssh\@.service
echo >> /etc/systemd/system/ssh\@.service
echo '[Service]' >> /etc/systemd/system/ssh\@.service
echo 'EnvironmentFile=-/etc/default/ssh' >> /etc/systemd/system/ssh\@.service
echo 'ExecStart=-/usr/sbin/sshd -i $SSHD_OPTS' >> /etc/systemd/system/ssh\@.service
echo 'StandardInput=socket' >> /etc/systemd/system/ssh\@.service
echo '[Unit]' > /etc/systemd/system/ssh.socket
echo 'Description=OpenBSD Secure Shell server socket' >> /etc/systemd/system/ssh.socket
echo 'Before=ssh.service' >> /etc/systemd/system/ssh.socket
echo 'Conflicts=ssh.service' >> /etc/systemd/system/ssh.socket
echo 'ConditionPathExists=!/etc/ssh/sshd_not_to_be_run' >> /etc/systemd/system/ssh.socket
echo >> /etc/systemd/system/ssh.socket
echo '[Socket]' >> /etc/systemd/system/ssh.socket
echo 'ListenStream=22' >> /etc/systemd/system/ssh.socket
echo 'Accept=yes' >> /etc/systemd/system/ssh.socket
echo >> /etc/systemd/system/ssh.socket
echo '[Install]' >> /etc/systemd/system/ssh.socket
echo 'WantedBy=sockets.target' >> /etc/systemd/system/ssh.socket
echo 'd /var/run/sshd 0755 root root' > /etc/tmpfiles.d/sshd.conf

systemctl enable cron.service
systemctl enable ntp.service
systemctl disable ssh.service
systemctl enable ssh.socket

systemctl mask rc.local.service # seems buggy - replace with custom service files
systemctl disable rsyslog.service # disable to reduce writes to sd card
systemctl disable wpa_supplicant.service # unnecessary; started automatically
systemctl mask wd_keepalive.service # apparently conflicts with startup of watchdog because watchdog init script doesn't stop it successfully

systemctl stop rsyslog.service
rm /var/log/auth.log* /var/log/daemon.log* /var/log/debug /var/log/kern.log* /var/log/messages /var/log/user.log*

# Updates to systemd and udev should make these hacks unnecessary under Jessie, but Wheezy needs them
# udev should send "stop" commands to systemd; not just start commands... also ensure that systemctl only gets called for interfaces set as "auto" or "allow-hotplug"
# We also send the stop command to systemd even if ifdown is already running to avoid a race condition with wpa_supplicant
cp -a /lib/udev/net.agent /etc/udev/
echo '--- /etc/udev/net.agent' > /tmp/udev_net_unplug_systemd.patch
echo '+++ /etc/udev/net.agent.new' >> /tmp/udev_net_unplug_systemd.patch
echo '@@ -48,7 +48,11 @@' >> /tmp/udev_net_unplug_systemd.patch
echo ' ' >> /tmp/udev_net_unplug_systemd.patch
echo '     wait_for_interface lo' >> /tmp/udev_net_unplug_systemd.patch
echo '     if [ -e /sys/fs/cgroup/systemd ]; then' >> /tmp/udev_net_unplug_systemd.patch
echo '-      exec systemctl start ifup@${INTERFACE}.service' >> /tmp/udev_net_unplug_systemd.patch
echo "+      if grep -q '"'^\(allow-hotplug\|auto\)[[:space:]].*\<'"'"'"$INTERFACE"'"'"'\>'"'"' \' >> /tmp/udev_net_unplug_systemd.patch
echo '+            /etc/network/interfaces; then' >> /tmp/udev_net_unplug_systemd.patch
echo '+        # this $INTERFACE is marked as "allow-hotplug" or "auto"' >> /tmp/udev_net_unplug_systemd.patch
echo '+        exec systemctl start ifup@${INTERFACE}.service' >> /tmp/udev_net_unplug_systemd.patch
echo '+      fi' >> /tmp/udev_net_unplug_systemd.patch
echo '     else' >> /tmp/udev_net_unplug_systemd.patch
echo '       exec ifup --allow=hotplug $INTERFACE' >> /tmp/udev_net_unplug_systemd.patch
echo '     fi' >> /tmp/udev_net_unplug_systemd.patch
echo '@@ -57,12 +61,16 @@' >> /tmp/udev_net_unplug_systemd.patch
echo ' net_ifdown() {' >> /tmp/udev_net_unplug_systemd.patch
echo '     check_program /sbin/ifdown' >> /tmp/udev_net_unplug_systemd.patch
echo ' ' >> /tmp/udev_net_unplug_systemd.patch
echo '-    if ps -C ifdown ho args | grep -q $INTERFACE; then' >> /tmp/udev_net_unplug_systemd.patch
echo '+    if [ -e /sys/fs/cgroup/systemd ]; then' >> /tmp/udev_net_unplug_systemd.patch
echo '+      exec systemctl stop ifup@${INTERFACE}.service' >> /tmp/udev_net_unplug_systemd.patch
echo '+    else' >> /tmp/udev_net_unplug_systemd.patch
echo '+      if ps -C ifdown ho args | grep -q $INTERFACE; then' >> /tmp/udev_net_unplug_systemd.patch
echo $' \t''debug_mesg "Already ifdown-ing interface $INTERFACE"' >> /tmp/udev_net_unplug_systemd.patch
echo $' \texit 0' >> /tmp/udev_net_unplug_systemd.patch
echo '-    fi' >> /tmp/udev_net_unplug_systemd.patch
echo '+      fi' >> /tmp/udev_net_unplug_systemd.patch
echo ' ' >> /tmp/udev_net_unplug_systemd.patch
echo '-    exec ifdown --allow=hotplug $INTERFACE' >> /tmp/udev_net_unplug_systemd.patch
echo '+      exec ifdown --allow=hotplug $INTERFACE' >> /tmp/udev_net_unplug_systemd.patch
echo '+    fi' >> /tmp/udev_net_unplug_systemd.patch
echo ' }' >> /tmp/udev_net_unplug_systemd.patch
echo ' ' >> /tmp/udev_net_unplug_systemd.patch
echo ' do_everything() {' >> /tmp/udev_net_unplug_systemd.patch
patch -p0 < /tmp/udev_net_unplug_systemd.patch && rm /tmp/udev_net_unplug_systemd.patch
cp -a /lib/udev/rules.d/80-networking.rules /etc/udev/rules.d/
sed -i 's/RUN+="net.agent"/RUN+="\/etc\/udev\/net.agent"/g' /etc/udev/rules.d/80-networking.rules

# ifplugd should start up / shut down interfaces using systemd, not calling ifupdown directly
# ideally, this would work... but we have to comment out allow-hotplug in /etc/network/interfaces to prevent udev from ifup'ing eth0... and ifup@.service passes --allow=hotplug to ifup, which prevents this from working
# ...so I gave up and just let ifup run in the ifplugd service instead
#echo '--- /etc/ifplugd/action.d/ifupdown' > /tmp/ifplugd_systemd.patch
#echo '+++ /etc/ifplugd/action.d/ifupdown.new' >> /tmp/ifplugd_systemd.patch
#echo '@@ -3,9 +3,17 @@' >> /tmp/ifplugd_systemd.patch
#echo ' ' >> /tmp/ifplugd_systemd.patch
#echo ' case "$2" in' >> /tmp/ifplugd_systemd.patch
#echo ' up)' >> /tmp/ifplugd_systemd.patch
#echo $'-\t/sbin/ifup $1' >> /tmp/ifplugd_systemd.patch
#echo $'+\tif [ -e /sys/fs/cgroup/systemd ]; then' >> /tmp/ifplugd_systemd.patch
#echo $'+\t\t/bin/systemctl start ifup@$1.service' >> /tmp/ifplugd_systemd.patch
#echo $'+\telse' >> /tmp/ifplugd_systemd.patch
#echo $'+\t\t/sbin/ifup $1' >> /tmp/ifplugd_systemd.patch
#echo $'+\tfi' >> /tmp/ifplugd_systemd.patch
#echo $' \t;;' >> /tmp/ifplugd_systemd.patch
#echo ' down)' >> /tmp/ifplugd_systemd.patch
#echo $'-\t/sbin/ifdown $1' >> /tmp/ifplugd_systemd.patch
#echo $'+\tif [ -e /sys/fs/cgroup/systemd ]; then' >> /tmp/ifplugd_systemd.patch
#echo $'+\t\t/bin/systemctl stop ifup@$1.service' >> /tmp/ifplugd_systemd.patch
#echo $'+\telse' >> /tmp/ifplugd_systemd.patch
#echo $'+\t\t/sbin/ifdown $1' >> /tmp/ifplugd_systemd.patch
#echo $'+\tfi' >> /tmp/ifplugd_systemd.patch
#echo $' \t;;' >> /tmp/ifplugd_systemd.patch
#echo ' esac' >> /tmp/ifplugd_systemd.patch
#patch -p0 < /tmp/ifplugd_systemd.patch && rm /tmp/ifplugd_systemd.patch

cp -a /lib/systemd/system/getty\@.service /etc/systemd/system/
sed -i 's/ExecStart=-\/sbin\/agetty %I 38400/ExecStart=-\/sbin\/agetty --noclear %I 38400/g' /etc/systemd/system/getty\@.service
sed -i 's/TTYVTDisallocate=yes/#TTYVTDisallocate=yes/g' /etc/systemd/system/getty\@.service
mkdir /etc/systemd/system/getty.target.wants
ln -sf /etc/systemd/system/getty\@.service /etc/systemd/system/getty.target.wants/getty\@tty1.service

systemctl mask networking.service # we use ifplugd instead
systemctl mask kbd.service # this doesn't seem to work anyway
echo 'D /run/network 0755 root root' > /etc/tmpfiles.d/debian-networking.conf
echo 'F /run/network/ifstate 0644 root root - lo=lo' >> /etc/tmpfiles.d/debian-networking.conf

See also: http://blog.higgsboson.tk/2012/09/19/systemd-on-raspbian/

Part 6: systemd / relay, temperature log, and customization

TODO
computer/raspberry_pi_mcp-relay.txt · Last modified: 2018/11/10 11:38 by tdobes
Recent changes RSS feed Driven by DokuWiki Valid XHTML 1.0 Valid CSS