In my previous blog here, I have figured out the basic hardware & software setup for my Powerunit® project. Now Its time to fine tune the Software for my Powerunit® .
Powerunit® Project – Software phase
Now that the everything is working I want to fine tune the software a little bit more, and make it easy installer for everyone. How am I going to do that? by creating a GitHub© repository in this repository I will create an install shell script, so everything will automatically be installed on your Raspberry Pi® how neet is that!
GitHub© repository
Let start by making a new repository on GitHub©. GitHub© is a website and service that we hear geeks rave about all the time, yet a lot of people don’t really understand what it does. GitHub© is a development platform inspired by the way you work. From open source to business, you can host and review code, manage projects, and build software alongside 31 million developers. Once created my GitHub© repository I can start adding my files.
install.sh
You can use the install.sh shell script to Install the Python™ script silently without user interaction. But I included wiptail to debug and to make it more user friendly. What this script does is clone, the files from my GitHub© repository to your Raspberry Pi® the it makes a directory called powerunit and copy’s the powerunit.py into it. The it copy’s the powerunit.service to the systemd folder and make it run when your Raspberry Pi® boots up.
Systemd to Start a Linux Service at Boot
systemd is a Linux system tool initially developed by the Red Hat Linux team. It includes many features, including a bootstrapping system used to start and manage system processes. It is currently the default initialization system on most Linux distributions. Many commonly used software tools, such as SSH and Apache, ship with a systemd service.
It is simple to create a custom systemd service that will run any script or process you choose. Although there are several ways to run a script or start a process when your Raspberry Pi® boots, a custom systemd service makes it easy to start, stop, or restart your script, as well as configure it to start automatically on boot. Systemd offers the advantage of using a standardized interface that is consistent across all Linux distributions that support it.
#!/usr/bin/env bash #Check if script is being run as root if [ "$(id -u)" != "0" ]; then echo "This script must be run as root" 1>&2 exit 1 fi if [ ! $? = 0 ]; then exit 1 else apt-get install -y git whiptail # Installing whiptail to display dialog boxes from shell scripts. PowerunitDir="Powerunit" if [ -d "$PowerunitDir" ]; then whiptail --title "Installation aborted" --msgbox "$PowerunitDir already exists, please remove it and restart the installation" 8 78 exit else git clone https://github.com/AchimPieter/Power.unit.git fi mkdir /opt/Powerunit cp $PowerunitDir/powerunit.py /opt/Powerunit if [ ! -f /opt/Powerunit/Powerunit.py ]; then whiptail --title "Installation aborted" --msgbox "There was a problem writing the Powerunit.py file" 8 78 exit fi cp $PowerunitDir/Powerunit.service /etc/systemd/system if [ ! -f /etc/systemd/system/Powerunit.service ]; then whiptail --title "Installation aborted" --msgbox "There was a problem writing the Powerunit.service file" 8 78 exit fi systemctl enable /etc/systemd/system/Powerunit.service whiptail --title "Installation complete" --msgbox "Power.unit® installation complete. \nThe system will power off. \nCopyright 2019 StudioPieters®" 8 78 poweroff fi
Powerunit.py
Then I have added the Python™ script from my previous blog here with some minor adjustments (remember, it’s all still in testing phase).
This script need to start at boot up of your Raspberry Pi®. This Python™ script monitors if a GPIO pin of your Raspberry Pi® is LOW of changes to HIGH. When it turns from LOW to HIGH it will start a software “PowerOff” of your Raspberry Pi®.
#!/usr/bin/env python # Import the modules to send commands to the system and access GPIO pins. from subprocess import call import RPi.GPIO as GPIO from time import sleep # Map PinEleven and PinThirteen on the Power.unit PCB to chosen pins on the Raspberry Pi header. # The PCB numbering is a legacy with the original design of the board. PinEleven = 11 PinThirteen = 13 GPIO.setmode(GPIO.BOARD) # Set pin numbering to board numbering. GPIO.setup(PinEleven, GPIO.IN) # Set up PinEleven as an input. GPIO.setup(PinThirteen, GPIO.OUT, GPIO.HIGH) # Setup PinThirteen as output for the LED. while (GPIO.input(PinEleven) == True): # While button not pressed GPIO.wait_for_edge(PinEleven, GPIO.RISING) # Wait for a rising edge on PinSeven sleep(0.1); # Sleep 100ms to avoid triggering a shutdown when a spike occured if (GPIO.input(PinEleven) == True): GPIO.output(PinThirteen,GPIO.LOW) # Bring down PinThirteen so that the LED will turn off. GPIO.cleanup() # clean up any resources we have used. call('poweroff', shell=False) # Initiate OS Poweroff else: call('reboot', shell=False) # Initiate OS Reboot
Powerunit.service
To start the Python™ script at boot up of your Raspberry Pi® You need a service script. I made a script called powerunit.service this defines a simple start up service. The critical part is the ExecStart directive, which specifies the command that will be run to start the service.
[Unit] Description=Starts Power.unit for Power.unit PCB Requires=local-fs.target [Service] Type=simple ExecStart=/opt/Powerunit/Powerunit.py WorkingDirectory=/opt/Powerunit/ [Install] WantedBy=multi-user.target
Attiny85 Code
The Attiny85 part is really strait forward it’s based on a “simple” State Change Detection (Edge Detection) for a push button. For now this is working fine. Maybe I can add something more later, and use the full potential of the ATTiny. Maybe a little hardware change… But more about that later.
/* Project name: Powerunit® Project URI: https://www.studiopieters.nl/raspberry-pi-power-unit Description: Powerunit® - Atmel® ATTiny85 Software package Version: 3.9.2 License: MIT - Copyright 2018 StudioPieters. (https://opensource.org/licenses/MIT) */ int RelaisPin = 0; // ATTINY85/13A (PB0 / Physical Pin 5) int PinSeven = 1; // ATTINY85/13A (PB1 / Physical Pin 6) int ButtonPin = 2; // ATTINY85/13A (PB2 / Physical Pin 7) boolean OldRelaisState = LOW; // variable to hold the OLD Relais state boolean NewRelaisState = LOW; // variable to hold the NEW Relais state boolean Relaisstatus = LOW; // variable to hold the Relais state void setup() { pinMode(RelaisPin, OUTPUT); // Set Relaispin as Output digitalWrite(RelaisPin, LOW); // Set Relaispin to LOW pinMode(PinSeven, OUTPUT); // Set PinSeven as Output digitalWrite(PinSeven, LOW); // Set PinSeven to LOW pinMode(ButtonPin, INPUT); // Set Buttonpin as Input } void loop() { NewRelaisState = digitalRead(ButtonPin); if ( NewRelaisState != OldRelaisState ) { if ( NewRelaisState == HIGH ) { if ( Relaisstatus == LOW ) { digitalWrite(RelaisPin, HIGH); // Set Relaispin to HIGH digitalWrite(PinSeven, HIGH); // Set PinSeven to HIGH Relaisstatus = HIGH; } else { digitalWrite(PinSeven, LOW); // Set PinSeven to LOW delay(30000); // wait for 30 Seconds to shutdown all services on your Pi digitalWrite(RelaisPin, LOW); // Set Relaispin to LOW Relaisstatus = LOW; } } OldRelaisState = NewRelaisState; } }
uninstall.sh
Not only can you use the install.sh shell script to Install the Python™ script silently. You can also make a Uninstall script to cleaning everything up. So I did!
#!/usr/bin/env bash #Check if script is being run as root if [ "$(id -u)" != "0" ]; then echo "This script must be run as root" 1>&2 exit 1 fi if [ ! $? = 0 ]; then exit 1 else systemctl stop Powerunit.service systemctl disable /etc/systemd/Powerunit.service rm /opt/Powerunit/Powerunit.py rm /opt/Powerunit -d rm /etc/systemd/system/Powerunit.service rm -rf powerunit whiptail --title "Uninstall complete" --msgbox "Powerunit® Uninstallation complete. \nThe system will power off. \nCopyright 2019 StudioPieters®.\nYou are safe to remove the folder Power.unit." 8 78 fi
Powerunit® Installation
Login via SSH and run the following command and Powerunit͘® will be installed.
curl -sSL https://raw.githubusercontent.com/AchimPieters/powerunit/master/install.sh | sudo bash
How do I know if the service is running properly?
Run the following command
systemctl status powerunit.service
which should return something like, but it does not…
• powerunit.service - Starts powerunit for Powerunit pcb Loaded: loaded (/etc/systemd/system/powerunit.service; enabled) Active: active (running) since Thu 2017-06-29 09:56:13 UTC; 6min ago Main PID: 427 (python) CGroup: /system.slice/powerunit.service └─427 python /opt/powerunit/powerunit.py
Im getting:
• powerunit.service - Starts powerunit for Powerunit pcb Loaded: loaded (/etc/systemd/system/powerunit.service; enabled) Active: Failed ((Result: exit-code) since Thu 2017-06-29 09:56:13 UTC; 6min ago Main PID: 427 (python)(code=exited, status=203/EXEC)
Sh#t! Time to figure out what went wrong and why…
You can read about the solution here…
REFERENCE
Raspberry Pi® (2019), The Raspberry Pi is a tiny and affordable computer that you can use to learn programming through fun, practical projects, https://www.raspberrypi.orgPython™ (2019 )Python is a programming language that lets you work quickly and integrate systems more effectively, https://www.python.org/ PiSupply (DEC 5 2017), Pi-Supply-Switch, Pi Sup