1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141 | """
A StopWatch class for tracking the amount of time between events
"""
from ev3dev2 import is_micropython
if is_micropython():
import utime
else:
import datetime as dt
def get_ticks_ms():
if is_micropython():
return utime.ticks_ms()
else:
return int(dt.datetime.timestamp(dt.datetime.now()) * 1000)
class StopWatchAlreadyStartedException(Exception):
"""
Exception raised when start() is called on a StopWatch which was already start()ed and not yet
stopped.
"""
pass
class StopWatch(object):
"""
A timer class which lets you start timing and then check the amount of time
elapsed.
"""
def __init__(self, desc=None):
"""
Initializes the StopWatch but does not start it.
desc:
A string description to print when stringifying.
"""
self.desc = desc
self._start_time = None
self._stopped_total_time = None
def __str__(self):
name = self.desc if self.desc is not None else self.__class__.__name__
return "{}: {}".format(name, self.hms_str)
def start(self):
"""
Starts the timer. If the timer is already running, resets it.
Raises a :py:class:`ev3dev2.stopwatch.StopWatchAlreadyStartedException` if already started.
"""
if self.is_started:
raise StopWatchAlreadyStartedException()
self._stopped_total_time = None
self._start_time = get_ticks_ms()
def stop(self):
"""
Stops the timer. The time value of this Stopwatch is paused and will not continue increasing.
"""
if self._start_time is None:
return
self._stopped_total_time = get_ticks_ms() - self._start_time
self._start_time = None
def reset(self):
"""
Resets the timer and leaves it stopped.
"""
self._start_time = None
self._stopped_total_time = None
def restart(self):
"""
Resets and then starts the timer.
"""
self.reset()
self.start()
@property
def is_started(self):
"""
True if the StopWatch has been started but not stoped (i.e., it's currently running), false otherwise.
"""
return self._start_time is not None
@property
def value_ms(self):
"""
Returns the value of the stopwatch in milliseconds
"""
if self._stopped_total_time is not None:
return self._stopped_total_time
return get_ticks_ms() - self._start_time if self._start_time is not None else 0
@property
def value_secs(self):
"""
Returns the value of the stopwatch in seconds
"""
return self.value_ms / 1000
@property
def value_hms(self):
"""
Returns this StopWatch's elapsed time as a tuple
``(hours, minutes, seconds, milliseconds)``.
"""
(hours, x) = divmod(int(self.value_ms), 3600000)
(mins, x) = divmod(x, 60000)
(secs, x) = divmod(x, 1000)
return hours, mins, secs, x
@property
def hms_str(self):
"""
Returns the stringified value of the stopwatch in HH:MM:SS.msec format
"""
return '%02d:%02d:%02d.%03d' % self.value_hms
def is_elapsed_ms(self, duration_ms):
"""
Returns True if this timer has measured at least ``duration_ms``
milliseconds.
Otherwise, returns False. If ``duration_ms`` is None, returns False.
"""
return duration_ms is not None and self.value_ms >= duration_ms
def is_elapsed_secs(self, duration_secs):
"""
Returns True if this timer has measured at least ``duration_secs`` seconds.
Otherwise, returns False. If ``duration_secs`` is None, returns False.
"""
return duration_secs is not None and self.value_secs >= duration_secs
|