This unofficial Python API was created to provide an interface to interact with the STIHL iMow mower WebAPI. This wrapper is able to receive the current state
from the mowers and to send actions.
I wrote this library to implement an integration for the Home Assistant Smart Home System, which you can find here.
STIHL uses different webapps for their iMOW generations. Currently only the iMOW RMI series are supported by this library, because i'm not able to reverse engineer the newer generation. This is simply because I do not own them.
If you use this webapp, https://app.imow.sithl.com, this library should work for your mower.
Also see here: Issue #13
These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.
API Documentation is available on: https://chrishapunkt.github.io/stihl-imow-webapi/imow
Python 3.8+ is required to run this application, other than that there are no prerequisites for the project, as the dependencies are included in the repository.
To install the library is as simple as cloning the repository and running
pip install -e .
It is recommended to create an virtual environment prior to installing this library. Alternatively, you can also install this library via Pip:
pip install imow-webapi
And have fun!
Import the module and instantiate the IMowApi()
constructor with credentials. Afterwards, initiate the get_token()
method.
Or place credentials in the get_token()
method.
from imow.api import IMowApi
from imow.common.actions import IMowActions
import asyncio
import aiohttp
async def main():
async with aiohttp.ClientSession() as session:
api = IMowApi(aiohttp_session=session, lang="de")
# save token for later use if you want to recreate IMowApi(token=my_token) because the created token is valid for
# 30 days
token, expire_time = await api.get_token("email@account.stihl", "supersecret", return_expire_time=True)
print(await api.get_token())
mowers = await api.receive_mowers()
mower = mowers[0]
print(f"{mower.name} @ {mower.coordinateLatitude},{mower.coordinateLongitude}")
print(f"Currently: {mower.stateMessage['short']}")
await mower.update_setting("gpsProtectionEnabled", True)
print(mower.stateMessage)
print(mower.machineState)
await mower.intent(IMowActions.TO_DOCKING)
print(await mower.update_from_upstream())
print(await mower.get_startpoints())
if __name__ == "__main__":
asyncio.run(main())
Selection of outputs from above statements:
> Mährlin @ 54.123456,10.12345
> Currently: Hood blocked
> {'short': 'Hood blocked', 'long': 'The hood is blocked. Please check the hood and press the OK button on your machine (M1120).', 'legacyMessage': 'Abschaltung Automatikmode durch Bumper', 'errorId': '', 'error': False}
> HOOD_BLOCKED
> <imow.common.mowerstate.MowerState object at 0x000001B034C245F8>
Save the following as myscript.sh
and execute chmod +x myscript.sh
. Make sure you install the api via pip3 install imow-webapi
Afterwards you can execute via ./myscript.sh
#!/usr/bin/env python3
from imow.api import IMowApi
from imow.common.actions import IMowActions
import asyncio
import aiohttp
import logging
logger = logging.getLogger("imow")
# Enable DEBUG output
logging.basicConfig(level=logging.DEBUG)
async def main():
async with aiohttp.ClientSession() as session:
api = IMowApi(aiohttp_session=session, lang="de")
# save token for later use if you want to recreate IMowApi(token=my_token) because the created token is valid for
# 30 days
token, expire_time = await api.get_token("email@account.stihl", "supersecret", return_expire_time=True)
print(await api.get_token())
mowers = await api.receive_mowers()
mower = mowers[0]
print(f"{mower.name} @ {mower.coordinateLatitude},{mower.coordinateLongitude}")
print(f"Currently: {mower.stateMessage['short']}")
startpoints = await mower.get_startpoints()
for i in range(len(startpoints)):
print("Startpoint {}: {}".format(i, startpoints[i]))
# if your mower supports the "startMowing" call, use this action (i.e iMow 600 series)
await mower.intent(IMowActions.START_MOWING, starttime="2023-08-12 20:50")
# await mower.intent(IMowActions.START_MOWING, endtime="2023-08-12 22:50")
# await mower.intent(IMowActions.START_MOWING, starttime="2023-08-12 20:50", endtime="2023-08-12 22:50")
# if your mower supports the "startMowingFromPoint" call, use this action (i.e iMow 400 series)
await mower.intent(IMowActions.START_MOWING_FROM_POINT, duration=50)
# await mower.intent(IMowActions.START_MOWING_FROM_POINT, startpoint=2)
# await mower.intent(IMowActions.START_MOWING_FROM_POINT, duration=50, startpoint=2)
if __name__ == "__main__":
asyncio.run(main())
For unit testing run pytest -s tests/test_unit*
. For upstream integration testing, provide a /secrets.py
with the following contents:
EMAIL = "email@account.stihl"
PASSWORD = "supersecret"
MOWER_NAME = "MyRobot"
and run pytest -s tests/test_integration*
or pytest -s
.
- aiohttp
- BeautifulSoup
- asyncio
Navigate to tags on this repository to see all available versions.
Mail Address | GitHub Profile |
---|---|
chris@homeset.de | ChrisHaPunkt |
This project is licensed under the MIT License - see the LICENSE.md license file for more details.
Thanks to
for repo structure inspiration