From becb9704e821a91ac50fc150b56a5380256674da Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 21:13:02 -0400 Subject: [PATCH 1/3] Add select next or previous child using child index --- .python-version | 2 +- .vscode/settings.json | 2 +- Makefile | 5 +++++ firmware/lib/scout.py | 26 ++++++++++++++++++++++++++ firmware/main.py | 4 ++-- 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/.python-version b/.python-version index 1281604..6f80e59 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.10.7 +micropython-1.19.1 diff --git a/.vscode/settings.json b/.vscode/settings.json index 9fea9f5..7e6ef1f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,6 +8,6 @@ "python.analysis.extraPaths": [ ".vscode/Pico-W-Stub/stubs" ], - "picowgo.syncFolder": "firmware", + "picowgo.syncFolder": "dist", "picowgo.openOnStart": true } \ No newline at end of file diff --git a/Makefile b/Makefile index fa46902..b6d091a 100644 --- a/Makefile +++ b/Makefile @@ -5,3 +5,8 @@ run_tests: pytest --cov=firmware/lib coverage xml coverage report --fail-under=80 + +dist: + mkdir -p dist + cp -r firmware/* dist + python -m upip install -r requirements.txt -p 'dist/' diff --git a/firmware/lib/scout.py b/firmware/lib/scout.py index da8d69e..d0ffa98 100644 --- a/firmware/lib/scout.py +++ b/firmware/lib/scout.py @@ -9,6 +9,7 @@ def __init__(self, base_url): self.base_url = base_url self.children = [] self.init_children() + self.child_index = None def init_children(self): path = "children" @@ -100,6 +101,31 @@ def bottle_feed(self, child_id): self.resolve_timers(child_id, activity, data) print("Recorded Bottle Feeding") + def next_child(self): + if len(self.children) == 0: + raise IndexError("No children setup in BabyBuddy") + if self.child_index == None: + self.child_index = 0 + return self.children[0] + max_index = len(self.children) - 1 + new_index = self.child_index + 1 + if new_index > max_index: + new_index = 0 + self.child_index = new_index + return self.children[new_index] + + def previous_child(self): + if len(self.children) == 0: + raise IndexError("No children setup in BabyBuddy") + if self.child_index == None: + self.child_index = len(self.children) - 1 + return self.children[self.child_index] + max_index = len(self.children) - 1 + new_index = self.child_index - 1 + if new_index < max_index: + new_index = len(self.children) - 1 + self.child_index = new_index + return self.children[new_index] def connect_to_baby_buddy(base_url): # Attempt to establish connection to BabyBuddy Instance diff --git a/firmware/main.py b/firmware/main.py index f067b10..7b1202c 100644 --- a/firmware/main.py +++ b/firmware/main.py @@ -28,6 +28,7 @@ ) BABY_SCOUT = connect_to_baby_buddy(base_url=WLAN_VARIABLES["BASE_URL"]) # Set default to first child in BabyBuddy, add functionality to allow for toggling between multiple children. + BABY_SCOUT.next_child() child = BABY_SCOUT.children[0] # Create button matrix, matching gpio pin to the specific action you want to capture @@ -49,7 +50,6 @@ buttons.append(create_button(button)) # Loop through and check if any button has been pressed. - def button_pressed(): while True: for index, button in enumerate(buttons): @@ -57,7 +57,7 @@ def button_pressed(): onboard_led(1) time.sleep(0.5) onboard_led(0) - button_actions[index](child) + button_actions[index](BABY_SCOUT.children[BABY_SCOUT.child_index]) # Continually check and assure connectivity to wireless and babyscout From fc7b7510380d1dcce57bdd851dc2f155ee89f770 Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 21:33:04 -0400 Subject: [PATCH 2/3] Add unit tests and fix issue with previous child logic --- firmware/lib/scout.py | 3 +- tests/test_scout.py | 71 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/firmware/lib/scout.py b/firmware/lib/scout.py index d0ffa98..2c2214e 100644 --- a/firmware/lib/scout.py +++ b/firmware/lib/scout.py @@ -120,9 +120,8 @@ def previous_child(self): if self.child_index == None: self.child_index = len(self.children) - 1 return self.children[self.child_index] - max_index = len(self.children) - 1 new_index = self.child_index - 1 - if new_index < max_index: + if new_index < 0: new_index = len(self.children) - 1 self.child_index = new_index return self.children[new_index] diff --git a/tests/test_scout.py b/tests/test_scout.py index 4c839ef..a043691 100644 --- a/tests/test_scout.py +++ b/tests/test_scout.py @@ -1,5 +1,6 @@ from unittest.mock import patch from lib.scout import Scout, connect_to_baby_buddy, send_api_request +import pytest with patch('lib.scout.send_api_request') as mock_api: scout = Scout("fake_url") @@ -108,4 +109,72 @@ def test_resolve_timers_current_timer(mock_api_request): mock_api_request.side_effect = [{"results": [{"name": "sleep", "child": 0, "active": True, "id": 0}]}, None] # Test Initializing Scout class timer = scout.resolve_timers(0, "sleep", {"timer": 0}) - assert timer == None \ No newline at end of file + assert timer == None + +@patch('lib.scout.send_api_request') +def test_next_child(mock_api_request): + # Test Initializing Scout class + mock_api_request.side_effect = [{"results": [{"id": 3}]}] + scout = Scout("fake_url") + next_child = scout.next_child() + assert next_child == 3 + +@patch('lib.scout.send_api_request') +def test_next_child_no_children(mock_api_request): + # Test Initializing Scout class + scout = Scout("fake_url") + with pytest.raises(IndexError) as e: + next_child = scout.next_child() + +@patch('lib.scout.send_api_request') +def test_next_next_child(mock_api_request): + # Test Initializing Scout class + mock_api_request.side_effect = [{"results": [{"id": 3}, {"id": 5}]}] + scout = Scout("fake_url") + next_child = scout.next_child() + next_child = scout.next_child() + assert next_child == 5 + +@patch('lib.scout.send_api_request') +def test_next_put_of_index_child(mock_api_request): + # Test Initializing Scout class + mock_api_request.side_effect = [{"results": [{"id": 3}, {"id": 5}]}] + scout = Scout("fake_url") + next_child = scout.next_child() + next_child = scout.next_child() + next_child = scout.next_child() + assert next_child == 3 + +@patch('lib.scout.send_api_request') +def test_previous_child(mock_api_request): + # Test Initializing Scout class + mock_api_request.side_effect = [{"results": [{"id": 3}, {"id": 5}]}] + scout = Scout("fake_url") + previous_child = scout.previous_child() + assert previous_child == 5 + +@patch('lib.scout.send_api_request') +def test_previous_child_no_children(mock_api_request): + # Test Initializing Scout class + scout = Scout("fake_url") + with pytest.raises(IndexError) as e: + previous_child = scout.previous_child() + +@patch('lib.scout.send_api_request') +def test_previous_previous_child(mock_api_request): + # Test Initializing Scout class + mock_api_request.side_effect = [{"results": [{"id": 3}, {"id": 5}]}] + scout = Scout("fake_url") + previous_child = scout.previous_child() + previous_child = scout.previous_child() + assert previous_child == 3 + +@patch('lib.scout.send_api_request') +def test_previous_out_of_index_child(mock_api_request): + # Test Initializing Scout class + mock_api_request.side_effect = [{"results": [{"id": 3}, {"id": 5}]}] + scout = Scout("fake_url") + previous_child = scout.previous_child() + previous_child = scout.previous_child() + previous_child = scout.previous_child() + assert previous_child == 5 \ No newline at end of file From 914e9f1b8486db329f887d99892a3b9ba3f8d429 Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 21:35:22 -0400 Subject: [PATCH 3/3] Remove redundant comments in test --- tests/test_scout.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/tests/test_scout.py b/tests/test_scout.py index a043691..e4b84ed 100644 --- a/tests/test_scout.py +++ b/tests/test_scout.py @@ -7,49 +7,41 @@ @patch('lib.scout.send_api_request') def test_init_scout_children(mock_api_request): - # Test Initializing Scout class scout.init_children() mock_api_request.assert_called_with("fake_url", "children") @patch('lib.scout.send_api_request') def test_bottle_feed(mock_api_request): - # Test Initializing Scout class scout.bottle_feed(0) mock_api_request.assert_called_with('fake_url', path='timers', data={'child': 0, 'name': 'feedings'}) @patch('lib.scout.send_api_request') def test_right_breast(mock_api_request): - # Test Initializing Scout class scout.right_breast(0) mock_api_request.assert_called_with('fake_url', path='timers', data={'child': 0, 'name': 'feedings'}) @patch('lib.scout.send_api_request') def test_left_breast(mock_api_request): - # Test Initializing Scout class scout.left_breast(0) mock_api_request.assert_called_with('fake_url', path='timers', data={'child': 0, 'name': 'feedings'}) @patch('lib.scout.send_api_request') def test_both_breasts(mock_api_request): - # Test Initializing Scout class scout.breast_feed(0) mock_api_request.assert_called_with('fake_url', path='timers', data={'child': 0, 'name': 'feedings'}) @patch('lib.scout.send_api_request') def test_wet_solid_diaper(mock_api_request): - # Test Initializing Scout class scout.wet_solid_diaper(0) mock_api_request.assert_called_with('fake_url', 'changes', data={'wet': True, 'solid': True, 'child': 0}) @patch('lib.scout.send_api_request') def test_solid_diaper(mock_api_request): - # Test Initializing Scout class scout.solid_diaper(0) mock_api_request.assert_called_with('fake_url', 'changes', data={'wet': False, 'solid': True, 'child': 0}) @patch('lib.scout.send_api_request') def test_wet_diaper(mock_api_request): - # Test Initializing Scout class scout.wet_diaper(0) mock_api_request.assert_called_with('fake_url', 'changes', data={'wet': True, 'solid': False, 'child': 0}) @@ -57,7 +49,6 @@ def test_wet_diaper(mock_api_request): @patch('lib.scout.send_api_request') def test_conect_to_baby_buddy(mock_api_request): mock_api_request.side_effect = [OSError("test"), {"results": [{"id": 1}]}] - # Test Initializing Scout class scout = connect_to_baby_buddy('fake_url') mock_api_request.assert_called_with('fake_url', 'children') @@ -87,33 +78,28 @@ def __init__(self): @patch('lib.scout.send_api_request') def test_sleep(mock_api_request): - # Test Initializing Scout class scout.sleep(0) mock_api_request.assert_called_with('fake_url', path='timers', data={'child': 0, 'name': 'sleep'}) @patch('lib.scout.send_api_request') def test_tummy_time(mock_api_request): - # Test Initializing Scout class scout.tummy_time(0) mock_api_request.assert_called_with('fake_url', path='timers', data={'child': 0, 'name': 'tummy-times'}) @patch('lib.scout.send_api_request') def test_get_timers(mock_api_request): mock_api_request.side_effect = [{"results": [{"name": "sleep", "child": 0, "active": True}]}] - # Test Initializing Scout class timer = scout.get_timer(0, "sleep") assert timer == {'active': True, 'child': 0, 'name': 'sleep'} @patch('lib.scout.send_api_request') def test_resolve_timers_current_timer(mock_api_request): mock_api_request.side_effect = [{"results": [{"name": "sleep", "child": 0, "active": True, "id": 0}]}, None] - # Test Initializing Scout class timer = scout.resolve_timers(0, "sleep", {"timer": 0}) assert timer == None @patch('lib.scout.send_api_request') def test_next_child(mock_api_request): - # Test Initializing Scout class mock_api_request.side_effect = [{"results": [{"id": 3}]}] scout = Scout("fake_url") next_child = scout.next_child() @@ -121,14 +107,12 @@ def test_next_child(mock_api_request): @patch('lib.scout.send_api_request') def test_next_child_no_children(mock_api_request): - # Test Initializing Scout class scout = Scout("fake_url") with pytest.raises(IndexError) as e: next_child = scout.next_child() @patch('lib.scout.send_api_request') def test_next_next_child(mock_api_request): - # Test Initializing Scout class mock_api_request.side_effect = [{"results": [{"id": 3}, {"id": 5}]}] scout = Scout("fake_url") next_child = scout.next_child() @@ -137,7 +121,6 @@ def test_next_next_child(mock_api_request): @patch('lib.scout.send_api_request') def test_next_put_of_index_child(mock_api_request): - # Test Initializing Scout class mock_api_request.side_effect = [{"results": [{"id": 3}, {"id": 5}]}] scout = Scout("fake_url") next_child = scout.next_child() @@ -147,7 +130,6 @@ def test_next_put_of_index_child(mock_api_request): @patch('lib.scout.send_api_request') def test_previous_child(mock_api_request): - # Test Initializing Scout class mock_api_request.side_effect = [{"results": [{"id": 3}, {"id": 5}]}] scout = Scout("fake_url") previous_child = scout.previous_child() @@ -155,14 +137,12 @@ def test_previous_child(mock_api_request): @patch('lib.scout.send_api_request') def test_previous_child_no_children(mock_api_request): - # Test Initializing Scout class scout = Scout("fake_url") with pytest.raises(IndexError) as e: previous_child = scout.previous_child() @patch('lib.scout.send_api_request') def test_previous_previous_child(mock_api_request): - # Test Initializing Scout class mock_api_request.side_effect = [{"results": [{"id": 3}, {"id": 5}]}] scout = Scout("fake_url") previous_child = scout.previous_child() @@ -171,7 +151,6 @@ def test_previous_previous_child(mock_api_request): @patch('lib.scout.send_api_request') def test_previous_out_of_index_child(mock_api_request): - # Test Initializing Scout class mock_api_request.side_effect = [{"results": [{"id": 3}, {"id": 5}]}] scout = Scout("fake_url") previous_child = scout.previous_child()