Page 1 of 1

Temp Monitor w/ Email wont run in background on Raspbian

Posted: Fri Jun 21, 2019 1:17 pm
by tschulze
Hi,

Trying to create a temperature monitor with a phidget thermocouple and raspberry pi with raspbian.

The script is a modified form of a phidget provided example script for temperature monitoring. I am hoping it will continuously monitor temps of a freezer, send a warning email if certain temps are reached, and in a separate thread run a scheduler to check-in monthly or so to let me know the script, pi, power, smtp server, are all intact and functioning. Lastly, I hope to have it start on boot and run in the background with rc.local or cron but so far this has also been unsuccessful.

The script will run fine the foreground and prints the temp to stdout but runs into issue when trying to run in the background with “&” and with the stdout and stderr redirected to dev/null. When started as background the shell is also tied up where any key will stop the job.
pi@raspberrypi:/home/phidget/python_temp/examples/development $ python3 thread_test9<.>py >/dev/null 2>&1 &
[2] 1345
pi@raspberrypi:/home/phidget/python_temp/examples/development $
[2]- Done python3 thread_test9<.>py > /dev/null 2>&1
I suspect the “readin = sys.stdin.readline()” may have something to do with this but if I remove it the script no longer runs as a continual loop. I am quickly running into the limits of my understanding with python, phidgets, and raspbian.

Any suggestions would be much appreciated.

Code: Select all

import os
import sys
import time
import traceback
import subprocess
import smtplib
import schedule

from multiprocessing import Process
from threading import Thread
from email.message import EmailMessage
from subprocess import call

from Phidget22.Devices.TemperatureSensor import *
from Phidget22.PhidgetException import *
from Phidget22.Phidget import *
from Phidget22<.>Net import *
from PhidgetHelperFunctions import *

def onAttachHandler(self):
    
    ph = self
    try:
        print("\nAttach Event:")
        ## Get device information and display it.
        channelClassName = ph.getChannelClassName()
        serialNumber = ph.getDeviceSerialNumber()
        channel = ph.getChannel()
        if(ph.getDeviceClass() == DeviceClass.PHIDCLASS_VINT):
            hubPort = ph.getHubPort()
            print("\n\t-> Channel Class: " + channelClassName + "\n\t-> Serial Number: " + str(serialNumber) +
                "\n\t-> Hub Port: " + str(hubPort) + "\n\t-> Channel:  " + str(channel))
        else:
            print("\n\t-> Channel Class: " + channelClassName + "\n\t-> Serial Number: " + str(serialNumber) +
                    "\n\t-> Channel:  " + str(channel) + "\n")
        ## Set the DataInterval inside of the attach handler to initialize the device with this value.
        ## DataInterval defines the minimum time between TemperatureChange events.
        ## DataInterval can be set to any value from MinDataInterval to MaxDataInterval
        print("\n\tSetting Data Interval to 3.0 seconds")
        ph.setDataInterval(1000)
        ## Set the TemperatureChangeTrigger inside of the attach handler to initialize the device with this value.
        ## TemperatureChangeTrigger will affect the frequency of TemperatureChange events, by limiting them to only occur when
        ## the temperature changes by at least the value set.
        print("\tSetting Temperature Change Trigger to 0.0")
        ph.setTemperatureChangeTrigger(0)
        
    except PhidgetException as e:
        print("\nError in Attach Event:")
        DisplayError(e)
        traceback.print_exc()
        return
        
def onTemperatureChangeHandler(self, temperature):

    print("[Temperature Event] -> Temperature: " + str(temperature), end="\r") #this event prints temperature to stdout and clears last printed item to conserve memory
    if temperature > 30: ########## SET TEMP MONITOR HERE
       temperature_monitor_warning(temperature)
       time.sleep(5)
       
def temperature_monitor_status():

    msg = EmailMessage()
    msg['Subject'] = ''
    msg['From'] = ''
    msg['To'] = ''
    msg.set_content('TEMPERATURE MONITOR STATUS: ACTIVE')
    server = smtplib.SMTP('smtp.gmail<.>com', 587)
    server.connect('smtp.gmail<.>com', 587)
    server.ehlo()
    server.starttls()
    server.ehlo()
    server.login('') ## user & password
    server.send_message(msg)
    server.quit()
    time.sleep(5)

def temperature_monitor_warning(temperature):
    
    msg = EmailMessage()
    msg['Subject'] = ''
    msg['From'] = ''
    msg['To'] = ''
    msg.set_content('WARNING: Current Temperature: ' + str(temperature)+ ' C')
    server = smtplib.SMTP('smtp.gmail<.>com', 587)
    server.connect('smtp.gmail<.>com', 587)
    server.ehlo()
    server.starttls()
    server.ehlo()
    server.login('') ## user & password
    server.send_message(msg)
    server.quit()
    time.sleep(5)
    
def main():
    #while True:
        ## Allocate a new Phidget Channel object
        ch = TemperatureSensor()
        ## Set matching parameters to specify which channel to open
        ## prompt user or hard-code the addressing parameters 
        ## channelInfo = AskForDeviceParameters(ch)
        ch.setDeviceSerialNumber(538813)
        ch.setHubPort(0)
        ch.setChannel(0)
        ## Add event handlers before calling open so that no events are missed.
        ch.setOnAttachHandler(onAttachHandler)
        #ch.setOnDetachHandler(onDetachHandler)
        #ch.setOnErrorHandler(onErrorHandler)
        ch.setOnTemperatureChangeHandler(onTemperatureChangeHandler)
        ## Open the channel      
        ch.openWaitForAttachment(5000)
        readin = sys.stdin.readline()

schedule.every(1).minutes<.>do(temperature_monitor_status)
		
def status():
    while True:
        schedule.run_pending()
        time.sleep(1)
				
thread1 = Thread(target = main)
thread2 = Thread(target = status)
thread2.daemon = True
thread1.start()
thread2.start()