python code to control GPIO at specific times
Question: I want to build an irrigation automation system based on a Raspberry Pi. I
have a script that generates a .CSV file based on the input parameters of the
sprinkeling schedule (station no, time/station, use/not use rain sensor,
etc.).

The .CSV file looks like this:

    
    
    1 00:00:00 00:29:59 110000
    2 00:30:00 00:44:59 101000
    3 00:45:00 01:14:59 100100
    .
    .
    .
    .
    

, where each line represent a time interval and the six digits binary number
represent the GPIO pins state (1=valve on, 0=valve off).

What is the best way to scan this .CSV file and trigger the valves based on
the binary code?

For now I have two options, but I'm sure there must be a better one:

  * Continuously loop a code at 1 second interval, read each line of the .CSV file until the interval mathes the current time and then trigger the correspondent ports
  * Read a .CSV file and generate a cron job for each line

Either way, the solution has to be very simple and very reliable, the program
is supposed to run during the entire summer season without mistake or error.

Thanks!


Answer: This program should do what you want it to. When it starts, your file is read
into a schedule. The schedule is sorted, and the for loop runs through your
schedule as needed. Once the schedule has been completed, your program will
need to be run again.

    
    
    import operator
    import time
    
    
    def main():
        schedule = []
        with open('example.csv') as file:
            for line in file:
                _, start, _, state = line.split()
                data = time.strptime(start, '%H:%M:%S')
                schedule.append((time_to_seconds(data), int(state, 2)))
        schedule.sort(key=operator.itemgetter(0))
        for start, state in schedule:
            current_time = time_to_seconds(time.localtime())
            difference = start - current_time
            if difference >= 0:
                time.sleep(difference)
                set_gpio_pins(state)
    
    
    def time_to_seconds(data):
        return (data.tm_hour * 60 + data.tm_min) * 60 + data.tm_sec
    
    
    def set_gpio_pins(state):
        raise NotImplementedError()
    
    if __name__ == '__main__':
        main()
    

