2

Last timestamp + syslogGoodmorning everybody!

My name is Joey and I have a serious problem that I can't solve. The problem is that my python script stops running after some hours. To give a little background, I'm building an automatic grow tent to grow house plants like Philodendrons, Syngoniums, Monstera's etc. I'm a mechanical engineering student so I'm very new to python and raspberry. I only worked with arduino for some small projects. So please assume I know nothing and if you can, please explain like you're talking to a child ;)

So there are 5 main components used in the tent:

  • Grow light
  • Humidifier
  • Floor heating
  • Fans
  • Exhaust fan (refresh air)

I'm using a SCD30 seeed sensor for measuring temperature, humidity and CO2.

Now to the coding. The plan was using SSH on the Pi so I could acces it by my laptop. This worked. Then I started writing the code on my laptop with VScode, PIGPIO and the sensor library. This all works as well. In the code I redirect the output to the tent_data.txt where I can see timestamps, temp, humidity, co2 and which devices are on/off in the tent. The idea was putting this data in an grafana dashboard and everything would be good.

Now to the problem! For some reason the code turns off after some hours. It seems pretty random when it does but it seems to be more like after 6-8 hours. So maybe something with memory? I tried ps aux | grep joes_kweektent but it says that it isn"t running anymore. So it doesn't give an error so I don't know where to start. I can also see the timestamps stopping so I know it isn't printing anymore. At the link drive there are two pictures, stoppedhere and syslog. At that moment the code stopped at 0:37 at night, I also screenshotted the syslog. I tried /var/log/messages but it says nothing. I've been searching on the internet for days now for a solution but I can't find any explanation. Maybe there is a voltage drop and it crashes? Maybe the sensor can't read fast enough and it crashes? Maybe the memory is to full (see unable to watch large file picture in link)? Maybe it's something I'm totally unaware of since I'm so new?

I really really really hope someone can help me out! If you ever need help with CAD software or need a part created for you i will help you out! If you live in the Netherlands I can send you a plant or something! :) Thanks in advance everyone!

Links:

Seeed SCD30 sensor: https://nl.rs-online.com/web/p/sensor-development-tools/1887076?cm_mmc=NL-PLA-DS3A-_-google-_-CSS_NL_NL_Raspberry_Pi_%26_Arduino_%26_Development_Tools_Whoop-_-(NL:Whoop!)+Sensor+Development+Tools-_-1887076&matchtype=&aud-772940708119:pla-332152890415&gclid=CjwKCAjwlqOXBhBqEiwA-hhitP9bEsrxwcjAy3F_GZi7MO1z3RYx9YcS4o_q_tcqsTvrNEhNVDNG_hoC89cQAvD_BwE&gclsrc=aw.ds

Code and some pictures: https://drive.google.com/drive/folders/1qbOtcluAanKll6cTUWEDwjfUR-fYzdG2?usp=sharing

# Imports
import adafruit_scd30
import board
import time
import busio
import datetime
import kweekparameters
import RPi.GPIO as GPIO
import sys



# Setup

# Sensor
i2c = busio.I2C(board.SCL, board.SDA, frequency=50000)
scd = adafruit_scd30.SCD30(board.I2C())

# Opstart-bericht
print ("Joe's Kweektent© by Joey Slager")
time.sleep(2)

# Hardware pinnen
ventilatorenPin = 5
bevochtigerPin = 16
kweeklichtPin = 20
buisVentilatorPin = 19
vloerVerwarmingPin = 26

# Zet de GPIO op board pin layout
GPIO.setmode(GPIO.BCM)

# Pin setup
GPIO.setup(ventilatorenPin, GPIO.OUT)
GPIO.setup(bevochtigerPin, GPIO.OUT)
GPIO.setup(kweeklichtPin, GPIO.OUT)
GPIO.setup(buisVentilatorPin, GPIO.OUT)
GPIO.setup(vloerVerwarmingPin, GPIO.OUT)

# Dict om de booleans te vertalen naar aan/uit
aan_uit = {True: "Uit", False: "Aan"}



# Loop

