Skip to content

Commit

Permalink
Merge pull request #215 from PiotrMachowski/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
PiotrMachowski authored Jan 3, 2022
2 parents 65e0a90 + 162ef22 commit f95db4b
Show file tree
Hide file tree
Showing 15 changed files with 326 additions and 37 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/hacs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Validate HACS
on:
push:
pull_request:
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
name: Download repo
with:
fetch-depth: 0

- uses: actions/setup-python@v2
name: Setup Python
with:
python-version: '3.8.x'

- uses: actions/cache@v2
name: Cache
with:
path: |
~/.cache/pip
key: custom-component-ci

- name: HACS Action
uses: hacs/action@main
with:
CATEGORY: integration
24 changes: 24 additions & 0 deletions .github/workflows/lint_python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: lint_python
on: [pull_request, push]
jobs:
lint_python:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- run: pip install --upgrade pip wheel
- run: pip install bandit black codespell flake8 flake8-2020 flake8-bugbear
flake8-comprehensions isort mypy pytest pyupgrade safety
- run: bandit --recursive --skip B105,B108,B303,B304,B311,B413 .
- run: black --check . || true
- run: codespell --ignore-words-list="hass"
- run: flake8 . --count --ignore=B001,E241,E265,E302,E722,E731,F403,F405,F841,W504
--max-complexity=21 --max-line-length=184 --show-source --statistics
- run: isort --check-only --profile black . || true
- run: pip install -r requirements.txt || pip install --editable . || true
- run: mkdir --parents --verbose .mypy_cache
- run: mypy --ignore-missing-imports --install-types --non-interactive . || true
- run: pytest . || true
- run: pytest --doctest-modules . || true
- run: shopt -s globstar && pyupgrade --py36-plus **/*.py || true
- run: safety check
27 changes: 27 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Release

on:
release:
types: [published]

jobs:
release:
name: Prepare release
runs-on: ubuntu-latest
steps:
- name: Download repo
uses: actions/checkout@v1

- name: Zip xiaomi_cloud_map_extractor dir
run: |
cd /home/runner/work/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor/custom_components/xiaomi_cloud_map_extractor
zip xiaomi_cloud_map_extractor.zip -r ./
- name: Upload zip to release
uses: svenstaro/upload-release-action@v1-release
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: /home/runner/work/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor/custom_components/xiaomi_cloud_map_extractor/xiaomi_cloud_map_extractor.zip
asset_name: xiaomi_cloud_map_extractor.zip
tag: ${{ github.ref }}
overwrite: true
152 changes: 152 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
53 changes: 37 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
[![hacs_badge](https://img.shields.io/badge/HACS-Default-orange.svg)](https://hacs.xyz/)
[![Community Forum](https://img.shields.io/badge/Community-Forum-41BDF5.svg?style=popout)](https://community.home-assistant.io/t/xiaomi-cloud-vacuum-map-extractor/231292)
[![buymeacoffee_badge](https://img.shields.io/badge/Donate-Buy%20Me%20a%20Coffee-ff813f?style=flat)](https://www.buymeacoffee.com/PiotrMachowski)
[![paypalme_badge](https://img.shields.io/badge/Donate-PayPal-0070ba?style=flat)](https://paypal.me/PiMachowski)
![GitHub All Releases](https://img.shields.io/github/downloads/Piotrmachowski/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor/total)
[![HACS Default][hacs_shield]][hacs]
[![GitHub Latest Release][releases_shield]][latest_release]
[![GitHub All Releases][downloads_total_shield]][releases]
[![Community Forum][community_forum_shield]][community_forum]
[![Buy me a coffee][buy_me_a_coffee_shield]][buy_me_a_coffee]
[![PayPal.Me][paypal_me_shield]][paypal_me]


[hacs_shield]: https://img.shields.io/static/v1.svg?label=HACS&message=Default&style=popout&color=green&labelColor=41bdf5&logo=HomeAssistantCommunityStore&logoColor=white
[hacs]: https://hacs.xyz/docs/default_repositories

[latest_release]: https://github.com/PiotrMachowski/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor/releases/latest
[releases_shield]: https://img.shields.io/github/release/PiotrMachowski/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor.svg?style=popout

[releases]: https://github.com/PiotrMachowski/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor/releases
[downloads_total_shield]: https://img.shields.io/github/downloads/PiotrMachowski/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor/total

[community_forum_shield]: https://img.shields.io/static/v1.svg?label=%20&message=Forum&style=popout&color=41bdf5&logo=HomeAssistant&logoColor=white
[community_forum]: https://community.home-assistant.io/t/xiaomi-cloud-vacuum-map-extractor/231292

[buy_me_a_coffee_shield]: https://img.shields.io/static/v1.svg?label=%20&message=Buy%20me%20a%20coffee&color=6f4e37&logo=buy%20me%20a%20coffee&logoColor=white
[buy_me_a_coffee]: https://www.buymeacoffee.com/PiotrMachowski

[paypal_me_shield]: https://img.shields.io/static/v1.svg?label=%20&message=PayPal.Me&logo=paypal
[paypal_me]: https://paypal.me/PiMachowski


# Xiaomi Cloud Map Extractor

Expand Down Expand Up @@ -67,7 +88,7 @@ camera:
password: !secret xiaomi_cloud_password
draw: ['all']
attributes:
- calibration_points
- calibration_points
```
Expand Down Expand Up @@ -229,18 +250,18 @@ camera:
| `attributes` | list | false | | List of desired entity attributes ([see below](#attributes-configuration)) |
| `scan_interval` | interval | false | default: `5` seconds | Interval between map updates ([documentation](https://www.home-assistant.io/docs/configuration/platform_options/#scan-interval)) |
| `auto_update` | boolean | false | default: `true` | Activation/deactivation of automatic map updates. ([see below](#updates)) |
| `store_map_raw` | boolean | false | default: `false` | Enables storing raw map data in `store_map_path` directory ([more info](#retrieving-map)). Xiaomi map can be opened with [RoboMapViewer](https://github.com/marcelrv/XiaomiRobotVacuumProtocol/tree/master/RRMapFile). |
| `store_map_image` | boolean | false | default: `false` | Enables storing map image in `store_map_path` path with name `map_image_<device_model>.png` |
| `store_map_path` | string | false | default: `/tmp` | Storing map data directory |
| `force_api` | string | false | One of: `xiaomi`, `viomi`, `roidmi` | Forces usage of specific API. |
| `store_map_raw` | boolean | false | default: `false` | Enables storing raw map data in `store_map_path` directory ([more info](#retrieving-map)). Xiaomi map can be opened with [RoboMapViewer](https://github.com/marcelrv/XiaomiRobotVacuumProtocol/tree/master/RRMapFile). |
| `store_map_image` | boolean | false | default: `false` | Enables storing map image in `store_map_path` path with name `map_image_<device_model>.png` |
| `store_map_path` | string | false | default: `/tmp` | Storing map data directory |
| `force_api` | string | false | One of: `xiaomi`, `viomi`, `roidmi` | Forces usage of specific API. |

#### Colors configuration

Each color is represented by a list of 3 or 4 parameters: `[red, green, blue]` or `[red, green, blue, alpha]`.
Each parameter is a number from a range 0-255 and can be also provided as a HEX value: [0x12, 0xAF, 0xC5] matches #12AFC5.
Each parameter is a number from a range 0-255 and can be also provided as a HEX value: [0x12, 0xAF, 0xC5] matches #12AFC5.

<img src="https://raw.githubusercontent.com/PiotrMachowski/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor/master/images/map_no_rooms_custom_colors.png" width=50%>

| Color name | Description |
| --- | --- |
| `color_charger` | Charger position |
Expand Down Expand Up @@ -274,7 +295,7 @@ camera:

This section contains mapping between room numbers and colors.
Each color is represented by a list of 3 or 4 parameters: `[red, green, blue]` or `[red, green, blue, alpha]`.
Each parameter is a number from a range 0-255 and can be also provided as a HEX value: [0x12, 0xAF, 0xC5] matches #12AFC5.
Each parameter is a number from a range 0-255 and can be also provided as a HEX value: [0x12, 0xAF, 0xC5] matches #12AFC5.

#### Draw configuration

Expand Down Expand Up @@ -401,7 +422,7 @@ This integration was tested on following vacuums:
- Roidmi map format:
- `roidmi.vacuum.v60` (Roidmi EVE Plus)
- `viomi.vacuum.v18` (Viomi S9)

## Unsupported devices

At this moment this integration is known to not work with following vacuums:
Expand All @@ -412,7 +433,7 @@ At this moment this integration is known to not work with following vacuums:
When `store_map_raw: true` is added to your config this integration will store a raw map file in `/tmp` directory.
If you don't use Core installation ([installation types](https://www.home-assistant.io/installation/#compare-installation-methods)) you can retrieve this file in the following way:
- In [SSH & Terminal add-on](https://github.com/hassio-addons/addon-ssh) enable protected access
- Open terminal and use the following command to copy file:
- Open terminal and use the following command to copy file:
```
docker exec homeassistant bash -c "mkdir -p /config/tmp/ && cp /tmp/map_* /config/tmp/"
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ condition:
value_template: '{{ trigger.to_state.state != trigger.from_state.state }}'

action:
- condition: trigger
id: 0
- service: |
{% if trigger.to_state.state in ["unavailable", "unknown", "docked"] %}
camera.turn_off
Expand Down
4 changes: 2 additions & 2 deletions custom_components/xiaomi_cloud_map_extractor/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def __init__(self, entity_id, host, token, username, password, country, name, sh
super().__init__()
self.entity_id = entity_id
self.content_type = CONTENT_TYPE
self._vacuum = miio.Vacuum(host, token)
self._vacuum = miio.RoborockVacuum(host, token)
self._connector = XiaomiCloudConnector(username, password)
self._status = CameraStatus.INITIALIZING
self._device = None
Expand Down Expand Up @@ -195,7 +195,7 @@ def supported_features(self):
return SUPPORT_ON_OFF

@property
def device_state_attributes(self):
def extra_state_attributes(self):
attributes = {}
if self._map_data is not None:
rooms = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def __str__(self):
return f"({self.x}, {self.y}, a = {self.a})"

def __eq__(self, other):
return self.x == other.x and self.y == other.y and self.a == other.a
return other is not None and self.x == other.x and self.y == other.y and self.a == other.a

def as_dict(self):
if self.a is None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def get_map_url(self, map_name):
params = {
"data": f'{{"obj_name":"{self._user_id}/{self._device_id}/{map_name}"}}'
}
api_response = self._connector.execute_api_call(url, params)
api_response = self._connector.execute_api_call_encrypted(url, params)
if api_response is None or "result" not in api_response or "url" not in api_response["result"]:
return None
return api_response["result"]["url"]
Expand Down
Loading

0 comments on commit f95db4b

Please sign in to comment.