how can I implement time scheduling in micropython

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
zedtech
Posts: 6
Joined: Thu Nov 30, 2017 3:36 am

how can I implement time scheduling in micropython

Post by zedtech » Mon Dec 04, 2017 11:08 pm

How can i implement a similar to below time scheduling code in micropython??
from datetime import datetime
turnon_time = "16:41:00"
turnoff_time = "16:45:00"
while True:
current_time = datetime.strftime(datetime.now(),"%H:%M:%S") #output: 11:12:12
#print(current_time)
if current_time == turnon_time:
print("Turned the Lights on!")

elif current_time == turnoff_time:
print("Turned the lights off!")


I tried the following code below but with no success. current_time prints only once, its not been updated. Why is that when its in the while loop?
import machine
import time
rtc = RTC()
LED_YELLOW = machine.Pin(15,machine.Pin.OUT)
turnon_time = "18:45:00"
turnoff_time = "07:00:00"
rtc.datetime((2017, 12, 4, 0, 14, 17, 0, 0))
while True:
t = time.localtime()
current_time = '{:02d}:{:02d}:{:02d}'.format(t[3],t[4],t[5])
print(current_time)
if current_time == turnon_time:
if LED_YELLOW.value():
pass
else:
LED_YELLOW.on()
print('Yellow Led On')
elif current_time == turnoff_time:
if LED_YELLOW.value():
LED_YELLOW.off()
else:
pass

User avatar
pythoncoder
Posts: 2017
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: how can I implement time scheduling in micropython

Post by pythoncoder » Tue Dec 05, 2017 7:55 am

It's hard to figure out why your code doesn't run since the forum doesn't allow code posts until you've posted a few messages. So I can't see your indentation. But the following does work - tested on an ESP8266. Note I changed the on time so you only have to wait a minute to see the LED turn on.

Code: Select all

import machine
import time
rtc = machine.RTC()
LED_YELLOW = machine.Pin(15,machine.Pin.OUT)
turnon_time = "14:18:00"
turnoff_time = "07:00:00"
rtc.datetime((2017, 12, 4, 0, 14, 17, 0, 0))
while True:
    t = time.localtime()
    current_time = '{:02d}:{:02d}:{:02d}'.format(t[3],t[4],t[5])
    print(current_time)
    if current_time == turnon_time:
        if not LED_YELLOW.value():
            LED_YELLOW.on()
            print('Yellow Led On')
    elif current_time == turnoff_time:
        if LED_YELLOW.value():
            LED_YELLOW.off()
            print('Yellow Led Off')
    time.sleep(0.3)
Last edited by pythoncoder on Tue Dec 05, 2017 8:54 am, edited 1 time in total.
Peter Hinch

SpotlightKid
Posts: 277
Joined: Wed Apr 08, 2015 5:19 am

Re: how can I implement time scheduling in micropython

Post by SpotlightKid » Tue Dec 05, 2017 8:40 am

pythoncoder wrote:
Tue Dec 05, 2017 7:55 am
It's hard to figure out why your code doesn't run since the forum doesn't allow code posts until you've posted a few messages. So I can't see your indentation.
A workaround for this is use the quote message function, then you'll see the markup of the original post with the indentation intact.

User avatar
pythoncoder
Posts: 2017
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: how can I implement time scheduling in micropython

Post by pythoncoder » Tue Dec 05, 2017 8:58 am

So it does! Thank you.
Peter Hinch

zedtech
Posts: 6
Joined: Thu Nov 30, 2017 3:36 am

Re: how can I implement time scheduling in micropython

Post by zedtech » Thu Dec 07, 2017 2:21 am

[quote=pythoncoder post_id=23678 time=1512460525 user_id=265]
It's hard to figure out why your code doesn't run since the forum doesn't allow code posts until you've posted a few messages. So I can't see your indentation. But the following does work - tested on an ESP8266. Note I changed the on time so you only have to wait a minute to see the LED turn on.
[code]import machine
import time
rtc = machine.RTC()
LED_YELLOW = machine.Pin(15,machine.Pin.OUT)
turnon_time = "14:18:00"
turnoff_time = "07:00:00"
rtc.datetime((2017, 12, 4, 0, 14, 17, 0, 0))
while True:
t = time.localtime()
current_time = '{:02d}:{:02d}:{:02d}'.format(t[3],t[4],t[5])
print(current_time)
if current_time == turnon_time:
if not LED_YELLOW.value():
LED_YELLOW.on()
print('Yellow Led On')
elif current_time == turnoff_time:
if LED_YELLOW.value():
LED_YELLOW.off()
print('Yellow Led Off')
time.sleep(0.3)
[/code]
[/quote]

Hello, Thanks a million for your help. My code if exactly as you wrote except It doesn't have the time.sleep(0.3) part at the end and if yours worked then i'm going to make the time.sleep(0.3) addition to my code and see if it will work. Anyways what is the need for time.sleep(0.3)?

User avatar
pythoncoder
Posts: 2017
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: how can I implement time scheduling in micropython

