Skip to content

Commit 0c9b40a

Browse files
update time control package (Time, TimeController, TimeUtils, and other helpers)
1 parent 5ec198e commit 0c9b40a

4 files changed

Lines changed: 248 additions & 1 deletion

File tree

oshconnect/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from abc import ABC
2-
32
from dataclasses import dataclass
43
from enum import Enum
4+
import oshdatacore as swe_common
55

66

77
@dataclass(kw_only=True)
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import time
2+
from datetime import datetime, timezone
3+
from enum import Enum
4+
5+
6+
class TemporalMode(Enum):
7+
REAL_TIME = 0
8+
ARCHIVE = 1
9+
10+
11+
class State(Enum):
12+
UNINITIALIZED = 0
13+
INTIALIZED = 1
14+
STOPPED = 2
15+
BUFFERING = 3
16+
PLAYING = 4
17+
FAST_FORWARDING = 5
18+
REWINDING = 6
19+
20+
21+
class TimeUtils:
22+
@staticmethod
23+
def to_epoch_time(a_time: datetime | str) -> float:
24+
"""
25+
Convert a datetime or string to epoch time
26+
:param a_time:
27+
:return:
28+
"""
29+
if isinstance(a_time, str):
30+
return time.mktime(datetime.strptime(a_time, "%Y-%m-%d %H:%M:%S").timetuple())
31+
elif isinstance(a_time, datetime):
32+
return time.mktime(a_time.timetuple())
33+
34+
@staticmethod
35+
def to_utc_time(a_time: float | str) -> datetime:
36+
"""
37+
Convert epoch time or string to UTC time object
38+
:param a_time:
39+
:return:
40+
"""
41+
if isinstance(a_time, str):
42+
return datetime.strptime(a_time, "%Y-%m-%d %H:%M:%S").replace(tzinfo=timezone.utc)
43+
elif isinstance(a_time, float):
44+
return datetime.fromtimestamp(a_time, tz=timezone.utc)
45+
46+
@staticmethod
47+
def current_epoch_time():
48+
"""
49+
Get the current time in epoch format
50+
:return:
51+
"""
52+
return time.time()
53+
54+
@staticmethod
55+
def current_utc_time() -> datetime:
56+
"""
57+
Get the current time in UTC timezone
58+
:return:
59+
"""
60+
return datetime.now(timezone.utc)
61+
62+
@staticmethod
63+
def time_to_iso(a_time: datetime | float) -> str:
64+
"""
65+
Convert a datetime object to iso format
66+
:param a_time: datetime object in UTC timezone or epoch time (float)
67+
:return:
68+
"""
69+
if isinstance(a_time, float):
70+
return datetime.fromtimestamp(a_time, tz=timezone.utc).isoformat() + "Z"
71+
elif isinstance(a_time, datetime):
72+
return a_time.isoformat() + "Z"
73+
74+
75+
class Time:
76+
_epoch_time: float
77+
78+
def __init__(self, epoch_time: float = None, utc_time: datetime = None):
79+
if epoch_time is not None:
80+
self._epoch_time = epoch_time
81+
elif utc_time is not None:
82+
self._epoch_time = TimeUtils.to_epoch_time(utc_time)
83+
84+
@property
85+
def epoch_time(self):
86+
return self._epoch_time
87+
88+
@epoch_time.setter
89+
def epoch_time(self, epoch_time: float):
90+
if hasattr(self, "_epoch_time"):
91+
raise AttributeError("Epoch time should not be changed once set")
92+
93+
def get_epoch_time(self):
94+
return self._epoch_time
95+
96+
def get_utc_time(self):
97+
return TimeUtils.to_utc_time(self._epoch_time)
98+
99+
100+
class IndeterminateTime(Enum):
101+
NOW = "now"
102+
# LATEST = "latest"
103+
# FIRST = "first"
104+
105+
106+
class TimePeriod:
107+
_start_time: Time | IndeterminateTime
108+
_end_time: Time | IndeterminateTime
109+
110+
def __init__(self, start_time: Time | IndeterminateTime, end_time: Time | IndeterminateTime):
111+
if isinstance(start_time, Time) and isinstance(end_time, Time):
112+
if start_time.get_epoch_time() > end_time.get_epoch_time():
113+
raise ValueError("Start time cannot be later than end time")
114+
115+
if isinstance(start_time, IndeterminateTime) and isinstance(end_time, IndeterminateTime):
116+
raise ValueError("Start time and end time cannot be indeterminate at the same time")
117+
118+
self._start_time = start_time
119+
self._end_time = end_time
120+
121+
def get_start_time(self):
122+
return self._start_time
123+
124+
def get_end_time(self):
125+
return self._end_time
126+
127+
def set_start_time(self, start_time: Time):
128+
self._start_time = start_time
129+
130+
def set_end_time(self, end_time: Time):
131+
self._end_time = end_time
132+
133+
def is_indeterminate_start_time(self):
134+
return isinstance(self._start_time, IndeterminateTime)
135+
136+
def is_indeterminate_end_time(self):
137+
return isinstance(self._end_time, IndeterminateTime)
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
from __future__ import annotations
2+
3+
import datetime
4+
5+
from oshdatacore import component_implementations as swe_common_components
6+
7+
from oshconnect.timemanagement import Time, TemporalMode
8+
9+
10+
class TimeManagement:
11+
time = swe_common_components.TimeComponent()
12+
time_controller: TimeController
13+
14+
15+
class TimeController:
16+
_instance = None
17+
_temporal_mode: TemporalMode
18+
_status: str
19+
_playback_speed: int
20+
_timeline_begin: Time
21+
_timeline_end: Time
22+
_current_time: Time
23+
24+
def __new__(cls, *args, **kwargs):
25+
if cls._instance is None:
26+
cls._instance = super(TimeController, cls).__new__(cls)
27+
return cls._instance
28+
29+
def set_temporal_mode(self, mode: TemporalMode):
30+
self._temporal_mode = mode
31+
32+
def get_temporal_mode(self):
33+
return self._temporal_mode
34+
35+
def start(self):
36+
pass
37+
38+
def pause(self):
39+
pass
40+
41+
def stop(self):
42+
pass
43+
44+
def fast_forward(self, speed: int):
45+
self._playback_speed = speed
46+
47+
def rewind(self, speed: int):
48+
self._playback_speed = speed
49+
50+
def skip(self, a_time: Time):
51+
self._current_time = a_time
52+
53+
def get_status(self):
54+
return self._status
55+
56+
def set_timeline_start(self, a_time: Time):
57+
self._timeline_begin = a_time
58+
59+
def set_timeline_end(self, a_time: Time):
60+
self._timeline_end = a_time
61+
62+
def set_current_time(self, a_time: Time):
63+
if a_time < self._timeline_begin:
64+
self._current_time = self._timeline_begin
65+
elif a_time > self._timeline_end:
66+
self._timeline_end = a_time
67+
self._current_time = a_time
68+
69+
def get_timeline_start(self):
70+
return self._timeline_begin
71+
72+
def get_timeline_end(self):
73+
return self._timeline_end
74+
75+
def get_current_time(self):
76+
return self._current_time
77+
78+
def play_from_start(self):
79+
pass
80+
81+
def skip_to_end(self):
82+
pass
83+
84+
def add_listener(self, datastream, event_listener) -> str:
85+
pass
86+
87+
def remove_listener(self, stream_id):
88+
pass
89+
90+
def clear_streams(self):
91+
pass
92+
93+
def reset(self):
94+
self.clear_streams()
95+
self._temporal_mode = None
96+
self._status = None
97+
self._playback_speed = None
98+
self._timeline_begin = None
99+
self._timeline_end = None
100+
self._current_time = None
101+
102+
def set_buffer_time(self, time: int):
103+
pass
104+
105+
def get_buffer_time(self):
106+
pass
107+
108+
def _compute_time_range(self):
109+
pass

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ readme = "README.md"
88
[tool.poetry.dependencies]
99
python = "^3.12"
1010
consys4py = { git = "https://github.com/Botts-Innovative-Research/CSAPI4Py.git", branch = "dev" }
11+
oshdatacore = { git = "https://github.com/ChainReaction31/py_osh_data_core.git", branch = "master" }
1112

1213

1314
[build-system]

0 commit comments

Comments
 (0)