I've tried to make this python script run from /etc/rc.local, crontab @reboot, and systemd via systemctl without any success.
The python script runs from the command line while logged in as user pi and exits gracefully into the background without issue. The same goes for running it at the prompt as user pi with: sh /etc/rc.local
Any guidance would be appreciated, as follows:
#!/usr/bin/python
#required libraries
import sys
import ssl
import paho.mqtt.client as mqtt
import json
from pprint import pprint
import Adafruit_CharLCD as LCD
from textwrap import fill
#Configuration
rootCAPath = "/home/pi/Cigar-Box/certs/rootCA.pem"
certFilePath = "/home/pi/Cigar-Box/certs/xxxxxxxxxx-certificate.pem.crt"
keyFilePath = "/home/pi/Cigar-Box/certs/xxxxxxxxxx-private.pem.key"
iotThing = "Zorua"
clientID = "Zorua"
#Device JSON initialization
device = {'state': {'reported': {'HP':100} } }
device['state']['reported']['color'] = {'r':0, 'g':0, 'b':0}
#Create LCD
lcd = LCD.Adafruit_CharLCDPlate()
#LCD wrapper
def set_lcd_color(R,G,B):
global lcd
device['state']['reported']['color']['r'] = R
device['state']['reported']['color']['g'] = G
device['state']['reported']['color']['b'] = B
lcd.set_color(R, G, B)
def set_lcd_message(message):
global lcd
device['state']['reported']['msg'] = message
lcd.clear()
#Word wrap to fit 16-char wide display and add capitalization
lcd_message = fill(message.capitalize(),16)
lcd.message(lcd_message)
# Initialize the LCD using the pins
set_lcd_message('Initializing...')
set_lcd_color(0, 0, 1)
#called while client tries to establish connection with the server
def on_connect(mqttc, obj, flags, rc):
print "Connecting..."
if rc==0:
print ("Subscriber Connection status code: "+str(rc)+" | Connectionstatus: successful")
#We only want to be notified about things we need to change to stay in sync with AWS
mqttc.subscribe("$aws/things/" + iotThing + "/shadow/update/delta", qos=1)
elif rc==1:
print ("Subscriber Connection status code: "+str(rc)+" | Connection status: Connection refused")
print ("Subscriber Connection status code: "+str(rc))
#called when a topic is successfully subscribed to
def on_subscribe(mqttc, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos)+"data"+str(obj))
set_lcd_color(0,1,0)
set_lcd_message('Connected!\nReady for input')
#Let AWS know about the current state of the plate so we can tell us what's out of sync
mqttc.publish("$aws/things/" + iotThing + "/shadow/update", json.dumps(device))
#called when a message is received by a topic
#Messages are formatted in JSON
#When working with /update, we might not find all keys all the time, so we need to handle that
def on_message(mqttc, obj, msg):
try:
data = json.loads(msg.payload)
update = data['state']
except:
return
#Look for a message in the update. If it's there, we need to update the display
if 'msg' in update.keys():
try:
set_lcd_message(update['msg'])
except:
print("Could not enact message from topic: "+msg.topic+" | QoS: "+str(msg.qos)+" | Data Received: "+str(msg.payload))
#Look to see if the status of R, G, or B has changed for the display
if 'color' in update.keys():
try: lcd_r = update['color']['r']
except: lcd_r = device['state']['reported']['color']['r']
try: lcd_g = update['color']['g']
except: lcd_g = device['state']['reported']['color']['g']
try: lcd_b = update['color']['b']
except: lcd_b = device['state']['reported']['color']['b']
set_lcd_color(lcd_r,
lcd_g,
lcd_b)
#Let AWS know we've updated the display
mqttc.publish("$aws/things/Zorua/shadow/update", json.dumps(device))
#creating a client with client-id=Zorua
mqttc = mqtt.Client(client_id=clientID)
mqttc.on_connect = on_connect
mqttc.on_reconnect = on_connect
mqttc.on_subscribe = on_subscribe
mqttc.on_message = on_message
#Configure network encryption and authentication options. Enables SSL/TLS support.
#adding client-side certificates and enabling tlsv1.2 support as required by aws-iot service
mqttc.tls_set(rootCAPath,
certfile=certFilePath,
keyfile=keyFilePath,
tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
#connecting to aws-account-specific-iot-endpoint
print ("About to connect")
mqttc.connect("lettersandnumbers.iot.us-west-2.amazonaws.com", port=8883) #AWS IoT service hostname and portno
#automatically handles reconnecting
mqttc.loop_forever()
The code located in /etc/rc.local followed by a simple redirect test to see if rc.local is behaving
# Default code located inside /etc/rc.local
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP" > /home/pi/cigarbox.log
fi
exit 0
######################################################################
# After rebooting RPi = no output to log
pi@cigarbox:~ $ cat cigarbox.log
# Running /etc/rc.local from the command line
pi@cigarbox:~ $ sh /etc/rc.local
# After running /etc/rc.local locally = output to log
pi@cigarbox:~ $ cat cigarbox.log
My IP address is 192.168.0.21
Here are the paths for pi and root
# Running as pi
pi@cigarbox:~ $ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
# Running s root
pi@cigarbox:~ $ su - root
Password:
root@cigarbox:~# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Nice. It looks like rc.local is behaving
# Cat and pipe of boot.log
root@cigarbox:~# cat /var/log/boot.log | grep rc.local
Starting /etc/rc.local Compatibility...
[ OK ] Started /etc/rc.local Compatibility.
However, I've tried this in the past. See line commented out below the python command and path in parenthesis, per suggestion. So, the script still won't run out of /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# Print the IP address
#_IP=$(hostname -I) || true
#if [ "$_IP" ]; then
# printf "My IP address is %s\n" "$_IP" > /home/pi/cigarbox.log
#fi
(python /home/pi/Cigar-Box/CigarBox.py)&
#/usr/bin/python /home/pi/Cigar-Box/CigarBox.py > /home/pi/cigarbox.log 2>&1 &
exit 0
Hmm, it appears that I need 10 good boy points to upload images. I'll have to post the successful completion of this group's most appreciated help. Thank you all..photo URL and solution to follow.
Okay, here's a link to a photo of my voice recognition project that now starts automatically because of the support from my new friends at stackoverflow:
https://drive.google.com/file/d/19ribELmAnQFy4jfzi5D6I7fk91naS8J7/view?usp=drivesdk