1

I want to run a Python script on a Raspberry Pi in the background. The script fetches data from temperature sensors which are connected to the Pi and sends them to an InfluxDB Database.

I get it to run with the command: screen -d -m lcl-gateway.py

However, after a few days the data randomly stops transmitting. I have tried to do a cron job (sudo contab -e) to repeat the command above every hour: * * * * * screen -d -m /home/pi/lcl-gateway.py. But this has not worked.

The script looks as follows:

#!/usr/bin/python
# 
# LCL GATEWAY
# VERSION 1.2
# LECHACAL.COM 10 MARCH 2020

import ConfigParser
import serial
import os, sys
import requests
import datetime
import optparse


if __name__ == "__main__":


        parser = optparse.OptionParser(usage="%prog [-d] [--version]", version = "prog 1.2.0")
        parser.add_option('-d', '--debug', dest='debug', default=False, action='store_true',)
        options, remainder = parser.parse_args()

        c = ConfigParser.ConfigParser()
        c.read("/etc/gateway.conf")

        baud = c.getint('system','baud')
        serial_port = c.get('system', 'port')
        if not os.path.exists(serial_port):
                print 'Serial port %s not found' % serial_port
                sys.exit()
        ser = serial.Serial(serial_port, baud)

        DayOfMonth = datetime.datetime.utcnow().day
        ls_fileopen = False

        while True:
                try:
                        data_in = ser.readline()

                        utcnow = datetime.datetime.utcnow()
                        timestamp = utcnow.strftime("%s")

                        if options.debug: print data_in

                        while data_in[-1] in ['\r', '\n']:
                                data_in = data_in[:-1]

                        z = data_in.split(' ')
                        csv = ','.join(z[1:])
                        for sect in c.sections():
                                if sect=='emoncms' and c.getboolean(sect,'enabled'):
                                #EMONCMS
                                        hostname = c.get(sect, 'hostname')
                                        node = c.get(sect, 'node')
                                        apikey = c.get(sect, 'apikey')
                                        url = "http://%s/input/post?apikey=%s&node=%s&csv=%s" % (hostname, apikey, node, csv)
                                        if options.debug: print url
                                        r = requests.post(url)
                                        #s = urllib2.urlopen(url)
                                        if options.debug: print r
                                if sect=='influxdb' and c.getboolean(sect,'enabled'):
                              #INFLUXDB

                                        #z = data_in.split(' ') 
                                        t = timestamp + '000000000'     
                                        url = c.get(sect, 'url')
                                        dbname = c.get(sect, 'dbname')
                                        user = c.get(sect, 'user')
                                        passwd = c.get(sect, 'passwd')
                                        measurement = c.get(sect, 'measurement')
                                        params = {'db': dbname, 'u': user, 'p': passwd}

                                        i = 0
                                        payload = ""
                                        for zz in z[1:]:
                                                i += 1
                                                if zz!="":
                                                        payload += "%s,channel=%02d value=%s %s\n" % (measurement, i, zz,t)
                                        #payload = "rpict3t1,channel=01 value=50.2 %s\nrpict3t1,channel=02 value=156.2 %s\n" % (t,t)
                                        if options.debug: print payload
                                        r = requests.post(url, params=params, data=payload)
                                        if options.debug: print r.text

                                if sect=='localsave' and c.getboolean(sect,'enabled'):
                              # LOCALSAVE     
                                        ls_dir = c.get(sect, 'directory')
                                        filename = ls_dir+'/'+timestamp+'.csv'
                                        if not ls_fileopen:
                                                f = open(filename,'w')
                                                ls_fileopen = True      
                                        if DayOfMonth != utcnow.day:
                                                DayOfMonth = utcnow.day
                                                if ls_fileopen: f.close()
                                                f = open(filename,'w')
                                                ls_fileopen = True

                                        f.write(timestamp+','+csv+'\n')


                except KeyboardInterrupt:
                        if ls_fileopen: f.close()
                        print "Terminating."
                        break
Ben
  • 183
  • 8
  • 1
    Python can't handle this thread, so need use system tools for calling python script. something like that: [bash(start,stop as service)] >>> [Python] (handle all errors(PID,actions, etc.), create log for see what happening(ofcourse system got log but just claim global warnings)), another point : you can't create a file on server , use cache for chron_write. – dsgdfg Nov 10 '21 at 09:55
  • @dsgdfg Thanks for the quick reply. I am very new to this subject. Could you please elaborate on how to use system tools and what you mean by using cache for chron_write – Ben Nov 10 '21 at 10:04
  • 3
    @dsgdfg: sorry if I'm blunt but your comment is ridiculous, Python is perfectly able to handle something like this. The problem is your script is not robust enough, you need to handle any potential serial port errors (serial ports cannot be expected to be bullet-proof, sometimes they timeout or do not transmit the right data). You need to use `serial.SerialException`, see, for instance [here](https://stackoverflow.com/questions/28509398/handle-exception-in-pyserial-during-disconnection) and you also need to make sure even if you receive data, is it correct? you need to check for its size, etc – Marcos G. Nov 10 '21 at 13:56
  • 1
    You are correct ! Python got awesome skils for managment threads on system wide(Linux.). App or module Exceptions are Internal, which app handle this exception(s) on system ?Please continue to use python scripts directly on linux, unmanaged applications are indispensable to the linux system(!). – dsgdfg Nov 13 '21 at 07:49

0 Answers0