Search code examples
pythonjsoncronraspberry-pi

Sensor data with pythin does not get written to File


I'm currently working on a script for my sensor on my Raspberry Pi. The code underneath should get the values of my sensor and write it into a the data.json file. My problem is, if I run the scipt with my the Thonny editor everything works but if I add the script to my crontab menu the data does not get written to the data.json file.

The Code:

import time
import board
import adafruit_dht
import psutil
import io
import json
import os
from gpiozero import LED
from datetime import date
from datetime import datetime

# We first check if a libgpiod process is running. If yes, we kill it!
for proc in psutil.process_iter():
    if proc.name() == "libgpiod_pulsein" or proc.name() == "libgpiod_pulsei":
        proc.kill()
sensor = adafruit_dht.DHT11(board.D23)

# init
temp_values = [10]
hum_values = [10]
counter = 0
dataLED = LED(13)
dataList = []

def errSignal():
    for i in range(0,3):
        dataLED.on()
        time.sleep(0.1)
        dataLED.off()
        time.sleep(0.1)
        
#on startup
def runSignal():
    for i in range(0,5):
        dataLED.on()
        time.sleep(0.2)
        dataLED.off()
        time.sleep(0.2)

def getExistingData():
    with open('data.json') as fp:
        dataList = json.load(fp)
    print(dataList)


def startupCheck():
    if os.path.isfile("data.json") and os.access("data.json", os.R_OK):
        # checks if file exists
        print("File exists and is readable.")
        # get json data  an push into arr on startup
        getExistingData()
    else:
        print("Either file is missing or is not readable, creating file...")
        # create json file
        with open("data.json", "w") as f:
            print("The json file is created.")#
   
   
def calc_avgValue(values):
    sum = 0
    for iterator in values:
        sum += iterator
    return sum / len(values)


def onOFF():
    dataLED.on()
    time.sleep(0.7)
    dataLED.off()


# data led blinking on startup
runSignal()

# checks if file exists 
startupCheck()


while True:
    try:
        temp_values.insert(counter, sensor.temperature)
        hum_values.insert(counter, sensor.humidity)
        counter += 1
        time.sleep(6)
        if counter >= 10:
            print(
                "Temperature: {}*C   Humidity: {}% ".format(
                    round(calc_avgValue(temp_values), 2),
                    round(calc_avgValue(hum_values), 2)
                )
            )
            # get time
            today = date.today()
            now = datetime.now()

            
            # create json obj
            data = {
                "temperature": round(calc_avgValue(temp_values), 2),
                "humidity": round(calc_avgValue(hum_values), 2),
                "fullDate": str(today),
                "fullDate2": str(today.strftime("%d/%m/%Y")),
                "fullDate3": str(today.strftime("%B %d, %Y")),
                "fullDate4": str(today.strftime("%b-%d-%Y")),
                "date_time": str(now.strftime("%d/%m/%Y %H:%M:%S"))
            }
        
            
            # push data into list
            dataList.append(data)
            
            
            # writing to data.json
            with open("data.json", "w") as f:
                json.dump(dataList, f, indent=4, separators=(',',': '))

            # if data is written signal appears
            onOFF()
            
            print("Data has been written to data.json...")
            
            counter = 0
            
    except RuntimeError as error:
        continue
    except Exception as error:
        sensor.exit()
        while True:
            errSignal()
        raise error
    time.sleep(0.2)

Crontab Menu: The line in the center is the script. enter image description here


Solution

  • Investigation areas:

    • Do not put & in crontab, it serves no purpose.
    • You should capture the output of your scripts to see what is going on. You do this by adding >/tmp/stats.out 2>/tmp/stats.err (and similar for the other 2 lines). You will see what output and errors your scripts encounter.
    • cron does not run your scripts in the same environment, and from the same directory you are running them. Load what you require in the script.
    • cron might not have permissions to write into data.yml in the directory it is running from. Specify a full path, and ensure cron can write in that directory.
    • Look at https://unix.stackexchange.com/questions/109804/crontabs-reboot-only-works-for-root for usage of @reboot. Things that should occur at startup should be configured through systemd or init.d (I do not know what Rasperry Pie uses vs distro). Cron is to schedule jobs, not run things at startup.
    • It could be as simple as not having python3 in the PATH configured in cron.