Stephen C Phillips' blog - Latest Commentshttp://scphillips.disqus.com/enWed, 07 Dec 2016 17:50:10 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-3041315186<p>Many thanks for inducting me in to the dark art of services! I have struggled to find my own way in the past. Your article is a great example of how to demonstrate an advanced subject to acolyte users in a manner that is technical where required yet simple enough to understand and follow the process. My service (mqtt / moscuitto temperature status) ran (and kept running!) on the first attempt.</p><p>Cheers</p><p>Tom</p>Tom StrattonWed, 07 Dec 2016 17:50:10 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-3037517582<p>Hello Stephen, <br>I am running a RasPi3 with Jessie and ran across this post for creating a Daemon. I have a py script that retrieves some weather data from NOAA and scrolls it across an LED matrix display. I have tried to follow your directions explicitly however I am unable to get my script to run successfully as a daemon.<br>I followed your troubleshooting pointers and am able to run my py script stand-alone. I am able to start/stop/status my shell with the following results:</p><p>pi@METAR-Pi:/etc/init.d $ start-stop-daemon --start --exec /etc/init.d/<a href="http://metartext.sh" rel="nofollow noopener">metartext.sh</a><br>Usage: /etc/init.d/metartext {start|stop|restart|status}<br>pi@METAR-Pi:/etc/init.d $ sudo /etc/init.d/<a href="http://metartext.sh" rel="nofollow noopener">metartext.sh</a> start<br>[ ok ] Starting <a href="http://metartext.sh" rel="nofollow noopener">metartext.sh</a> (via systemctl): metartext.service.<br>pi@METAR-Pi:/etc/init.d $ sudo /etc/init.d/<a href="http://metartext.sh" rel="nofollow noopener">metartext.sh</a> status<br>● metartext.service - LSB: Scrolling METAR display<br> Loaded: loaded (/etc/init.d/<a href="http://metartext.sh" rel="nofollow noopener">metartext.sh</a>)<br> Active: active (exited) since Mon 2016-12-05 20:43:14 CST; 1h 18min ago<br>Dec 05 20:43:12 METAR-Pi systemd[1]: Starting LSB: Scrolling METAR display...<br>Dec 05 20:43:14 METAR-Pi systemd[1]: Started LSB: Scrolling METAR display.<br>Dec 05 20:43:14 METAR-Pi <a href="http://metartext.sh" rel="nofollow noopener">metartext.sh</a>[451]: Starting system metartext daemon:.<br>Dec 05 20:52:54 METAR-Pi systemd[1]: Started LSB: Scrolling METAR display.<br>Dec 05 22:01:38 METAR-Pi systemd[1]: Started LSB: Scrolling METAR display.<br>pi@METAR-Pi:/etc/init.d $</p><p>However I am unable to see to see the output on the LED Matrix when running the shell script.</p><p>Here is the code from my <a href="http://metartext.sh" rel="nofollow noopener">metartext.sh</a> file:<br>------------------------------------------------<br>#!/bin/bash<br># /etc/init.d/<a href="http://metartext.sh" rel="nofollow noopener">metartext.sh</a></p><p>### BEGIN INIT INFO<br># Provides: metartext<br># Required-Start: $remote_fs $syslog $network<br># Required-Stop: $remote_fs $syslog $network<br># Default-Start: 2 3 4 5<br># Default-Stop: 0 1 6<br># Short-Description: Scrolling METAR display<br># Description: Downloads METAR file from <a href="http://aviationweather.gov" rel="nofollow noopener">aviationweather.gov</a>, parses file to determine airport weather conditions and$<br>### END INIT INFO</p><p># Change the next 3 lines to suit where you install your script and what you want to call it<br>DIR=/display16x32/rpi-rgb-led-matrix/python/samples<br>DAEMON=$DIR/<a href="http://metartext.py" rel="nofollow noopener">metartext.py</a><br>DAEMON_NAME=metartext</p><p># Add any command line options for your daemon here<br>DAEMON_OPTS=" "</p><p># This next line determines what user the script runs as<br># Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.<br>DAEMON_USER=root</p><p># The process ID of the script when it runs is stored here:<br>PIDFILE=/var/run/$<a href="http://DAEMON_NAME.pid" rel="nofollow noopener">DAEMON_NAME.pid</a></p><p>. /lib/lsb/init-functions</p><p>do_start () {<br> log_daemon_msg "Starting system $DAEMON_NAME daemon"<br> start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --sta$<br> log_end_msg $?<br>}<br>do_stop () {<br> log_daemon_msg "Stopping system $DAEMON_NAME daemon"<br> start-stop-daemon --stop --pidfile $PIDFILE --retry 10<br> log_end_msg $?<br>}</p><p>case "$1" in</p><p> start|stop)<br> do_${1}<br> ;;</p><p> restart|reload|force-reload)<br> do_stop<br> do_start<br> ;;</p><p> status)<br> status_of_proc "$DAEMON_NAME" "$DAEMON" &amp;&amp; exit 0 || exit $?<br> ;;</p><p> *)<br> echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"<br> exit 1<br> ;;</p><p>esac<br>exit 0<br>------------------------------------------------</p><p>I am very new to linux and Pi and hopeful that you will be able to shed a little light on where my mistake is in order to make this functional.</p><p>Thank you!</p>KenMon, 05 Dec 2016 23:13:46 -0000Re: Logging Broadband Speed with Logglyhttp://blog.scphillips.com/posts/2015/05/logging-broadband-speed-with-loggly/#comment-3033043642<p>Got it, thanks</p>Bill SteinerSat, 03 Dec 2016 11:14:33 -0000Re: Logging Broadband Speed with Logglyhttp://blog.scphillips.com/posts/2015/05/logging-broadband-speed-with-loggly/#comment-3031888463<p>The speedtest-cli accesses the list of servers to choose the closest one. The relevant line in speedtest-cli is <a href="https://github.com/sivel/speedtest-cli/blob/master/speedtest.py#L799" rel="nofollow noopener">https://github.com/sivel/speed...</a></p><p>From that, the list of server is at: <a href="http://www.speedtest.net/speedtest-servers-static.php" rel="nofollow noopener">http://www.speedtest.net/speed...</a> <br>I don't know what the difference between the four addresses in speedtest-cli are.</p><p>I assume the speedtest people keep it up to date!</p>Stephen C PhillipsFri, 02 Dec 2016 16:08:36 -0000Re: Logging Broadband Speed with Logglyhttp://blog.scphillips.com/posts/2015/05/logging-broadband-speed-with-loggly/#comment-3031746310<p>Is there a file that has all of the <a href="http://speedtest.net" rel="nofollow noopener">speedtest.net</a> servers listed if so what is its name and how can I view it? Is that file updated if so how?<br>Thank you</p>Bill SteinerFri, 02 Dec 2016 15:25:33 -0000Re: The Tado APIhttp://blog.scphillips.com/posts/2016/01/the-tado-api/#comment-3002034482<p>really nice article, there is not an open API as they said, I like a lot your investigations of this device. I have one and now I can do some stuff. thanks!</p>luismgMon, 14 Nov 2016 14:29:29 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-2999189593<p>Worked great on a DragonBoard 410C, just had to add in a --chdir parameter as my python script was using relative paths</p>WorkshopshedSat, 12 Nov 2016 16:56:15 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-2996080497<p>Hi Stephen,</p><p>I've used this init script in several projects now and it has worked so well! Thank you!</p><p>I am now trying to run a c program that requires command line options. In the terminal, I would run</p><p>/path/to/program/my_program 0 &gt; somefile.txt</p><p>I thought the way to accomplish this would be to use the following</p><p># Change the next 3 lines to suit where you install your script and what you want to call it<br>DIR=/path/to/program<br>DAEMON=$DIR/my_program<br>DAEMON_NAME=my_program</p><p># Add any command line options for your daemon here<br>DAEMON_OPTS="0 &gt; somefile.txt"</p><p>Is this the correct way to include command line options?</p>Peter HillyardThu, 10 Nov 2016 18:21:57 -0000Re: Playing music on a Raspberry Pi using UPnP and DLNA (v3)http://blog.scphillips.com/posts/2014/05/playing-music-on-a-raspberry-pi-using-upnp-and-dlna-v3/#comment-2982933796<p>Don't like to spam you just need your help<br>I got raspberry pi work with bubble upnp. It shows up there now. But when I start the "gmediarender -f Raspberry" command and play from the app, this is what it shows</p><p>pi@arjunpi:~ $ gmediarender -f Raspberry<br>gmediarender 0.0.7-git started [ gmediarender 2016-10-22_57dfbfd (libupnp-1.6.19+git20141001; glib-2.42.1; gstreamer-1.4.4) ].<br>Logging switched off. Enable with --logfile=&lt;filename&gt; (e.g. --logfile=/dev/stdout for console)<br>Ready for rendering.<br>ERROR [2016-11-03 20:49:54.283482 | gstreamer] setting play state failed (2)ERROR [2016-11-03 20:49:54.283433 | gstreamer] <br>uridecodebin1: Error: No URI handler implemented for "http". (Debug: gsturidecodebin.c(1416): gen_source_element (): /GstPlayBin:play/GstURIDecodeBin:uridecodebin1)<br>ERROR [2016-11-03 20:49:54.283589 | upnp] upnp_set_error: Playing failed<br>ERROR [2016-11-03 20:49:55.320922 | gstreamer] ERROR [2016-11-03 20:49:55.320972 | gstreamer] uridecodebin1: Error: No URI handler implemented for "http". (Debug: gsturidecodebin.c(1416): gen_source_element (): /GstPlayBin:play/GstURIDecodeBin:uridecodebin1)setting play state failed (2)</p><p>ERROR [2016-11-03 20:49:55.321056 | upnp] upnp_set_error: Playing failed</p>Arjun MenonThu, 03 Nov 2016 11:22:20 -0000Re: Playing music on a Raspberry Pi using UPnP and DLNA (v3)http://blog.scphillips.com/posts/2014/05/playing-music-on-a-raspberry-pi-using-upnp-and-dlna-v3/#comment-2982771579<p>Thanks, that makes sense. I'm not sure why I didn't need this though!</p>Stephen C PhillipsThu, 03 Nov 2016 09:40:54 -0000Re: Playing music on a Raspberry Pi using UPnP and DLNA (v3)http://blog.scphillips.com/posts/2014/05/playing-music-on-a-raspberry-pi-using-upnp-and-dlna-v3/#comment-2982710886<p>Raspberry pi would not show up in the bubbleupnp rendered list.<br>After configuring gmrender, I installed the app in android running kitkat, but in the renderer list it only shows "Local media render". How to diagnose this?</p>Arjun MenonThu, 03 Nov 2016 08:58:45 -0000Re: Logging Broadband Speed with Logglyhttp://blog.scphillips.com/posts/2015/05/logging-broadband-speed-with-loggly/#comment-2980862043<p>Very nice! Loggly seems to be a great service as well. Thank you for introducing me to it and for sharing your solution.</p>GentilWed, 02 Nov 2016 08:36:26 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-2980772170<p>Good to hear.</p>Stephen C PhillipsWed, 02 Nov 2016 07:11:22 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-2980669843<p>Hi Stephen,</p><p>Problem solved: <br>In my py script, I use /dev/ttyUSB0. First time after (re)boot there is some unwanted data in the stream and that terminated the script, After 'sudo service rflink restart', it worked!<br>I added a serial.flush() in my program and now everything works like expected.</p><p>Thanks again for your extensive support!</p><p>-ben</p>benWed, 02 Nov 2016 04:45:59 -0000Re: The Tado APIhttp://blog.scphillips.com/posts/2016/01/the-tado-api/#comment-2979661200<p>Yup, I just spent all weekend working on this:</p><p><a href="https://github.com/maxxoverclocker/tado_smart_thermostat" rel="nofollow noopener">https://github.com/maxxoverclo...</a></p><p>Works for me...</p>Kyle ProchaskaTue, 01 Nov 2016 14:26:10 -0000Re: The Tado APIhttp://blog.scphillips.com/posts/2016/01/the-tado-api/#comment-2979659628<p>Hi,</p><p>I spend this weekend figuring out how to use the v2 APIs to make a 'smart' thermostat script. My issue is my AC overcools by 3-7 degrees, so I created a script in powershell (hey, it's what I know) that monitors a google sheet for settings and then sends them to the tado v2 api. Feel free to ask if you have any questions. I created a github for it that I'll be updating as I go.</p><p><a href="https://github.com/maxxoverclocker/tado_smart_thermostat" rel="nofollow noopener">https://github.com/maxxoverclo...</a></p>Kyle ProchaskaTue, 01 Nov 2016 14:25:12 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-2979076560<p>The sleep delay won't work. Each init script is executed in sequence so adding the delay in the init script just slows the whole process down - it doesn't change any other behaviour. I see you have put that "$all" are required and I guess that should make sure that the other processes are running. The only thing I can think of is to remove the sleep from the init script and add the delay to the start of the Python script. You could also add some logging to the Python script so you can see what is going on.</p>Stephen C PhillipsTue, 01 Nov 2016 07:58:09 -0000Re: The Tado APIhttp://blog.scphillips.com/posts/2016/01/the-tado-api/#comment-2978411682<p>I look forward to this! I'm looking to write a component for Home Assistant to support Tado, and details ont he latest iteration of the API would be extremely useful. :)</p>MattMon, 31 Oct 2016 18:45:49 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-2977941925<p>Script is back to 'normal' except for lines 14,15 and 16 to match my setup, only thing what has been added is a 30 sec delay after line 30 to make sure all processes are up and running.<br>After reboot it still doesn't work, but if I run 'sudo services rflink restart' it all works !</p><p>Below are the last few syslog lines, @ 18:54:08 is were I executed above line.</p><p>Oct 31 18:48:42 openhab systemd[1]: Time has been changed<br>Oct 31 18:48:48 openhab dhcpcd[674]: eth0: no IPv6 Routers available<br>Oct 31 18:49:02 openhab <a href="http://rflink.sh" rel="nofollow noopener">rflink.sh</a>[410]: Starting system rflink daemon:.<br>Oct 31 18:49:02 openhab systemd[1]: Started LSB: Start/stop rflink script.<br>Oct 31 18:49:02 openhab systemd[1]: Starting Multi-User System.<br>Oct 31 18:49:02 openhab systemd[1]: Reached target Multi-User System.<br>Oct 31 18:49:02 openhab systemd[1]: Starting Graphical Interface.<br>Oct 31 18:49:02 openhab systemd[1]: Reached target Graphical Interface.<br>Oct 31 18:49:02 openhab systemd[1]: Starting Update UTMP about System Runlevel Changes...<br>Oct 31 18:49:02 openhab systemd[1]: Started Update UTMP about System Runlevel Changes.<br>Oct 31 18:49:02 openhab systemd[1]: Startup finished in 2.271s (kernel) + 33.678s (userspace) = 35.950s.<br>Oct 31 18:54:08 openhab systemd[1]: Stopping LSB: Start/stop rflink script...<br>Oct 31 18:54:08 openhab <a href="http://rflink.sh" rel="nofollow noopener">rflink.sh</a>[1784]: Stopping system rflink daemon:start-stop-daemon: warning: failed to kill 1536: No such process<br>Oct 31 18:54:08 openhab <a href="http://rflink.sh" rel="nofollow noopener">rflink.sh</a>[1784]: No process in pidfile '/var/run/<a href="http://rflink.pid" rel="nofollow noopener">rflink.pid</a>' found running; none killed.<br>Oct 31 18:54:08 openhab <a href="http://rflink.sh" rel="nofollow noopener">rflink.sh</a>[1784]: failed!<br>Oct 31 18:54:08 openhab systemd[1]: Starting LSB: Start/stop rflink script...<br>Oct 31 18:54:38 openhab <a href="http://rflink.sh" rel="nofollow noopener">rflink.sh</a>[1792]: Starting system rflink daemon:.<br>Oct 31 18:54:38 openhab systemd[1]: Started LSB: Start/stop rflink script.</p><p>At reboot it creates a pidfile but my program (<a href="http://rflink.py" rel="nofollow noopener">rflink.py</a>) doesn't start the first time, therefore it cannot be killed.<br>But after 'sudo services rflink restart' it does, tried a lot of things since but no luck, it is driving me crazy!</p>benMon, 31 Oct 2016 14:05:25 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-2977736074<p>Good, as it says in the article, the process name of the python script is just "python" so you cannot use it to kill the process: you must use the PID instead.</p>Stephen C PhillipsMon, 31 Oct 2016 12:00:11 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-2977497931<p>Yes, I was using the a skeleton that looks slightly different, but the ins and outs were mainly the same. You guessed correctly, I modified my stop line to to take a pidfile, and now it works. Thanks for the speedy reply, you saved the day :)</p>ruaraidh jay-chalmersMon, 31 Oct 2016 09:18:27 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-2977492627<p>I suspect you've done things a little differently as I can't see how the stop command in my script could give that output. It sounds like the script is trying to kill the process by process name rather than process ID (PID).</p>Stephen C PhillipsMon, 31 Oct 2016 09:14:18 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-2977489633<p>There is one part in your script which is a bit odd: you've moved the PID file into a subdirectory of /var/run. You've then added a check in the do_start function to create the subdirectory if it doesn't exist. This is all an extra complication and I am not sure why you bother? In doing so you have added a chown command to the new folder but you are changing the ownership to the DAEMON_USER which is probably wrong.</p><p>The init script will run as root when the machine boots. When running it manually from the command-line it also need to be run as root (e.g. using sudo). The init script writes the PID file. The DAEMON_USER defined in the init script is the user that the Python script will run as. The choice of DAEMON_USER depends on what the Python script does: making it root will ensure things work but is not ideal from a security perspective.</p><p>I suggest just following my init script (remove the PID subdirectory) and see if that helps.</p>Stephen C PhillipsMon, 31 Oct 2016 09:11:56 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-2977488273<p>Hi! Thanks for the tutorial, nice work! While configuring a python script to behave as a demon using your help, I have come across a problem. I have configured the start-stop program to be verbose while stopping and starting, and to start as a background process. When starting everything seems fine, the .pid file is created. However, when told to stop, I get "No nifi-watcher found running; none killed. No /usr/sbin/nifi-watcher found running; none killed.". A ps shows that the process is running however. Any ideas?</p><p>Thanks for your time!</p>ruaraidh jay-chalmersMon, 31 Oct 2016 09:10:52 -0000Re: Getting a Python script to run in the background (as a service) on boothttp://blog.scphillips.com/posts/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/#comment-2975161986<p>Hi stephen,</p><p>Thanks for the reply,<br>I set DAEMON_USER to root but no luck</p><p>I assume that at startup all scripts in /etc/init.d are run as root, is this correct ?<br>My shell script :<br>#!/bin/sh</p><p>### BEGIN INIT INFO<br># Provides: rflink<br># Required-Start: $all<br># Required-Stop: $remote_fs $syslog<br># Default-Start: 2 3 4 5<br># Default-Stop: 0 1 6<br># Short-Description: Start/stop rflink script<br># Description: Put a long description of the service here<br>### END INIT INFO</p><p># Change the next 3 lines to suit where you install your script and what you want to call it<br>DIR=/usr/local/bin<br>DAEMON=$DIR/<a href="http://rflink.py" rel="nofollow noopener">rflink.py</a><br>DAEMON_NAME=rflink</p><p># Add any command line options for your daemon here<br>DAEMON_OPTS=""</p><p># This next line determines what user the script runs as.<br># Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.<br>DAEMON_USER=root</p><p># The process ID of the script when it runs is stored here:<br>PIDFILE=/var/run/$DAEMON_NAME/$<a href="http://DAEMON_NAME.pid" rel="nofollow noopener">DAEMON_NAME.pid</a></p><p>. /lib/lsb/init-functions</p><p>do_start () {<br> sleep 20<br> log_daemon_msg "Starting system $DAEMON_NAME daemon"<br> if [ ! -d /var/run/$DAEMON_NAME ] ; then<br> mkdir /var/run/$DAEMON_NAME<br> chown $DAEMON_USER:$DAEMON_USER /var/run/$DAEMON_NAME/<br> fi<br> log_daemon_msg "Starting system $DAEMON_NAME daemon"<br> sudo start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS<br> log_end_msg $?<br>}<br>do_stop () {<br> log_daemon_msg "Stopping system $DAEMON_NAME daemon"<br> start-stop-daemon --stop --pidfile $PIDFILE --retry 10<br> log_end_msg $?<br>}</p><p>case "$1" in</p><p> start|stop)<br> do_${1}<br> ;;</p><p> restart|reload|force-reload)<br> do_stop<br> do_start<br> ;;</p><p> status)<br> status_of_proc "$DAEMON_NAME" "$DAEMON" &amp;&amp; exit 0 || exit $?<br> ;;</p><p> *)<br> echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"<br> exit 1<br> ;;<br>esac<br>exit 0</p><p>Initially I thought it had to do with the mqtt broker to become active late, I also changed the delay to 60 seconds, no difference.</p><p>-ben</p>benSat, 29 Oct 2016 16:08:21 -0000