-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from brainelectronics/feature/support-rtc
Add support for RTC
- Loading branch information
Showing
5 changed files
with
342 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: UTF-8 -*- | ||
|
||
""" | ||
Main script | ||
Do your stuff here, this file is similar to the loop() function on Arduino | ||
Example on how to interact with a RTC | ||
""" | ||
|
||
# system packages | ||
import time | ||
|
||
# custom packages | ||
from nextion import NexHardware, NexRtc | ||
|
||
# define communication pins for Nextion display | ||
tx_pin = 21 | ||
rx_pin = 22 | ||
|
||
# create Nextion hardware interface | ||
nh = NexHardware(rx_pin=rx_pin, tx_pin=tx_pin) | ||
|
||
# init nextion communication interface | ||
nh.nexInit() | ||
|
||
# create a RTC instance | ||
rtc = NexRtc(nh) | ||
|
||
# ============================================================================ | ||
# ============================ Sync time with NTP ============================ | ||
try: | ||
import network | ||
import ntptime | ||
|
||
station = network.WLAN(network.STA_IF) | ||
if station.isconnected(): | ||
ntptime.settime() | ||
else: | ||
print('Device not connected to the internet, using available time') | ||
except Exception as e: | ||
print('Unexpected exception {} occured, using available time'.format(e)) | ||
|
||
# cut off weekday and yearday, keep [year, month, mday, hour, minute, second] | ||
localtime = list(time.localtime())[0:6] | ||
|
||
# ============================================================================ | ||
# ============================ Set RTC functions ============================= | ||
# set RTC time to list of integers '[2022, 7, 30, 18, 21, 45]' | ||
print('Set RTC time to: {}'.format(localtime)) | ||
rtc.write_rtc_time(localtime) | ||
print() | ||
|
||
time.sleep(1) | ||
|
||
# set RTC time to time string '2022,07,30,18,21,45' | ||
localtime_str = ','.join('{:02d}'.format(x) for x in localtime) | ||
print('Set RTC time to: "{}"'.format(localtime_str)) | ||
rtc.write_rtc_time(localtime_str) | ||
print() | ||
|
||
time.sleep(1) | ||
|
||
# set only year of RTC | ||
print('Set only year of RTC to: "{}"'.format(localtime[0])) | ||
rtc.write_rtc_time('year', localtime[0]) | ||
print() | ||
|
||
time.sleep(1) | ||
|
||
# ============================================================================ | ||
# ============================ Get RTC functions ============================= | ||
# get RTC time as string | ||
response = rtc.read_rtc_time('str') | ||
print('Timestamp from RTC as string: "{}"'.format(response)) | ||
print() | ||
|
||
time.sleep(1) | ||
|
||
# get RTC time as list of integers | ||
response = rtc.read_rtc_time('int') | ||
print('Timestamp from RTC list of integers: "{}"'.format(response)) | ||
print() | ||
|
||
time.sleep(1) | ||
|
||
# get available time types from RTC one by one | ||
print('Get individual time types from RTC...') | ||
for time_type in rtc.time_types: | ||
response = rtc.read_rtc_time(time_type) | ||
print('{} by RTC: "{}"'.format(time_type, response)) | ||
print() | ||
|
||
# ============================================================================ | ||
# ============================= End of example =============================== | ||
print('Returning to REPL in 5 seconds') | ||
|
||
# wait for 5 more seconds to safely finish the may still running threads | ||
time.sleep(5) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: UTF-8 -*- | ||
|
||
""" | ||
NexRtc | ||
Functions to interact with Nextion RTC | ||
""" | ||
|
||
# system packages | ||
from time import sleep | ||
|
||
# custom packages | ||
from .common import Common | ||
from .typing import List, Optional, Union | ||
|
||
|
||
class NexRtcError(Exception): | ||
"""Base class for exceptions in this module.""" | ||
pass | ||
|
||
|
||
class NexRtc(Common): | ||
"""docstring for NexRtc""" | ||
def __init__(self, nh) -> None: | ||
""" | ||
Init RTC | ||
:param nh: The Nextion hardware interface object | ||
:type nh: NexHardware | ||
""" | ||
super().__init__(nh, pid=-1, cid=-1, name="rtc") | ||
|
||
self._time_types = ["year", "mon", "day", "hour", "min", "sec", "week"] | ||
|
||
@property | ||
def time_types(self) -> List[str]: | ||
""" | ||
Get available time types | ||
:returns: Requestable time types from RTC | ||
:rtype: List[str] | ||
""" | ||
return self._time_types | ||
|
||
def write_rtc_time(self, *args, **kwargs) -> bool: | ||
""" | ||
Write time to RTC | ||
:param time: The time to set the RTC | ||
:type time: Union[str, List[int]] | ||
:param time_type: The type of time to change | ||
:type time_type: str | ||
:returns: True on success, False otherwise | ||
:rtype: bool | ||
""" | ||
if (len(args) + len(kwargs) == 1): | ||
# only a time is given | ||
if len(args): | ||
time = args[0] | ||
else: | ||
time = kwargs["time"] | ||
if isinstance(time, str) and len(time) >= 19: | ||
# "2016,11,25,12,34,50" | ||
year = time[0:4] | ||
month = time[5:7] | ||
day = time[8:10] | ||
hour = time[11:13] | ||
minute = time[14:16] | ||
second = time[17:19] | ||
elif (isinstance(time, list) and | ||
all(isinstance(x, int) for x in time)): | ||
# [2016, 11, 25, 12, 34, 50] | ||
year = time[0] | ||
month = time[1] | ||
day = time[2] | ||
hour = time[3] | ||
minute = time[4] | ||
second = time[5] | ||
else: | ||
raise NexRtcError("Time can either be given as '{}' or '{}'". | ||
format("2016,11,25,12,34,50", | ||
[2016, 11, 25, 12, 34, 50])) | ||
|
||
self._nh._logger.debug("Timestamp (ISO8601): {}-{}-{}T{}:{}:{}". | ||
format(year, month, day, hour, minute, | ||
second)) | ||
|
||
cmd = "rtc0={}".format(year) | ||
self._nh.sendCommand(cmd) | ||
self._nh.recvRetCommandFinished() | ||
|
||
cmd = "rtc1={}".format(month) | ||
self._nh.sendCommand(cmd) | ||
self._nh.recvRetCommandFinished() | ||
|
||
cmd = "rtc2={}".format(day) | ||
self._nh.sendCommand(cmd) | ||
self._nh.recvRetCommandFinished() | ||
|
||
cmd = "rtc3={}".format(hour) | ||
self._nh.sendCommand(cmd) | ||
self._nh.recvRetCommandFinished() | ||
|
||
cmd = "rtc4={}".format(minute) | ||
self._nh.sendCommand(cmd) | ||
self._nh.recvRetCommandFinished() | ||
|
||
cmd = "rtc5={}".format(second) | ||
self._nh.sendCommand(cmd) | ||
return self._nh.recvRetCommandFinished() | ||
elif (len(args) + len(kwargs) == 2): | ||
# time_type is given as well | ||
if len(kwargs) == 2: | ||
time_type = kwargs['time_type'] | ||
time = kwargs['time'] | ||
else: | ||
if len(args) == 2: | ||
time_type = args[0] | ||
time = args[1] | ||
else: | ||
raise NexRtcError("Either use keyword or positional args") | ||
|
||
self._nh._logger.debug("Set '{}' to '{}'".format(time_type, time)) | ||
rtc_index = self.time_types.index(time_type.lower()) | ||
|
||
cmd = "rtc{}={}".format(rtc_index, time) | ||
self._nh.sendCommand(cmd) | ||
return self._nh.recvRetCommandFinished() | ||
else: | ||
raise NexRtcError("Only two args are allowed") | ||
|
||
def read_rtc_time(self, | ||
return_type: str, | ||
length: Optional[int] = 22) -> Union[str, List[int]]: | ||
""" | ||
Read RTC time | ||
:param return_type: The return type, choose "int", "str" or from | ||
["year", "mon", "day", "hour", "min", "sec", | ||
"week"] | ||
:type return_type: str | ||
:param length: The length | ||
:type length: Optional[int] | ||
:returns: RTC time | ||
:rtype: Union[str, List[int]] | ||
""" | ||
return_type = return_type.lower() | ||
|
||
if return_type in ["str", "int"]: | ||
cmd = "get rtc0" | ||
self._nh.sendCommand(cmd) | ||
sleep(0.1) # necessary, data might not be available otherwise | ||
year = self._nh.recvRetNumber() | ||
|
||
cmd = "get rtc1" | ||
self._nh.sendCommand(cmd) | ||
sleep(0.1) # necessary, data might not be available otherwise | ||
month = self._nh.recvRetNumber() | ||
|
||
cmd = "get rtc2" | ||
self._nh.sendCommand(cmd) | ||
sleep(0.1) # necessary, data might not be available otherwise | ||
day = self._nh.recvRetNumber() | ||
|
||
cmd = "get rtc3" | ||
self._nh.sendCommand(cmd) | ||
sleep(0.1) # necessary, data might not be available otherwise | ||
hour = self._nh.recvRetNumber() | ||
|
||
cmd = "get rtc4" | ||
self._nh.sendCommand(cmd) | ||
sleep(0.1) # necessary, data might not be available otherwise | ||
minute = self._nh.recvRetNumber() | ||
|
||
cmd = "get rtc5" | ||
self._nh.sendCommand(cmd) | ||
sleep(0.1) # necessary, data might not be available otherwise | ||
second = self._nh.recvRetNumber() | ||
|
||
cmd = "get rtc6" | ||
self._nh.sendCommand(cmd) | ||
sleep(0.1) # necessary, data might not be available otherwise | ||
week = self._nh.recvRetNumber() | ||
|
||
time_buf = [year, month, day, hour, minute, second, week] | ||
|
||
if return_type == "str": | ||
time_string = ("{}/{}/{} {}:{}:{} {}". | ||
format(year, month, day, hour, minute, second, | ||
week)) | ||
if length >= 22: | ||
return time_string | ||
else: | ||
return time_string[0:length] | ||
elif return_type == "int": | ||
if length >= 7: | ||
return time_buf | ||
else: | ||
return time_buf[0:length] | ||
elif return_type in self.time_types: | ||
rtc_index = self.time_types.index(return_type) | ||
cmd = "get rtc{}".format(rtc_index) | ||
self._nh.sendCommand(cmd) | ||
sleep(0.1) # necessary, data might not be available otherwise | ||
return self._nh.recvRetNumber() | ||
else: | ||
raise NexRtcError("RTC time can only be returned as '{}' or '{}'" | ||
"or chosen from {}". | ||
format("str", "int", self.time_types)) |