Archive
Python Daemon
There can only be one daemon process running: that is managed by the PID lock file, like most other Linux daemons. To stop it, do
kill `cat /var/run/eg_daemon.pid`
To see if it is running:
ps -elf | grep `cat /var/run/eg_daemon.pid`
Using the pidfile submodule, the PID file is managed automatically. When the daemon is stopped, the pidfile is cleared up. Please see the linked GitHub repo for the init script.
Here’s the Python daemon code:
#!/usr/bin/env python3.5
import sys
import os
import time
import argparse
import logging
import daemon
from daemon import pidfile
debug_p = False
def do_something(logf):
### This does the "work" of the daemon
logger = logging.getLogger('eg_daemon')
logger.setLevel(logging.INFO)
fh = logging.FileHandler(logf)
fh.setLevel(logging.INFO)
formatstr = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
formatter = logging.Formatter(formatstr)
fh.setFormatter(formatter)
logger.addHandler(fh)
while True:
logger.debug("this is a DEBUG message")
logger.info("this is an INFO message")
logger.error("this is an ERROR message")
time.sleep(5)
def start_daemon(pidf, logf):
### This launches the daemon in its context
### XXX pidfile is a context
with daemon.DaemonContext(
working_directory='/var/lib/eg_daemon',
umask=0o002,
pidfile=pidfile.TimeoutPIDLockFile(pidf),
) as context:
do_something(logf)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Example daemon in Python")
parser.add_argument('-p', '--pid-file', default='/var/run/eg_daemon.pid')
parser.add_argument('-l', '--log-file', default='/var/log/eg_daemon.log')
args = parser.parse_args()
start_daemon(pidf=args.pid_file, logf=args.log_file)
For completeness’ sake, here is the init script. Note that “kill” is really just a method for sending a POSIX signal — see man page for signal(7) for an overview. The python-daemon context will catch the signal, terminate the process cleanly closing file descriptors, and delete the PID file automatically. So, it really is a clean termination.
You can write your code to catch SIGUSR1 or something similar, in order to do a reload of the daemon config. There is no advantage to writing Python stop the daemon.
#!/bin/bash
#
# eg_daemon Startup script for eg_daemon
#
# chkconfig: - 87 12
# description: eg_daemon is a dummy Python-based daemon
# config: /etc/eg_daemon/eg_daemon.conf
# config: /etc/sysconfig/eg_daemon
# pidfile: /var/run/eg_daemon.pid
#
### BEGIN INIT INFO
# Provides: eg_daemon
# Required-Start: $local_fs
# Required-Stop: $local_fs
# Short-Description: start and stop eg_daemon server
# Description: eg_daemon is a dummy Python-based daemon
### END INIT INFO
# Source function library.
. /etc/rc.d/init.d/functions
if [ -f /etc/sysconfig/eg_daemon ]; then
. /etc/sysconfig/eg_daemon
fi
eg_daemon=/var/lib/eg_daemon/eg_daemon.py
prog=eg_daemon
pidfile=${PIDFILE-/var/run/eg_daemon.pid}
logfile=${LOGFILE-/var/log/eg_daemon.log}
RETVAL=0
OPTIONS=""
start() {
echo -n $"Starting $prog: "
if [[ -f ${pidfile} ]] ; then
pid=$( cat $pidfile )
isrunning=$( ps -elf | grep $pid | grep $prog | grep -v grep )
if [[ -n ${isrunning} ]] ; then
echo $"$prog already running"
return 0
fi
fi
$eg_daemon -p $pidfile -l $logfile $OPTIONS
RETVAL=$?
[ $RETVAL = 0 ] && success || failure
echo
return $RETVAL
}
stop() {
if [[ -f ${pidfile} ]] ; then
pid=$( cat $pidfile )
isrunning=$( ps -elf | grep $pid | grep $prog | grep -v grep | awk '{print $4}' )
if [[ ${isrunning} -eq ${pid} ]] ; then
echo -n $"Stopping $prog: "
kill $pid
else
echo -n $"Stopping $prog: "
success
fi
RETVAL=$?
fi
echo
return $RETVAL
}
reload() {
echo -n $"Reloading $prog: "
echo
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status -p $pidfile $eg_daemon
RETVAL=$?
;;
restart)
stop
start
;;
force-reload|reload)
reload
;;
*)
echo $"Usage: $prog {start|stop|restart|force-reload|reload|status}"
RETVAL=2
esac
exit $RETVAL
Control Arduino from Raspberry Pi with pyFirmata
Requirements
- Raspberry Pi with Raspbian OS installed in it
- Arduino Uno or any other Arduino board
- Arduino USB cable
- LED
Installing PyFirmata in Arduino using Raspberry Pi
To upload PyFirmata firmware in Arduino, we have to install Arduino IDE in Raspberry Pi. Follow these steps to install:
Step 1:- Connect the Raspberry Pi to the internet. Open command terminal and type the following command and hit enter
sudo apt-get -y install arduino python-serial mercurial
Wait for few minutes, it will take time. This command will install the Arduino IDE in your Raspberry Pi.
Step 2:- Now, we will install pyFirmata files using the given github:
git clone https://github.com/tino/pyFirmata
Then run the following command:
cd pyFirmata sudo python setup.py install
Step 3:- We have installed all the required files and setups.
Now, connect your Arduino board with Raspberry Pi using USB cable and launch Arduino IDE by typing arduino in terminal window.
Step 4:- Then type lsusb command to check whether Arduino is connected with your raspberry pi.
In Arduino IDE, Go to tools and choose your board and Serial Port.
Step 5:- Upload the PyFirmata firmware on the Arduino by clicking File -> Examples -> Firmata -> Standard Firmata and then click upload button . As shown below.
We have successfully installed the pyFirmata firmware in the Arduino board. Now, we can control our Arduino using Raspberry Pi.
For demonstration we will blink and fade an LED on the Arduino by writing python codes in Raspberry Pi.
Code Explanation
For coding part, you should read documentation of pyFirmata for better understanding. We will use pyFirmata functions to write our code. You can find pyFirmata documentation by following the link.
So let’s start writing the code
Open your favorite text editor on the Raspberry Pi and import pyFirmata library.
import pyfirmata
Define pin on the Arduino to connect the LED
led_pin = 9
Now, we have to write serial port name on which Arduino board is connected using pyfirmata.Arduino() function and then make an instance by assigning port in board variable.
board = pyfirmata.Arduino("/dev/ttyACM0") print "Code is running”
In while loop, make led pin HIGH and low using board.digital[].write() function and give delay using board.pass_time() function.
while True: board.digital[led_pin].write(0) board.pass_time(1) board.digital[led_pin].write(1) board.pass_time(1)
Our code is ready, save this code by putting .py extension to the file name.
Open command terminal and type python blink.py to run the code on the Arduino board. Make sure your Arduino board is connected with your Raspberry Pi board using USB cable.
Now, you can see Blinking LED on the Arduino board.
Complete code for blinking LED using pyFirmata is given at the end.
Fading LED on Arduino using pyFirmata
Now, we will write code for fading the LED to make you more familiar with the pyFirmata functions. This code is easy as previous one. You have to use two for loops, one for increase brightness and other for decrease brightness.
In this code, we have defined the pins in different way like led = board.get_pin(‘d:9:p’) where d means digital pin. This is function of pyFirmata library. Read the documentation for more details.
Complete code for Fading LED using pyFirmata is given at the end.
Now, you can add more sensors to your system and make it more cool, check our other Arduino projects and try building them using Raspberry pi and python script.
Python code for LED blink:
import pyfirmata led_pin = 9 board = pyfirmata.Arduino("/dev/ttyACM0") while True: board.digital[led_pin].write(0) board.pass_time(1) board.digital[led_pin].write(1) board.pass_time(1)
Python code for Fading LED:
import time import pyfirmata delay = 0.3 brightness = 0 board = pyfirmata.Arduino("/dev/ttyACM0") led = board.get_pin('d:9:p') while True: # increase for i in range(0, 10): brightness = brightness + 0.1 print "Setting brightness to %s" % brightness led.write(brightness) board.pass_time(delay) # decrease for i in range(0, 10): print "Setting brightness to %s" % brightness led.write(brightness) brightness = brightness - 0.1 board.pass_time(delay)
Arduino and cpp files
You can create an Arduino project in which you have a main .ino file with setup() and loop(), but all the stuff in .h and .cpp files.
Simple debounce.js function minified
export default function debounce(a,b,c){var d,e;return function(){function h(){d=null,c||(e=a.apply(f,g))}var f=this,g=arguments;return clearTimeout(d),d=setTimeout(h,b),c&&!d&&(e=a.apply(f,g)),e}}