Skip to content

get_local_time improvements #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 16, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 49 additions & 25 deletions adafruit_portalbase/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@
)
# our strftime is %Y-%m-%d %H:%M:%S.%L %j %u %z %Z see http://strftime.net/ for decoding details
# See https://apidock.com/ruby/DateTime/strftime for full options
TIME_SERVICE_STRFTIME = (
"&fmt=%25Y-%25m-%25d+%25H%3A%25M%3A%25S.%25L+%25j+%25u+%25z+%25Z"
)
TIME_SERVICE_FORMAT = "%Y-%m-%d %H:%M:%S.%L %j %u %z %Z"
LOCALFILE = "local.txt"
# pylint: enable=line-too-long

Expand Down Expand Up @@ -157,17 +155,27 @@ def add_json_transform(self, json_transform):
else:
self.json_transform.extend(filter(callable, json_transform))

def get_local_time(self, location=None):
# pylint: disable=line-too-long
@staticmethod
def url_encode(url):
"""
Fetch and "set" the local time of this microcontroller to the local time at the location, using an internet time API.
A function to perform minimal URL encoding
"""
url = url.replace(" ", "+")
url = url.replace("%", "%25")
url = url.replace(":", "%3A")
return url

def get_strftime(self, time_format, location=None):
"""
Fetch a custom strftime relative to your location.

:param str location: Your city and country, e.g. ``"New York, US"``.
:param str location: Your city and country, e.g. ``"America/New_York"``.

"""
# pylint: enable=line-too-long
# pylint: disable=line-too-long
self.connect()
api_url = None
reply = None
try:
aio_username = self._secrets["aio_username"]
aio_key = self._secrets["aio_key"]
Expand All @@ -184,42 +192,58 @@ def get_local_time(self, location=None):
else: # we'll try to figure it out from the IP address
print("Getting time from IP address")
api_url = TIME_SERVICE % (aio_username, aio_key)
api_url += TIME_SERVICE_STRFTIME
api_url += "&fmt=" + self.url_encode(time_format)

try:
response = self._wifi.requests.get(api_url, timeout=10)
if response.status_code != 200:
print(response)
error_message = (
"Error connection to Adafruit IO. The response was: "
"Error connecting to Adafruit IO. The response was: "
+ response.text
)
raise RuntimeError(error_message)
if self._debug:
print("Time request: ", api_url)
print("Time reply: ", response.text)
times = response.text.split(" ")
the_date = times[0]
the_time = times[1]
year_day = int(times[2])
week_day = int(times[3])
is_dst = None # no way to know yet
reply = response.text
except KeyError:
raise KeyError(
"Was unable to lookup the time, try setting secrets['timezone'] according to http://worldtimeapi.org/timezones" # pylint: disable=line-too-long
) from KeyError
year, month, mday = [int(x) for x in the_date.split("-")]
the_time = the_time.split(".")[0]
hours, minutes, seconds = [int(x) for x in the_time.split(":")]
now = time.struct_time(
(year, month, mday, hours, minutes, seconds, week_day, year_day, is_dst)
)
if rtc is not None:
rtc.RTC().datetime = now

# now clean up
response.close()
response = None
gc.collect()

return reply

def get_local_time(self, location=None):
# pylint: disable=line-too-long
"""
Fetch and "set" the local time of this microcontroller to the local time at the location, using an internet time API.

:param str location: Your city and country, e.g. ``"America/New_York"``.

"""
reply = self.get_strftime(TIME_SERVICE_FORMAT, location=location)
if reply:
times = reply.split(" ")
the_date = times[0]
the_time = times[1]
year_day = int(times[2])
week_day = int(times[3])
is_dst = None # no way to know yet
year, month, mday = [int(x) for x in the_date.split("-")]
the_time = the_time.split(".")[0]
hours, minutes, seconds = [int(x) for x in the_time.split(":")]
now = time.struct_time(
(year, month, mday, hours, minutes, seconds, week_day, year_day, is_dst)
)

if rtc is not None:
rtc.RTC().datetime = now

def wget(self, url, filename, *, chunk_size=12000):
"""Download a url and save to filename location, like the command wget.

Expand Down