Package: pyIndego
API for Bosch Indego lawnmowersJoin the Discord channel to discuss around this integration:https://discord.gg/aD33GsPSource codeFor source files and version handling:https://github.com/jm-73/pyIndegoPyPi packageFor PYPI package:https://pypi.org/project/pyIndegoHome AssistantFor use in Home Assistant:https://github.com/jm-73/IndegoBasic information neededThe library requires python 3.7 or above.Required informationDescriptionyour_mail@gmail.comYour username in the BoschSmartGardening appyour_passwordYour password for the appThis library is written for the login method with username (email address) and password. Login with Facebook account is not supported.Call the API and the mowerCall the API, synchronously:from pyIndego import IndegoClient
indego = IndegoClient(username='your_mail@gmail.com', password='your_password')Call the API, asynchronously:from pyIndego import IndegoAsyncClient
indego = IndegoAsyncClient(username='your_mail@gmail.com', password='your_password')

await indego.close()Propertiesindego.serialReturns the serial number of the indego mower, is usefull mostly when serial was not initialized.indego.state_descriptionReturns a description of the state, instead of a number.indego.state_description_detailReturns a detailed description of the state, instead of a number.indego.next_mowsUpdate/download functionsDescription for the functions updating data from API and mower. The functions collecting data from only Bosch API does not wake up mower. Functions collecting data from both Bosch API and mower does wake up mower from sleeping.CallBosch APIMowerMower needs to be onlineindego.update_alerts()Xindego.update_calendar()Xindego.update_config()XXindego.update_generic_data()Xindego.update_last_completed_mow()Xindego.update_location()Xindego.update_network()???indego.update_next_mow()indego.update_operating_data()XXindego.update_predictive_calendar()Xindego.update_predictive_schedule()Xindego.update_security()Xindego.update_setup()Xindego.update_state()Xindego.update_state(force=True)Xindego.update_state(longpoll=True, longpoll_timeout=120)Xindego.update_updates_available()XX?indego.update_users()Xindego.download_map(filename='')??To be implementedPredictive SetupList of update functionsindego.update_all()Updates all sensors.indego.update_alerts()Updates alerts to indego.alerts.[Alert(alert_id='5d48171263c5345a75dbc017',error_code='ntfy_blade_life',headline='UnderhÃ¥llstips.',date='2019-08-05T11:46:26.397Z',message='Kontrollera klippknivarna. Indego har klippt i 100 timmar. Ska den fungera optimalt, kontrollera klippknivarna sÃ¥ att de Ã¤r i bra skick. Du kan bestÃ¤lla nya knivar via avsnittet TillbehÃ¶r.',read_status='unread',flag='warning',push=True,alert_description='Reminder blade life')]Contains: alerts for mower.indego.update_calendar()Updates the calendar to indego.calendar with the next planned mows.Calendar(cal=3,days=[CalendarDay(day=0,day_name='monday',slots=[CalendarSlot(En=True,StHr=10,StMin=0,EnHr=13,EnMin=0),CalendarSlot(En=False,StHr=None,StMin=None,EnHr=None,EnMin=None)]),CalendarDay(day=2,day_name='wednesday',slalendarSlot(En=False,StHr=None,StMin=None,EnHr=None,EnMin=None)])])indego.update_config()Updates indego.config with settings for region, border cut, pin lock, id for the wire, bump and alarm mode. This call doesnt work on some Indegos, this function gives an error on Indego 1000, while it works on newer models (e.g., Indego S+ 400).Config(region=0,language=1,border_cut=0,is_pin_set=True,wire_id=4,bump_sensitivity=0,alarm_mode=True)indego.update_generic_data()Updates indego.generic_data with serial, service counter, name, mowing mode, model number and firmware version, model description, voltage for battery, descripton  of mowing mode.GenericData(alm_name='Indego',alm_sn='505703041',service_counter=132436,needs_service=False,alm_mode='calendar',bareToolnumber='3600HA2300',alm_firmware_version='00837.01043',model_description='Indego 1000',model_voltage=ModelVoltage(min=297,max=369),mowing_mode_description='Calendar')indego.update_last_completed_mow()Updates indego.last_completed_mow with date and time of the latest completed mow.2020-06-2121:38:50.115000+02:00indego.update_location()Updates indego.location with the location of the garden/mower.Location(latitude='59.742950',longitude='17.380440',timezone='Europe/Berlin')indego.update_network()Updates indego.network with data on the mobile network the Indego is connected to.Network(mcc=262,mnc=2,rssi=-77,currMode='s',configMode='s',steeredRssi=-100,networkCount=3,networks=[26201,26202,26203])indego.update_next_mow()Updates the indego.next_mow with the next planned mow date and time.2020-06-2910:00:00+02:00orNoneindego.update_operating_data()Update the indego.operating_data with data about battery, runtime, garden data and temperature.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.update_predictive_calendar()Updates the indego.predictive_calendar with the timeslots (days and hours) where the user wants smart mowing not to mow the lawn.Calendar(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.update_predictive_schedule()Updates the indego.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').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.Security(enabled=True,autolock=False)indego.update_setup()Updates the indego.setup with information if the Indego is set up, has pincode and wome other unknown values.Setup(hasOwner=True,hasPin=True,hasMap=True,hasAutoCal=False,hasIntegrityCheckPassed=True)indego.update_state(force=False, longpoll=False, longpoll_timeout=120)Updates the indego.state with state of mower, % lawn mowed, position, runtime, map updates, map coordinates (cached).State(state=64513,map_update_available=True,mowed=78,mowmode=0,xPos=162,yPos=65,charge=None,operate=None,runtime=Runtime(total=RuntimeDetail(operate=1715,charge=387,cut=1328),session=RuntimeDetail(operate=5,charge=0,cut=0)),mapsvgcache_ts=1593207884109,svg_xPos=192,svg_yPos=544,config_change=None,mow_trig=None)indego.update_state(force=True, longpoll=False, longpoll_timeout=120)Updates the indego.state with state of mower, % lawn mowed, position, runtime, map updates and real time map coordinates.State(state=64513,map_update_available=True,mowed=78,mowmode=0,xPos=162,yPos=65,charge=None,operate=None,runtime=Runtime(total=RuntimeDetail(operate=1715,charge=387,cut=1328),session=RuntimeDetail(operate=5,charge=0,cut=0)),mapsvgcache_ts=1593207884109,svg_xPos=192,svg_yPos=544,config_change=None,mow_trig=None)indego.update_state(force=False, longpoll=True, longpoll_timeout=120)Updates the indego.state with state of mower, % lawn mowed, position, runtime, map coordinates.When longpoll is set to True, the indego.state must contain a value. It should contain the current state of the mower (you must run a "regular" update.state first). You send the current value to the API, and the API answers back when the state chenges.This function can be used instead of polling the status every couple of seconds: place one longpoll status request with a timeout of max. 300 seconds and the function will provide its return value when the status has been updated. As soon as an answer is received, the next longpoll status request can be placed. This should save traffic on both ends.State(state=64513,map_update_available=True,mowed=78,mowmode=0,xPos=162,yPos=65,charge=None,operate=None,runtime=Runtime(total=RuntimeDetail(operate=1715,charge=387,cut=1328),session=RuntimeDetail(operate=5,charge=0,cut=0)),mapsvgcache_ts=1593207884109,svg_xPos=192,svg_yPos=544,config_change=None,mow_trig=None)State(state=257, map_update_available=True, mowed=79, mowmode=0, error=None, xPos=167, yPos=77, charge=None, operate=None, runtime=Runtime(total=RuntimeDetail(operate=1973, charge=433, cut=1540), session=RuntimeDetail(operate=121, charge=0, cut=0)), mapsvgcache_ts=1597492701099, svg_xPos=152, svg_yPos=640, config_change=None, mow_trig=None)indego.update_updates_available()Updatesindego.update_availablewith status if there are any updates applicable to the mower.Falseindego.update_users()Updates theindego.userwith information about the user.Users(email='youremail@mail.com',display_name='Indego',language='sv',country='SE',optIn=True,optInApp=True)Functions for the cached dataTBD!Sending commandsindego.delete_alert(alert_index)Delete an alert from the list, index should exist. If this is called before update_alerts it will not work.indego.put_alert_read(alert_index)Set the specified alert to read. This is a one way action, once read it is not possible to set back to unread. The function looks up the alert_id from indego.alerts, if it cannot find that ID or if update_alerts has not been run, this will stop and log a warning.indego.put_all_alerts_read()Set all alerts to read, the function loops through the alert_id's from indego.alerts, if update_alerts has not been run, this will stop and log a warning.indego.put_command(command)Send commands.CommandDescriptionput_command('mow')Start mowingput_command('pause')Pause mowerput_command('returnToDock')Return mower to dockindego.put_mow_mode(command)Send command. Accepted commands:CommandDescriptionput_mow_mode('true')Smart Mow enabledput_mow_mode('false')Smart Mow disabledNot implemented yetupdate_ & put_predictive_setup()Response:{'garden_size':93,'mowing_duration':3,'rain_factor':1.4,'temperature_factor':1.1,'garden_location':{'latitude':'48.7357','longitude':'8.9505','timezone':'Europe/Berlin'},'full_cuts':3,'avoid_rain':True,'avoid_temperature':True,'use_grass_growth':True,'no_mow_calendar_days':[{'day':0,'slots':[{'En':True,'StHr':0,'StMin':0,'EnHr':8,'EnMin':0},{'En':True,'StHr':20,'StMin':0,'EnHr':23,'EnMin':59}]},...{'day':6,'slots':[{'En':True,'StHr':0,'StMin':0,'EnHr':23,'EnMin':59}]}]}Attributes for reading data from locally cached API dataAll functions that doesnt contain "update" first in name is collecting data from locally stored variables in the function. No API calls to Bosch or mower.attributesDescriptionalerts_countShow counts of the current alerts.alertsShow detailed list of alerts.calendarGet the calendar of planned mows.AlmFirmwareVersionShow firmware version.AlmModeShow mow mode.AlmNameShow name.BareToolNumberShow the model number.BatteryShow battery information.BatteryAmbientTempShow the ambient temp of the battery.BatteryCyclesDont know what this value is?BatteryDischargeShow the current drawn in Ah.BatteryPercentShow the raw value for percentage left. For Gen 1 this seems to be the battery voltage. For Gen 2 it seems to be the actual percentage left in the battery.BatteryPercentAdjustedShow the adjusted value for percentage left. Calculated for Gen 1, and the actual percentage value for Gen 2.BatteryTempShow temp of the battery.BatteryVoltageShow voltage for the battery. For Gen 1 mowers this value seems to be correct. For Gen 2 it seems to be the same value as the percentage left in battery.ConvertBoschDateTimeConvert Bosch abbreviation for time to std 24h timeCountryShow country for the account.DisplaynameShow name for the account.EmailShow email adress for the account.FirmwareAvailableShow if there are any firmware updates available.FriendlyAlertErrorCodeShow user friendly alert error code description to be shown in HA GUI.GardenDont know what this is?HmiKeysnDont know what this is?LanguageShow language for the account.MapSvgCacheTsDont know what this is...MapUpdateAvailableShow if there is an update of the map image.ModelDescriptionShow user friendly model name.ModelVoltageShow the predefined voltage limits in order to calculate battery percentage.ModelVoltageMaxShow the maximum predefined voltage limits in order to calculate battery percentage.ModelVoltageMinShow the minimum predefined voltage limits in order to calculate battery percentage.MowModeShow mow modeMowedShow percentage of lawn mowedMowerStateShow current stateMowerStateDescriptionShow simple description of current state. States available are Docked, Mowing, Stuck, Diagnostics mode, End of life, Software update.MowerStateDescriptionDetailedShow description in detail of current state.MowingModeDescriptionShow the user friendly mow mode description.NeedsServiceShow needs service flag. Dont know when it is used.NextMowShow next planned mow session.OptInDont know what this are for?OptInAppDont know what this are for?RuntimeShow session and total rutime and charge time in minutes.RuntimeSessionshow session runtime and charge time in minutesRuntimeTotalShow total runtime and charge time in hoursSerialShow serial numberServiceCounterShow service counter for knivesSvgxPosShow svg x-position of mower.SvgyPosShow svg y-position of mower.XPosShow x-position of mower.YPosShow y-position of mower.Not workingNot properly implemented yetupdate_predicitive_calendar()Get the calender for predicted mow sessionsupdate_user_adjustment()Get the user adjustment of the mowing frequencyupdate_automatic_update()Get the automatic update settingsAPI CALLShttps://api.indego-cloud.iot.bosch-si.com/api/v1/get/alerts/alms/alms/<serial>/alms/<serial>/automaticUpdate/alms/<serial>/calendar/alms/<serial>/config/alms/<serial>/map/alms/<serial>/network/alms/<serial>/updates/alms/<serial>/operatingData/alms/<serial>/predictive/alms/<serial>/predictive/calendar/alms/<serial>/predictive/lastcutting/alms/<serial>/predictive/location/alms/<serial>/predictive/nextcutting/alms/<serial>/predictive/schedule/alms/<serial>/predictive/useradjustment/alms/<serial>/predictive/weather/alms/<serial>/security/alms/<serial>/setup/alms/<serial>/state/users/<userid>put/alms/<serial>/automaticUpdate/alms/<serial>/predictive/calendar/alms/<serial>/predictive/location/alms/<serial>/predictive/alms/<serial>/state/alms/<serial>/predictive/useradjustmentdelete/alerts/<alertid>