Skip to content

Commit

Permalink
Heating scheduler (#37)
Browse files Browse the repository at this point in the history
* Made example.py run without errors

- added the iolite directory as an editable dev-dependency, so iolite can be imported without being installed (and without a need to manipulate the path)
- changed the environment-accesses to use environs instead of os.getenv

* Added black & isort

- added black and isort as dev-dependencies to use them in file watchers
- as all black releases are pre-releases, a specific
  version number is required to avoid an error when locking
  (I chose the latest version)

* Added black & isort

- added black and isort as dev-dependencies to use them in file watchers
- chose isort 4.3.21 to match the pre-commit setup
- chose black 20.8.b to match the pre-commit setup
- also all black releases are pre-releases, a specific
version number is required to avoid an error when locking
- added a pyproject.toml to configure isort

* Minor refactoring to client

- moved place and device response handling into separate methods

* Fix isort in pre-commit

- added toml as a pre-commit dependency
- added toml to pipenv

* Added a Heating Scheduler

- added a Heating Scheduler object for interaction with the heating intervals endpoint
- added helpers to get rooms and entities to the Discovered class, to use these rooms with the Heating Scheduler
- added a jupyter notebook to showcase the Heating Scheduler
- added tests and extended client tests, for safer refactoring
- updated the readme to introduce the Heating Scheduler

* Updated lockfile

- updated lock file after merge

* Removed isort duplicate from pipfile

- updated lock file afterwards

* Fixed Code Quality issues

- added missing spaces to bulletpoints in README.md
- suppressed security warning in test_heating_scheduler.py, as the password is hard-coded deliberately and only used to verify that the client encodes a given password correctly

* Minor refactorings after Code Review

- renamed discovered into discovered_rooms, as only rooms will be stored
- refactored Interval min/max temperatures into constatnts
- detailed the instructions on how to install jupyter notebook and how to fix a ModuleNotFoundError that may occur when using jupyter from within the venv

* Removed fixed python version from pipfile, as it is not available on CI.

Co-authored-by: Malachi Soord <inverse.chi@gmail.com>
  • Loading branch information
firstdayofjune and inverse committed Mar 24, 2021
1 parent 9da4d45 commit e9bee7b
Show file tree
Hide file tree
Showing 13 changed files with 600 additions and 82 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ __pycache__
# Coverage
/coverage.xml
/.coverage

# Jupyter
.ipynb_checkpoints
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ repos:
rev: v4.3.21
hooks:
- id: isort
additional_dependencies: [toml]
- repo: https://github.com/gvanderest/pylama-pre-commit
rev: 0.1.2
hooks:
Expand Down
9 changes: 8 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@ pylama = "*"
pre-commit = "*"
coverage = "*"
pytest-cov = "*"
pipenv-setup = "*"
iolite = {editable = true,path = "."}
black = "==19.10b0"
toml = "*"
responses = "*"
isort = "==4.3.21"
pipenv-setup = "*"
pytest-socket = "*"
freezegun = "*"

[packages]
websockets = "*"
environs = "*"
requests = "*"

[pipenv]
allow_prereleases = true
69 changes: 66 additions & 3 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 42 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,47 @@
![CI](https://github.com/inverse/python-iolite-client/workflows/CI/badge.svg)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/a38c5dbfc12247c893b4f39db4fac2b2)](https://www.codacy.com/manual/inverse/python-iolite-client?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=inverse/python-iolite-client&amp;utm_campaign=Badge_Grade)
[![Codacy Badge](https://app.codacy.com/project/badge/Coverage/a38c5dbfc12247c893b4f39db4fac2b2)](https://www.codacy.com/manual/inverse/python-iolite-client?utm_source=github.com&utm_medium=referral&utm_content=inverse/python-iolite-client&utm_campaign=Badge_Coverage)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

WIP Python client for [IOLite's][0] remote API.

Build by reverse engineering the [Deutsche Wohnen][2] [MIA Android App][1]. I wrote a [short post][3] on how I achieved that.
Build by reverse engineering the [Deutsche Wohnen][2] [MIA Android App][1]. I wrote a [short post][3] on how I achieved
that.

The client is very incomplete and non-functional but the authentication layer and basic command models are in place.
The client is still incomplete, but the authentication layer, some basic command models and a client to change the
heating intervals are available.

## Requirements

- Python 3.6+
- Pipenv
- [Pipenv][4]

## Getting credentials

Open your Deutsche Wohnen tablet and begin pairing device process. Scan QR code and you'll get the following payload.
Open your Deutsche Wohnen tablet and begin pairing device process. Scan the QR code with your QR-Scanner and instead of
opening the QR code in your browser, copy it's content. You'll get the following payload:

```json
{"webApp":"/ui/","code":"<redacted>","basicAuth":"<redacted>"}
{
"webApp": "/ui/",
"code": "<redacted>",
"basicAuth": "<redacted>"
}
```

- `basicAuth` contains base64 encoded HTTP basic username and password. Decode this to get the `:` separated `user:pass`.
- `code` is the pairing code

You can decode the base64 encoded basicAuth information using the `scripts/get_credentials.py` script (see [development](#development) section).

## Development

- Init your pipenv environment (`pipenv install`)
- Init your pipenv environment (`pipenv install --dev`)
- Copy `.env.example` to `.env`
- Decode credentials (`pipenv run python scripts/get_credentials.py <basic-auth-value>`)
- Add your credentials to `.env` following the above process

The [pre-commit][4] framework is used enforce some linting and style compliance on CI.
The [pre-commit][5] framework is used enforce some linting and style compliance on CI.

To get the same behaviour locally you can run `pre-commit install` within your activated venv.

Expand All @@ -45,12 +55,36 @@ Run `pipenv run python scripts/example.py` and copy the URL to your browser of c

You will need the HTTP basic credentials you defined earlier within the `.env` file.

## Usage example

A jupyter notebook showcasing the heating interval scheduler can be found in `notebooks/Heating Scheduler.ipynb`. To
access the notebook install [jupyter notebook or jupyter lab](https://jupyter.org/install.html) into the virtual environment and run the notebook:

```sh
pipenv shell
pip install notebook
jupyter notebook
```

If running the notebook gives you a `ModuleNotFoundError`, you may fix this issue by changing the notebook's kernel (following [this StackOverflow post](https://stackoverflow.com/a/47296960/50913)):
```sh
pipenv shell
python -m ipykernel install --user --name=`basename $VIRTUAL_ENV`
```
And then switch the kernel in the notebook's top menu under: _Kernel > Change Kernel_.

## Licence

MIT

[0]: https://iolite.de/

[1]: https://play.google.com/store/apps/details?id=de.iolite.client.android.mia

[2]: https://deutsche-wohnen.com/

[3]: https://www.malachisoord.com/2020/08/06/reverse-engineering-iolite-remote-api/
[4]: https://pre-commit.com/

[4]: https://pipenv.pypa.io/en/latest/#install-pipenv-today

[5]: https://pre-commit.com/

0 comments on commit e9bee7b

Please sign in to comment.