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://github.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.org Python  (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 Supply Switch On/Off Switch for Raspberry Pi, https://github.com/PiSupply/Pi-Supply-Switch