Post by pythoncoder » Thu Dec 07, 2017 10:18 am

Simply to reduce the rate it prints out. My version will work without it.

As a general point in a more complex program I wouldn't compare text strings. This is because if you don't check it more than once per second there is a risk of missing the time. I would convert hours, minutes and seconds to an integer number of seconds past midnight. Then you can compare times with something along the lines of

Code: Select all

    if current_time >= turnon_time and not LED_YELLOW.value():
        LED_YELLOW.on()
        print('Yellow Led On')
    elif current_time >= turnoff_time and LED_YELLOW.value():
        LED_YELLOW.off()
        print('Yellow Led Off')
This will work even the code runs at a lower rate than 1Hz.
Peter Hinch

zedtech
Posts: 6
Joined: Thu Nov 30, 2017 3:36 am

Re: how can I implement time scheduling in micropython

Post by zedtech » Thu Dec 07, 2017 8:12 pm

Once again thanks very much for your help. My actual entire code in the while loop on the ESP8266 had other parts besides of the time comparison. when i remove it, the time comparison worked. But i want to keep the other part too. How can this be done? Any suggestions will be highly appreciated.
Here is the overview of the project that i'm working on. In the while loop the script is suppose to check if the time comparison has happened and perform some action. After that its suppose to check if there's a network connection from an mobile app device and if true perform some actions as well and the cycle should repeat over and over. As the script is below current_time doesn't get update.

Code: Select all

while True:
      t = utime.locatime()
      current_time = '{:02d}:{:02d}:{:02d}'.format(t[3],t[4],t[5])
     #print(current_time)
     if current_time == turnon_time:
         if LED_YELLOW.value():
             print('Yellow Led On')
         else:
             LED_YELLOW.on()
             print('Yellow Led On')
     elif current_time == turnoff_time:
         if LED_YELLOW.value():
             LED_YELLOW.off()
             print('Yellow Led Off')
         else:
             print('Yellow Led Off')   
    
     conn, addr = s.accept()
     print("Got a connection from %s" % str(addr))
     request = conn.recv(1024)
     print("Content = %s" % str(request))
     request = str(request)
    
     if request.find('/?STATUS='):
         STAT = str(request[15:22])
         STATUS = STAT.strip()


     if STATUS == 'REDOON':
         LED_RED.on()
         content = 'Kitchen Light On'

     elif STATUS == 'REDOFF':
         LED_RED.off()
         content = 'Kitchen Light Off '
     response = http % (len(content), content)
     conn.send(response)
     conn.close()
     utime.sleep(0.3)
Moderator note: I added code tags to your post so that the indentation would be presented properly.

User avatar
kfricke
Posts: 336
Joined: Mon May 05, 2014 9:13 am
Location: Germany

Re: how can I implement time scheduling in micropython

Post by kfricke » Thu Dec 07, 2017 10:30 pm

zedtech wrote:
Thu Dec 07, 2017 2:21 am
... Anyways what is the need for time.sleep(0.3)?
The ESP8266 RTOS (which MicroPythonactually runs embedde in) needs time slices to do the work to keep the WiFi functionalites up and running (especially in AP mode).

zedtech
Posts: 6
Joined: Thu Nov 30, 2017 3:36 am

Re: how can I implement time scheduling in micropython

Post by zedtech » Fri Dec 08, 2017 1:50 am

Its a pause and the code still works without it. I just followed the suggestion of someone and by adding it to my code thought it would clear up the issue with my code, but the issue was something else.

User avatar
pythoncoder
Posts: 2017
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: how can I implement time scheduling in micropython

Post by pythoncoder » Fri Dec 08, 2017 6:57 am

You're almost certainly hitting the problem I explained in my last post. The way your code works relies on the string comparison being performed at least once per second. The test

Code: Select all

     if current_time == turnon_time:
will only succeed if it runs at that precise time. Say the turnon_time is '12:00:00' and the time at the start of the loop is '11:59:59'. The test will (correctly) fail and the LED will remain off. The rest of the code runs with all the internet stuff taking (say) 5 seconds. On the next pass through the loop current_time == '12:00:04' and the test will again fail. The LED will never turn on.

The solution (as I said before) is to convert the times to integers instead of strings and perform a >= comparison. Thus:

Code: Select all

current_time = t[3]*3600 + t[4]*60 +t[5] # Seconds since midnight
The trigger times would be handled similarly

Code: Select all

TURN_YELLOW_ ON = (14, 05, 00)  # Turn on at 14:05:00
TURN_YELLOW_OFF = (08, 05, 30)  # Off at 08:05:30
def time_to_int(t):
	return t[0]*3600 + t[1]*60 + t[2]
turnon_time = time_to_int(TURN_YELLOW_ ON)
turnoff_time = time_to_int(TURN_YELLOW_ OFF)
Then your comparison would be performed by

Code: Select all

     if current_time >= turnon_time and LED_YELLOW.value():
         print('Yellow Led On')
This will work even if the subsequent part of the loop takes minutes to run since the >= test will pass.
Peter Hinch

Post Reply