diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2e33867..abc15b8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -20,14 +20,16 @@ // ], "postCreateCommand": "/bin/chmod +x /workspaces/hacs-govee/.devcontainer/postCreateContainer.sh && /workspaces/hacs-govee/.devcontainer/postCreateContainer.sh", "extensions": [ - "ms-python.python", + "cschleiden.vscode-github-actions", "github.vscode-pull-request-github", - "ryanluker.vscode-coverage-gutters", - "ms-python.vscode-pylance", - "littlefoxteam.vscode-python-test-adapter", "hbenl.vscode-test-explorer", + "knisterpeter.vscode-github", + "littlefoxteam.vscode-python-test-adapter", + "mhutchie.git-graph", + "ms-python.python", + "ms-python.vscode-pylance", + "ryanluker.vscode-coverage-gutters", "tht13.python", - "mhutchie.git-graph" ], "settings": { "files.eol": "\n", diff --git a/.github/workflows/cron.yaml b/.github/workflows/cron.yaml deleted file mode 100644 index 97bc65f..0000000 --- a/.github/workflows/cron.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Cron actions - -on: - schedule: - - cron: '0 0 * * *' - -jobs: - validate: - runs-on: "ubuntu-latest" - name: Validate - steps: - - uses: "actions/checkout@v2" - - - name: HACS validation - uses: "hacs/integration/action@main" - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CATEGORY: "integration" - - - name: Hassfest validation - uses: "home-assistant/actions/hassfest@master" \ No newline at end of file diff --git a/.github/workflows/hacs-hass.yaml b/.github/workflows/hacs-hass.yaml new file mode 100644 index 0000000..d7d7381 --- /dev/null +++ b/.github/workflows/hacs-hass.yaml @@ -0,0 +1,24 @@ +name: HACS/HASS Actions + +on: + push: + pull_request: + schedule: + - cron: "0 0 * * *" + +jobs: + hacs: + name: HACS Action + runs-on: "ubuntu-latest" + steps: + - uses: "actions/checkout@v2" + - name: HACS Action + uses: "hacs/action@main" + with: + category: "integration" + + hassfest: + runs-on: "ubuntu-latest" + steps: + - uses: "actions/checkout@v2" + - uses: home-assistant/actions/hassfest@master \ No newline at end of file diff --git a/.github/workflows/pull.yml b/.github/workflows/pull.yml deleted file mode 100644 index bea9662..0000000 --- a/.github/workflows/pull.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Pull actions - -on: - pull_request: - -jobs: - validate: - runs-on: "ubuntu-latest" - name: Validate - steps: - - uses: "actions/checkout@v2" - - - name: HACS validation - uses: "hacs/integration/action@main" - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CATEGORY: "integration" - - - name: Hassfest validation - uses: "home-assistant/actions/hassfest@master" - - style: - runs-on: "ubuntu-latest" - name: Check style formatting - steps: - - uses: "actions/checkout@v2" - - uses: "actions/setup-python@v1" - with: - python-version: "3.x" - - run: python3 -m pip install black - - run: black . \ No newline at end of file diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml deleted file mode 100644 index 4123136..0000000 --- a/.github/workflows/push.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Push actions - -on: - push: - branches: - - master - - dev - -jobs: - validate: - runs-on: "ubuntu-latest" - name: Validate - steps: - - uses: "actions/checkout@v2" - - - name: HACS validation - uses: "hacs/integration/action@main" - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CATEGORY: "integration" - - - name: Hassfest validation - uses: "home-assistant/actions/hassfest@master" - - style: - runs-on: "ubuntu-latest" - name: Check style formatting - steps: - - uses: "actions/checkout@v2" - - uses: "actions/setup-python@v1" - with: - python-version: "3.x" - - run: python3 -m pip install black - - run: black . \ No newline at end of file diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml new file mode 100644 index 0000000..33e05b8 --- /dev/null +++ b/.github/workflows/style.yml @@ -0,0 +1,17 @@ +name: Style check + +on: + push: + pull_request: + +jobs: + style: + runs-on: "ubuntu-latest" + name: Check style formatting + steps: + - uses: "actions/checkout@v2" + - uses: "actions/setup-python@v1" + with: + python-version: "3.x" + - run: python3 -m pip install black + - run: black . \ No newline at end of file diff --git a/.github/workflows/tox.yaml b/.github/workflows/tox.yaml new file mode 100644 index 0000000..f77e6f8 --- /dev/null +++ b/.github/workflows/tox.yaml @@ -0,0 +1,25 @@ +name: Test wtih tox + +on: + - push + - pull_request + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + # NOTE: keep this in sync with envlist in tox.ini + python-version: [3.9] + steps: + - uses: actions/checkout@v1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install tox tox-gh-actions + - name: Test with tox + run: tox \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 07a5a94..61e0d25 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,8 +8,7 @@ "name": "Launch Home Assistant UI in Chrome", "request": "launch", "type": "pwa-chrome", - "url": "http://192.168.144.5:9123 - ", + "url": "http://192.168.144.5:9123", "webRoot": "${workspaceFolder}" }, { diff --git a/README.md b/README.md index 9a6bbc9..d95b5c4 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,14 @@ The Govee integration allows you to control and monitor lights using the Govee A To set up this integration, click Configuration in the sidebar and then click Integrations. Click the + icon to add "Govee" to the integrations. An API key is necessary, you need to obtain it in the 'Govee Home' app on your mobile, in the User menu - About us - Apply for API Key. The key will be sent to you by email. +## Sponsor + +A lot of effort is going into that integration. So if you can afford it and want to support us: + +Buy Me A Coffee + +Thank you! + ## Pulling or assuming state Some devices do not support pulling state. In this case we assume the state on your last input. diff --git a/custom_components/govee/__init__.py b/custom_components/govee/__init__.py index 56b3fa6..c66d0f0 100644 --- a/custom_components/govee/__init__.py +++ b/custom_components/govee/__init__.py @@ -82,7 +82,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): unload_ok = all( await asyncio.gather( *[ - hass.config_entries.async_forward_entry_unload(entry, component) + await _unload_component_entry(hass, entry, component) for component in PLATFORMS ] ) @@ -93,3 +93,22 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): await hub.close() return unload_ok + + +async def _unload_component_entry( + hass: HomeAssistant, entry: ConfigEntry, component: str +) -> bool: + """Unload an entry for a specific component.""" + success = False + try: + success = await hass.config_entries.async_forward_entry_unload(entry, component) + except ValueError: + # probably ValueError: Config entry was never loaded! + return success + except Exception as ex: + _LOGGER.warning( + "Continuing on exception when unloading %s component's entry: %s", + component, + ex, + ) + return success diff --git a/custom_components/govee/manifest.json b/custom_components/govee/manifest.json index 016c547..477d21d 100644 --- a/custom_components/govee/manifest.json +++ b/custom_components/govee/manifest.json @@ -2,11 +2,11 @@ "codeowners": ["@LaggAt"], "domain": "govee", "name": "Govee", - "version": "0.1.9", + "version": "0.1.10", "config_flow": true, "documentation": "https://github.com/LaggAt/hacs-govee/blob/master/README.md", "issue_tracker": "https://github.com/LaggAt/hacs-govee/issues", - "requirements": ["govee-api-laggat==0.1.40", "dacite==1.6.0"], + "requirements": ["govee-api-laggat==0.1.41", "dacite==1.6.0"], "ssdp": [], "zeroconf": [], "homekit": {}, diff --git a/hacs.json b/hacs.json index 6daee67..da7382c 100644 --- a/hacs.json +++ b/hacs.json @@ -1,9 +1,9 @@ { "name": "govee", - "hacs": "0.1.9", + "hacs": "0.1.10", "domains": [ "light" ], - "iot_class": "Cloud Polling", - "homeassistant": "0.118.4" + "iot_class": ["Assumed State", "Cloud Polling"], + "homeassistant": "2021.4.5" } \ No newline at end of file diff --git a/requirements_test.txt b/requirements_test.txt index 0e3ddd1..161d084 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -1,11 +1,12 @@ -tox -pytest-homeassistant-custom-component==0.0.21 -homeassistant==0.118.4 -govee_api_laggat -flake8 -pytest -pytest-cov -coveralls black==20.8b1 colorlog==4.6.2 +coveralls +dacite==1.6.0 +flake8 +govee_api_laggat +homeassistant pylint==2.6.0 +pytest +pytest-cov +pytest-homeassistant-custom-component==0.3.0 +tox \ No newline at end of file diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index 21593e5..84e05d4 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -2,12 +2,13 @@ from homeassistant import config_entries, setup from custom_components.govee.const import DOMAIN from homeassistant.const import CONF_API_KEY, CONF_DELAY +from homeassistant.core import HomeAssistant # from tests.async_mock import patch -from pytest_homeassistant_custom_component.async_mock import patch +from unittest.mock import patch -async def test_form(hass): +async def test_form(hass: HomeAssistant): """Test we get the form.""" await setup.async_setup_component(hass, "persistent_notification", {}) result = await hass.config_entries.flow.async_init( @@ -38,7 +39,7 @@ async def test_form(hass): assert len(mock_setup_entry.mock_calls) == 1 -async def test_form_cannot_connect(hass): +async def test_form_cannot_connect(hass: HomeAssistant): """Test we handle cannot connect error.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} @@ -54,10 +55,10 @@ async def test_form_cannot_connect(hass): ) assert result2["type"] == "form" - assert result2["errors"] == {"base": "cannot_connect"} + assert result2["errors"] == {"api_key": "cannot_connect"} -async def test_form_unknown_exception(hass): +async def test_form_unknown_exception(hass: HomeAssistant): """Test we handle cannot connect error.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} diff --git a/tox.ini b/tox.ini index 8ed171e..361eee8 100644 --- a/tox.ini +++ b/tox.ini @@ -1,16 +1,20 @@ [tox] -envlist = py{37,39} +envlist = py{39} skipsdist=True +[gh-actions] +python = + 3.9: py39 + [testenv] basepython = - py37: python3.7 py39: python3.9 deps = flake8 -r{toxinidir}/requirements_test.txt commands = flake8 . + pytest [flake8] max-line-length = 119