while True:    

    # Huidige tijd
    tijd = datetime.datetime.now()

    # Als er data beschikbaar is print dan de waardes
    if scd.data_available:

        # Aangeven dat data naar tent_data.txt moet
        sys.stdout = open('/home/joeyslager/Joes_Kweektent/tent_data.txt', 'a')

        # Variabelen voor parameters
        temperatuur = scd.temperature
        luchtvochtigheid = scd.relative_humidity
        koolstofDioxide = scd.CO2

        # Prints
        print("---------------------------------------------")

        print(f"Tijd:                 {tijd.strftime('%X')}")
        print(f"Temperatuur:          {temperatuur:0.2f} °C")
        print(f"Luchtvochtigheid:     {luchtvochtigheid:0.1f}%")
        print(f"CO2:                  {koolstofDioxide:0.0f} PPM")

        print("---------------------------------------------")
       
        print(f"Kweeklicht:           {aan_uit[GPIO.input(kweeklichtPin)]}")
        print(f"Bevochtiger:          {aan_uit[GPIO.input(bevochtigerPin)]}")
        print(f"Ventilatoren:         {aan_uit[GPIO.input(ventilatorenPin)]}")
        print(f"Buisventilator:       {aan_uit[GPIO.input(buisVentilatorPin)]}")
        print(f"Vloerverwarming:      {aan_uit[GPIO.input(vloerVerwarmingPin)]}")
        
        print("---------------------------------------------")    

        sys.stdout.close()

    time.sleep(0.5)

    # Test (true = false)
    #GPIO.output(ventilatorenPin, True)
    #GPIO.output(bevochtigerPin, True)
    #GPIO.output(kweeklichtPin, True)
    #GPIO.output(buisVentilatorPin, True)
    #GPIO.output(vloerVerwarmingPin, True)

    # Variabelen voor parameters
    temperatuur = scd.temperature
    luchtvochtigheid = scd.relative_humidity
    koolstofDioxide = scd.CO2
    
    # Kweeklicht
    kweeklichtAan = bool(tijd.hour >= kweekparameters.kweekLichtStart and tijd.hour < kweekparameters.kweekLichtEind)

    if kweeklichtAan:
        GPIO.output(kweeklichtPin, False)
    else:
        GPIO.output(kweeklichtPin, True)

        

        
    # Ventilatoren
    ventilatorAan = bool(tijd.hour >= kweekparameters.ventilatorStart1 and tijd.hour < kweekparameters.ventilatorEind1
                    or tijd.hour >= kweekparameters.ventilatorStart2 and tijd.hour < kweekparameters.ventilatorEind2)

    if ventilatorAan:
        GPIO.output(ventilatorenPin, False)
    else:
        GPIO.output(ventilatorenPin, True)
    
       
    # Temperatuur
    if temperatuur < kweekparameters.minimumTemperatuur:
        GPIO.output(vloerVerwarmingPin, False)

    elif temperatuur > kweekparameters.minimumTemperatuur:
        GPIO.output(vloerVerwarmingPin, True)

    if temperatuur > kweekparameters.maximumTemperatuur:
        GPIO.output(buisVentilatorPin, False)

    elif temperatuur < kweekparameters.maximumTemperatuur:
        GPIO.output(buisVentilatorPin, True)


    # Luchtvochtigheid
    if luchtvochtigheid < kweekparameters.minimumLuchtvochtigheid:
        GPIO.output(bevochtigerPin, False)

    elif luchtvochtigheid > kweekparameters.minimumLuchtvochtigheid:
        GPIO.output(bevochtigerPin, True)

    # CO2
Joey
  • 21
  • 2
  • 1
    Try watching it with `htop` to see if its memory usage is increasing over time... – Mark Setchell Aug 02 '22 at 09:15
  • Please add your code to the question, instead of a link to it. Start with three backticks (`) on a single line. Put the code below that and end with a line with three backticks. – Roland Smith Aug 02 '22 at 11:51
  • Please provide enough code so others can better understand or reproduce the problem. – Community Aug 02 '22 at 12:00
  • you asked the [same question](https://stackoverflow.com/q/73135499/9938317) a few days ago, what has changed? There you posted the code in the question. Why not here. – rioV8 Aug 02 '22 at 15:11
  • There should be an error message with stack trace, shouldn't it? Have I overlooked it? – JeffRSon Aug 03 '22 at 07:23
  • What about this https://stackoverflow.com/questions/4990718/how-can-i-write-a-try-except-block-that-catches-all-exceptions for parts of or the whole loop? – JeffRSon Aug 03 '22 at 07:32
  • I dont know what to add to the code from that link. It still crashes btw – Joey Aug 04 '22 at 20:27

1 Answers1

0

I think your issue is due to the location of sys.stdout = open('/home/joeyslager/Joes_Kweektent/tent_data.txt', 'a').

The close statement for it is inside a conditional if statement, which means it only closes when the conditional if statement is met. This would mean you have unclosed open statements when the conditional is not met. This can be a root cause for a memory leak...

Either move the close outside of the conditional, or better, move the open inside the if scd.data_available: statement. (to prevent opening while you don't need it)

Note that I'm not sure about this, but it's the only thing that stands out in your code, as the rest is basic reading/writing of GPIO pins...


On an unrelated note, I would change the temp/humidity/CO2 prints to proper f-strings, as they are currently not actually f-strings. See this for reference.

        print(f"Temperatuur:          {temperatuur:0.2f} °C")
        print(f"Luchtvochtigheid:     {luchtvochtigheid:0.1f}%")
        print(f"CO2:                  {koolstofDioxide} PPM")

On another unrelated note, the print statements for the on/off values for the different pins can be optimized a bit as well.

Define a dict to turn True/False into words like this (before the while loop):

aan_uit = {True: "Uit", False: "Aan"}

You can then use f-string magic to replace the boolean values from the GPIO into the correct words:

        print(f"Kweeklicht:           {aan_uit[GPIO.input(kweeklichtPin)]}")
        print(f"Bevochtiger:          {aan_uit[GPIO.input(bevochtigerPin)]}")
        print(f"Ventilatoren:         {aan_uit[GPIO.input(ventilatorenPin)]}")
        print(f"Buisventilator:       {aan_uit[GPIO.input(buisVentilatorPin)]}")
        print(f"Vloerverwarming:      {aan_uit[GPIO.input(vloerVerwarmingPin)]}")

That should replace the whole if/else section for the pins. Do check if the on/off values match, otherwise you'll need to flip the string values for the aan_uit dict.

Please note that I wrote this without actual testing, so please inform me of any mistakes

Edo Akse
  • 4,051
  • 2
  • 10
  • 21
  • Hello Everyone! First I would like to give a huge thanks to Edo Akse for giving such a usefull answer to my problem. I feel like I'm already a little better at Python now ;) As for the problem sadly it isn't solved yet. Last night at 2:12 it turned off. I made a screenshot of the timestamp with the syslog. I have seen this next line a few times now at the moment of turning of. ```Aug 3 02:17:01 raspberrypi CRON[9472]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)``` – Joey Aug 03 '22 at 07:00