diff --git a/Adafruit_IO/client.py b/Adafruit_IO/client.py index 7ffe7d3..fb1cb41 100644 --- a/Adafruit_IO/client.py +++ b/Adafruit_IO/client.py @@ -18,6 +18,7 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import time from time import struct_time import json import platform @@ -182,9 +183,19 @@ def receive_time(self): https://docs.python.org/3.7/library/time.html#time.struct_time """ path = 'integrations/time/struct.json' - time = self._get(path) - return struct_time((time['year'], time['mon'], time['mday'], time['hour'], - time['min'], time['sec'], time['wday'], time['yday'], time['isdst'])) + return self._parse_time_struct(self._get(path)) + + @staticmethod + def _parse_time_struct(time_dict: dict) -> time.struct_time: + """Parse the time data returned by the server and return a time_struct + + Corrects for the weekday returned by the server in Sunday=0 format + (Python expects Monday=0) + """ + wday = (time_dict['wday'] - 1) % 7 + return struct_time((time_dict['year'], time_dict['mon'], time_dict['mday'], + time_dict['hour'], time_dict['min'], time_dict['sec'], + wday, time_dict['yday'], time_dict['isdst'])) def receive_weather(self, weather_id=None): """Adafruit IO Weather Service, Powered by Dark Sky diff --git a/tests/test_client.py b/tests/test_client.py index c037411..c1190bb 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -23,7 +23,7 @@ class TestClient(base.IOTestCase): # If your IP isn't put on the list of non-throttled IPs, uncomment the # function below to waste time between tests to prevent throttling. #def tearDown(self): - time.sleep(30.0) + # time.sleep(30.0) # Helper Methods def get_client(self): @@ -138,7 +138,7 @@ def test_create_data(self): data = Data(value=42) result = aio.create_data('testfeed', data) self.assertEqual(int(result.value), 42) - + def test_location_data(self): """receive_location """ @@ -160,11 +160,41 @@ def test_time_data(self): """receive_time """ aio = self.get_client() - time = aio.receive_time() + server_time = aio.receive_time() # Check that each value is rx'd properly # (should never be None type) - for time_data in time: + for time_data in server_time: self.assertIsNotNone(time_data) + # Check that the week day was interpreted properly + adjusted_time = time.localtime(time.mktime(server_time)) + self.assertEqual(server_time.tm_wday, adjusted_time.tm_wday) + + def test_parse_time_struct(self): + """Ensure the _parse_time_struct method properly handles all 7 + week days. Particularly important to make sure Sunday is 6, + not -1""" + # Zero time is a dictionary as would be provided by server + # (wday is one higher than it should be) + zero_time = {'year': 1970, + 'mon': 1, + 'mday': 1, + 'hour': 0, + 'min': 0, + 'sec': 0, + 'wday': 4, + 'yday': 1, + 'isdst': 0} + + # Create a good struct for each day of the week and make sure + # the server-style dictionary is parsed correctly + for k in range(7): + real_struct = time.gmtime(k * 86400) + d = zero_time.copy() + d['mday'] += k + d['wday'] += k + d['yday'] += k + newd = Client._parse_time_struct(d) + self.assertEqual(newd.tm_wday, real_struct.tm_wday) # Test Feed Functionality def test_append_by_feed_name(self): @@ -269,3 +299,7 @@ def test_receive_group_by_key(self): group = io.create_group(Group(name='grouprx')) response = io.groups(group.key) self.assertEqual(response.key, 'grouprx') + + +if __name__ == "__main__": + unittest.main()