diff --git a/README.md b/README.md index 9f9b567..58cfae5 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,8 @@ indego.update_location() | | | indego.update_network() | ? | ? | ? indego.update_next_mow() | | | indego.update_operating_data() | | X | +indego.update_predictive_calendar()| X | | +indego.update_predictive_schedule()| X | | indego.update_security() | X | | indego.update_setup() | X | | indego.update_state() | X | | @@ -135,6 +137,20 @@ Update the indego.operating_data with data about battery, runtime, garden data a OperatingData(hmiKeys=1768, battery=Battery(percent=357, voltage=35.7, cycles=0, discharge=0.0, ambient_temp=26, battery_temp=26, percent_adjusted=83), garden=Garden(id=8, name=1, signal_id=1, size=769, inner_bounds=3, cuts=15, runtime=166824, charge=37702, bumps=6646, stops=29, last_mow=1, map_cell_size=None), runtime=Runtime(total=RuntimeDetail(operate=1715, charge=387, cut=1328), session=RuntimeDetail(operate=9, charge=0, cut=0))) ``` +### indego.predictive_calendar() +Updates the predictive_calendar with the timeslots (days and hours) where the user wants smart mowing not to mow the lawn. + +```python +PredictiveCalendar(cal=1, days=[CalendarDay(day=0, day_name='monday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=8, EnMin=0, Attr=None), CalendarSlot(En=True, StHr=20, StMin=0, EnHr=23, EnMin=59, Attr=None)]), CalendarDay(day=1, day_name='tuesday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=8, EnMin=0, Attr=None), CalendarSlot(En=True, StHr=20, StMin=0, EnHr=23, EnMin=59, Attr=None)]), CalendarDay(day=2, day_name='wednesday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=8, EnMin=0, Attr=None), CalendarSlot(En=True, StHr=20, StMin=0, EnHr=23, EnMin=59, Attr=None)]), CalendarDay(day=3, day_name='thursday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=8, EnMin=0, Attr=None), CalendarSlot(En=True, StHr=20, StMin=0, EnHr=23, EnMin=59, Attr=None)]), CalendarDay(day=4, day_name='friday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=8, EnMin=0, Attr=None), CalendarSlot(En=True, StHr=20, StMin=0, EnHr=23, EnMin=59, Attr=None)]), CalendarDay(day=5, day_name='saturday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=8, EnMin=0, Attr=None), CalendarSlot(En=True, StHr=20, StMin=0, EnHr=23, EnMin=59, Attr=None)]), CalendarDay(day=6, day_name='sunday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=23, EnMin=59, Attr=None)])]) +``` + +### indego.predictive_schedule() +Updates the predictive_schedule with the next planned mows (schedule_days) and the days where the smart mowing will not mow the lawn. The latter is combined by the time slots where the user does not want the Indego to mow (Attr='C') and the slots where the weather conditions prevent the mowing (e.g., Attr='pP'). + +```python +PredictiveSchedule(schedule_days=[CalendarDay(day=0, day_name='monday', slots=[CalendarSlot(En=True, StHr=10, StMin=0, EnHr=13, EnMin=0, Attr=None)]), CalendarDay(day=2, day_name='wednesday', slots=[CalendarSlot(En=True, StHr=10, StMin=0, EnHr=13, EnMin=0, Attr=None)]), CalendarDay(day=4, day_name='friday', slots=[CalendarSlot(En=True, StHr=10, StMin=0, EnHr=13, EnMin=0, Attr=None)])], exclusion_days=[CalendarDay(day=0, day_name='monday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=8, EnMin=0, Attr='C'), CalendarSlot(En=True, StHr=20, StMin=0, EnHr=23, EnMin=59, Attr='C')]), CalendarDay(day=1, day_name='tuesday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=8, EnMin=0, Attr='C'), CalendarSlot(En=True, StHr=20, StMin=0, EnHr=23, EnMin=59, Attr='C')]), CalendarDay(day=2, day_name='wednesday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=8, EnMin=0, Attr='C'), CalendarSlot(En=True, StHr=20, StMin=0, EnHr=23, EnMin=59, Attr='C')]), CalendarDay(day=3, day_name='thursday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=8, EnMin=0, Attr='C'), CalendarSlot(En=True, StHr=8, StMin=0, EnHr=12, EnMin=0, Attr='pP'), CalendarSlot(En=True, StHr=13, StMin=0, EnHr=15, EnMin=0, Attr='Pp'), CalendarSlot(En=True, StHr=20, StMin=0, EnHr=23, EnMin=59, Attr='C')]), CalendarDay(day=4, day_name='friday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=8, EnMin=0, Attr='C'), CalendarSlot(En=True, StHr=20, StMin=0, EnHr=23, EnMin=59, Attr='C')]), CalendarDay(day=5, day_name='saturday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=8, EnMin=0, Attr='C'), CalendarSlot(En=True, StHr=20, StMin=0, EnHr=23, EnMin=59, Attr='C')]), CalendarDay(day=6, day_name='sunday', slots=[CalendarSlot(En=True, StHr=0, StMin=0, EnHr=23, EnMin=59, Attr='C')])]) +``` + ### indego.update_security() Updates the indego.security with information about the Indego security state. @@ -364,6 +380,7 @@ get /alms//predictive/lastcutting /alms//predictive/location /alms//predictive/nextcutting +/alms//predictive/schedule /alms//predictive/useradjustment /alms//predictive/weather /alms//security diff --git a/pyIndego/const.py b/pyIndego/const.py index d6bc60a..a28b3c0 100644 --- a/pyIndego/const.py +++ b/pyIndego/const.py @@ -222,7 +222,7 @@ class Methods(Enum): DAY_MAPPING = { 0: "monday", - 1: "teusday", + 1: "tuesday", 2: "wednesday", 3: "thursday", 4: "friday", diff --git a/pyIndego/indego_async_client.py b/pyIndego/indego_async_client.py index 68b413e..64e81d1 100644 --- a/pyIndego/indego_async_client.py +++ b/pyIndego/indego_async_client.py @@ -223,6 +223,14 @@ async def update_operating_data(self): await self.get(f"alms/{self._serial}/operatingData") ) + async def update_predictive_calendar(self): + """Update predictive_calendar.""" + self._update_predictive_calendar(await self.get(f"alms/{self._serial}/predictive/calendar")) + + async def update_predictive_schedule(self): + """Update predictive_schedule.""" + self._update_predictive_schedule(await self.get(f"alms/{self._serial}/predictive/schedule")) + async def update_security(self): """Update security.""" self._update_security(await self.get(f"alms/{self._serial}/security")) diff --git a/pyIndego/indego_base_client.py b/pyIndego/indego_base_client.py index 540e4d6..cf172cf 100644 --- a/pyIndego/indego_base_client.py +++ b/pyIndego/indego_base_client.py @@ -30,6 +30,8 @@ Setup, Security, OperatingData, + PredictiveCalendar, + PredictiveSchedule, Runtime, State, Users, @@ -79,6 +81,8 @@ def __init__( self.network = Network() self.next_mow = None self.operating_data = OperatingData() + self.predictive_calendar = PredictiveCalendar() + self.predictive_schedule = PredictiveSchedule() self.security = Security() self.state = State() self.setup = Setup() @@ -226,6 +230,24 @@ def _update_operating_data(self, new): else: self._online = False + @abstractmethod + def update_predictive_calendar(self): + """Update predictive_calendar.""" + + def _update_predictive_calendar(self, new): + """Update predictive_calendar.""" + if new: + self.predictive_calendar = replace(self.predictive_calendar, **new["cals"][0]) + + @abstractmethod + def update_predictive_schedule(self): + """Update predictive schedule.""" + + def _update_predictive_schedule(self, new): + """Update predictive schedule.""" + if new: + self.predictive_schedule = replace(self.predictive_schedule, **new) + @abstractmethod def update_security(self): """Update security.""" diff --git a/pyIndego/indego_client.py b/pyIndego/indego_client.py index fa2b5fe..90702b9 100644 --- a/pyIndego/indego_client.py +++ b/pyIndego/indego_client.py @@ -197,6 +197,14 @@ def update_operating_data(self): """Update operating data.""" self._update_operating_data(self.get(f"alms/{self._serial}/operatingData")) + def update_predictive_calendar(self): + """Update predictive_calendar.""" + self._update_predictive_calendar(self.get(f"alms/{self._serial}/predictive/calendar")) + + def update_predictive_schedule(self): + """Update predictive_schedule.""" + self._update_predictive_schedule(self.get(f"alms/{self._serial}/predictive/schedule")) + def update_security(self): """Update security.""" self._update_security(self.get(f"alms/{self._serial}/security")) diff --git a/pyIndego/states.py b/pyIndego/states.py index f154810..6d31bff 100644 --- a/pyIndego/states.py +++ b/pyIndego/states.py @@ -2,7 +2,7 @@ import logging from typing import List from dataclasses import dataclass, field, is_dataclass -from datetime import datetime +from datetime import datetime, time from .const import ( ALERT_ERROR_CODE, @@ -90,8 +90,18 @@ class CalendarSlot: En: bool = None StHr: int = None StMin: int = None + start: time = None EnHr: int = None EnMin: int = None + end: time = None + Attr: str = None + + def __post_init__(self): + """Convert start and end in time format.""" + if (self.StHr is not None and self.StMin is not None): + self.start = time(self.StHr, self.StMin) + if (self.EnHr is not None and self.EnMin is not None): + self.end = time(self.EnHr, self.EnMin) @nested_dataclass @@ -115,6 +125,20 @@ class Calendar: cal: int = None days: List[CalendarDay] = field(default_factory=lambda: [CalendarDay]) +@nested_dataclass +class PredictiveCalendar: + """Class for PredictiveCalendar.""" + + cal: int = None + days: List[CalendarDay] = field(default_factory=lambda: [CalendarDay]) + +@nested_dataclass +class PredictiveSchedule: + """Class for PredictiveSchedule.""" + + schedule_days: List[CalendarDay] = field(default_factory=lambda: [CalendarDay]) + exclusion_days: List[CalendarDay] = field(default_factory=lambda: [CalendarDay]) + @nested_dataclass class GenericData: