Skip to content

Commit a9a5e3a

Browse files
committed
Schedule: draft SCEDULE.md.
1 parent 6f1bf52 commit a9a5e3a

File tree

1 file changed

+63
-17
lines changed

1 file changed

+63
-17
lines changed

v3/docs/SCHEDULE.md

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
     4.2.2 [Time causing month rollover](./SCHEDULE.md#422-time-causing-month-rollover)
1111
4.3 [Limitations](./SCHEDULE.md#43-limitations)
1212
4.4 [The Unix build](./SCHEDULE.md#44-the-unix-build)
13+
4.5 [Initialisation](./SCHEDULE.md#45-initialisation)__
1314
5. [The cron object](./SCHEDULE.md#5-the-cron-object) For hackers and synchronous coders
1415
5.1 [The time to an event](./SCHEDULE.md#51-the-time-to-an-event)
1516
5.2 [How it works](./SCHEDULE.md#52-how-it-works)
1617
6. [Hardware timing limitations](./SCHEDULE.md#6-hardware-timing-limitations)
17-
7. [Use in synchronous code](./SCHEDULE.md#7-use-in-synchronous-code) If you really must
18+
7. [Use in synchronous code](./SCHEDULE.md#7-use-in-synchronous-code) If you really must.
19+
8. [The simulate script](./SCHEDULE.md#8-the-simulate-script) Rapidly test sequences.
1820

1921
##### [Tutorial](./TUTORIAL.md#contents)
2022
##### [Main V3 README](../README.md)
@@ -37,7 +39,7 @@ adapt the example code. It can be used in synchronous code and an example is
3739
provided.
3840

3941
It is cross-platform and has been tested on Pyboard, Pyboard D, ESP8266, ESP32
40-
and the Unix build (the latter is subject to a minor local time issue).
42+
and the Unix build.
4143

4244
# 2. Overview
4345

@@ -59,8 +61,8 @@ instances must explicitly be created.
5961
# 3. Installation
6062

6163
Copy the `sched` directory and contents to the target's filesystem. It requires
62-
`uasyncio` V3 which is included in daily firmware builds. It will be in release
63-
builds after V1.12.
64+
`uasyncio` V3 which is included in daily firmware builds and in release builds
65+
after V1.12.
6466

6567
To install to an SD card using [rshell](https://github.com/dhylands/rshell)
6668
move to the parent directory of `sched` and issue:
@@ -76,11 +78,12 @@ The following files are installed in the `sched` directory.
7678
4. `asynctest.py` Demo of asynchronous scheduling.
7779
5. `synctest.py` Synchronous scheduling demo. For `uasyncio` phobics only.
7880
6. `crontest.py` A test for `cron.py` code.
79-
7. `__init__.py` Empty file for Python package.
81+
7. `simulate.py` A simple script which may be adapted to prove that a `cron`
82+
instance will behave as expected. See [The simulate script](./SCHEDULE.md#8-the-simulate-script).
83+
8. `__init__.py` Empty file for Python package.
8084

8185
The `crontest` script is only of interest to those wishing to adapt `cron.py`.
82-
To run error-free a bare metal target should be used for the reason discussed
83-
[here](./SCHEDULE.md#46-the-unix-build).
86+
It will run on any MicroPython target.
8487

8588
# 4. The schedule function
8689

@@ -158,7 +161,8 @@ The args may be of the following types.
158161
3. An object supporting the Python iterator protocol and iterating over
159162
integers. For example `hrs=(3, 17)` will cause events to occur at 3am and 5pm,
160163
`wday=range(0, 5)` specifies weekdays. Tuples, lists, ranges or sets may be
161-
passed.
164+
passed. If using this feature please see
165+
[Initialisation](./SCHEDULE.md#45-initialisation).
162166

163167
Legal integer values are listed above. Basic validation is done as soon as
164168
`schedule` is run.
@@ -236,18 +240,34 @@ Asynchronous use requires `uasyncio` V3, so ensure this is installed on the
236240
Linux target.
237241

238242
The synchronous and asynchronous demos run under the Unix build. The module is
239-
usable on Linux provided the daylight saving time (DST) constraints below are
240-
met.
241-
242-
A consequence of DST is that there are impossible times when clocks go forward
243+
usable on Linux provided the daylight saving time (DST) constraints are met. A
244+
consequence of DST is that there are impossible times when clocks go forward
243245
and duplicates when they go back. Scheduling those times will fail. A solution
244246
is to avoid scheduling the times in your region where this occurs (01.00.00 to
245247
02.00.00 in March and October here).
246248

247-
The `crontest.py` test program produces failures under Unix. These result from
248-
the fact that the Unix `localtime` function handles daylight saving time. The
249-
purpose of `crontest.py` is to check `cron` code. It should be run on bare
250-
metal targets.
249+
## 4.5 Initialisation
250+
251+
Where a time specifier is an iterator (e.g. `mins=range(0, 60, 15)`) and there
252+
are additional constraints (e.g. `hrs=3`) it may be necessary to delay the
253+
start. The problem is specific to scheduling a sequence at a future time, and
254+
there is a simple solution.
255+
256+
A `cron` object searches forwards from the current time. Assume the above case.
257+
If the code start at 7:05 it picks the first later minute in the `range`,
258+
i.e. `mins=15`, then picks the hour. This means that the first trigger occurs
259+
at 3:15. Subsequent behaviour will be correct, but the first trigger would be
260+
expected at 3:00. The solution is to delay start until the minutes value is in
261+
the range`45 < mins <= 59`. The `hours` value is immaterial but a reasonable
262+
general solution is to delay until just before the first expected callback:
263+
264+
```python
265+
async def run():
266+
asyncio.create_task(schedule(payload, args, hrs=3, mins=range(0, 60, 15)))
267+
268+
async def delay_start():
269+
asyncio.create_task(schedule(run, hrs=2, mins=55, times=1))
270+
```
251271

252272
##### [Top](./SCHEDULE.md#0-contents)
253273

@@ -300,7 +320,7 @@ example).
300320

301321
# 6. Hardware timing limitations
302322

303-
The code has been tested on Pyboard 1.x, Pyboard D, ESP32 and ESP8266. All
323+
The code has been tested on Pyboard 1.x, Pyboard D, RP2, ESP32 and ESP8266. All
304324
except ESP8266 have good timing performance. Pyboards can be calibrated to
305325
timepiece precision using a cheap DS3231 and
306326
[this utility](https://github.com/peterhinch/micropython-samples/tree/master/DS3231).
@@ -377,4 +397,30 @@ available to the application including cancellation of scheduled tasks. The
377397
above code is incompatible with `uasyncio` because of the blocking calls to
378398
`time.sleep()`.
379399

400+
If scheduling a sequence to run at a future time please see
401+
[Initialisation](./SCHEDULE.md#45-initialisation).
402+
403+
##### [Top](./SCHEDULE.md#0-contents)
404+
405+
# 8. The simulate script
406+
407+
This enables the behaviour of sets of args to `schedule` to be rapidly checked.
408+
The `sim` function should be adapted to reflect the application specifics. The
409+
default is:
410+
```python
411+
def sim(*args):
412+
set_time(*args)
413+
cs = cron(hrs = 0, mins = 59)
414+
wait(cs)
415+
cn = cron(wday=(0, 5), hrs=(1, 10), mins = range(0, 60, 15))
416+
for _ in range(10):
417+
wait(cn)
418+
print("Run payload.\n")
419+
420+
sim(2023, 3, 29, 15, 20, 0) # Start time: year, month, mday, hrs, mins, secs
421+
```
422+
The `wait` function returns immediately, but prints the length of the delay and
423+
the value of system time when the delay ends. In this instance the start of a
424+
sequence is delayed to ensure that the first trigger occurs at 01:00.
425+
380426
##### [Top](./SCHEDULE.md#0-contents)

0 commit comments

Comments
 (0)