Giter VIP home page Giter VIP logo

python-bsblan's Introduction

Python: BSBLan API Client

GitHub Release Python Versions Project Stage Project Maintenance License

Build Status Code Coverage Quality Gate Status

Buy me a coffee

Asynchronous Python client for BSBLan.

About

This package allows you to control and monitor an BSBLan device programmatically. It is mainly created to allow third-party programs to automate the behavior of BSBLan.

Installation

pip install python-bsblan

Usage

# pylint: disable=W0621
"""Asynchronous Python client for BSBLan."""

import asyncio

from bsblan import BSBLan, Info, State


async def main(loop):
    """Show example on controlling your BSBLan device.

    Options:
    - passkey (http://url/"passkey"/) if your device is setup for passkey authentication
    - username and password if your device is setup for username/password authentication

    """
    async with BSBLan(
        host="10.0.1.60", passkey=None, username=None, password=None, loop=loop
    ) as bsblan:
        # get state from bsblan device
        state: State = await bsblan.state()
        print(state)

        # set temp thermostat
        await bsblan.thermostat(target_temperature=19.0)

        # set hvac_mode (0-3) (protection,auto,reduced,comfort)
        await bsblan.thermostat(hvac_mode=3)

        # get some generic info from the heater
        info: Info = await bsblan.info()
        print(info)

        # get device info
        device: Device = await bsblan.device()
        print(device)

        # get sensor from bsblan device
        sensor: Sensor = await bsblan.sensor()
        print(f"outside temperature: {sensor.outside_temperature.value}")


if __name__ == "__main__":
    loop = asyncio.get_event_loop_policy().get_event_loop()
    loop.run_until_complete(main())

Changelog & Releases

This repository keeps a change log using GitHub's releases functionality. The format of the log is based on Keep a Changelog.

Releases are based on Semantic Versioning, and use the format of MAJOR.MINOR.PATCH. In a nutshell, the version will be incremented based on the following:

  • MAJOR: Incompatible or major changes.
  • MINOR: Backwards-compatible new features and enhancements.
  • PATCH: Backwards-compatible bugfixes and package updates.

Contributing

This is an active open-source project. We are always open to people who want to use the code or contribute to it.

We've set up a separate document for our contribution guidelines.

Thank you for being involved! 😍

Setting up development environment

This Python project is fully managed using the Poetry dependency manager. But also relies on the use of NodeJS for certain checks during development.

You need at least:

  • Python 3.10+
  • Poetry
  • NodeJS 16+ (including NPM)

To install all packages, including all development requirements:

npm install
poetry install

As this repository uses the pre-commit framework, all changes are linted and tested with each commit. You can run all checks and tests manually, using the following command:

poetry run pre-commit run --all-files

To run just the Python tests:

poetry run pytest

Authors & contributors

The template is from the repository 'elgato' by Franck Nijhof. The setup of this repository is by Willem-Jan van Rootselaar.

For a full list of all authors and contributors, check the contributor's page.

License

MIT License

Copyright (c) 2024 WJ van Rootselaar

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

python-bsblan's People

Contributors

deepsource-autofix[bot] avatar dependabot-preview[bot] avatar dependabot[bot] avatar liudger avatar pyup-bot avatar renovate[bot] avatar thecode avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

Forkers

thecode retogaeh

python-bsblan's Issues

Sensors

average_outside_temperature
burning_hours
ch_return_temperature
ch_water_pressure
ch_water_temperature
flame?
outside_temperature
weather_status?

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • ⬆️ Update dependency bandit to v1.7.9
  • ⬆️ Update SonarSource/sonarcloud-github-action action to v2.3
  • ⬆️ Update dependency flake8 to v7.1.0
  • ⬆️ Update dependency prettier to v3.3.2
  • ⬆️ Update dependency pylint to v3.2.3
  • ⬆️ Update dependency pyupgrade to v3.16.0
  • ⬆️ Update dependency safety to v3.2.3
  • ⬆️ Update dependency pytest-cov to v5

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/codeql.yaml
  • actions/checkout v4@b4ffde65f46336ab88eb53be808477a3936bae11
  • github/codeql-action v3@1b1aada464948af03b950897e5eb522f92603cc2
  • github/codeql-action v3@1b1aada464948af03b950897e5eb522f92603cc2
.github/workflows/labels.yaml
  • actions/checkout v4@b4ffde65f46336ab88eb53be808477a3936bae11
  • micnncim/action-label-syncer v1.3.0@3abd5ab72fda571e69fffd97bd4e0033dd5f495c
.github/workflows/linting.yaml
  • actions/checkout v4@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/setup-python v5@82c7e631bb3cdc910f68e0081d67478d79c6982d
  • actions/checkout v4@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/setup-python v5@82c7e631bb3cdc910f68e0081d67478d79c6982d
  • actions/checkout v4@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/setup-python v5@82c7e631bb3cdc910f68e0081d67478d79c6982d
  • actions/checkout v4@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/setup-python v5@82c7e631bb3cdc910f68e0081d67478d79c6982d
  • actions/checkout v4@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/setup-python v5@82c7e631bb3cdc910f68e0081d67478d79c6982d
  • actions/checkout v4@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/setup-python v5@82c7e631bb3cdc910f68e0081d67478d79c6982d
  • actions/checkout v4@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/setup-python v5@82c7e631bb3cdc910f68e0081d67478d79c6982d
  • actions/setup-node v4@60edb5dd545a775178f52524783378180af0d1f8
.github/workflows/lock.yaml
  • dessant/lock-threads v5.0.1@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771
.github/workflows/pr-labels.yaml
  • jesusvasquez333/verify-pr-label-action v1.4.0@657d111bbbe13e22bbd55870f1813c699bde1401
.github/workflows/release-drafter.yaml
  • release-drafter/release-drafter v6.0.0@3f0f87098bd6b5c5b9a36d49c41d998ea58f9348
.github/workflows/release.yaml
  • actions/checkout v4@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/setup-python v5@82c7e631bb3cdc910f68e0081d67478d79c6982d
.github/workflows/stale.yaml
  • actions/stale v9@28ca1036281a5e5922ead5184a1bbf96e5fc984e
.github/workflows/tests.yaml
  • actions/checkout v4@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/setup-python v5@82c7e631bb3cdc910f68e0081d67478d79c6982d
  • actions/upload-artifact v3@a8a3f3ad30e3422c9c7b888a15615d19a852ae32
  • actions/checkout v4@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/download-artifact v3@9bc31d5ccc31df68ecc42ccf4149144866c47d8a
  • actions/setup-python v5@82c7e631bb3cdc910f68e0081d67478d79c6982d
  • codecov/codecov-action v4@84508663e988701840491b86de86b666e8a86bed
  • SonarSource/sonarcloud-github-action v2.2@4006f663ecaf1f8093e8e4abb9227f6041f52216
.github/workflows/typing.yaml
  • actions/checkout v4@b4ffde65f46336ab88eb53be808477a3936bae11
  • actions/setup-python v5@82c7e631bb3cdc910f68e0081d67478d79c6982d
npm
package.json
  • url-parse 1.5.10
  • prettier 3.2.5
nvm
.nvmrc
  • node 20.14.0
pep621
pyproject.toml
  • poetry-core >=1.0.0
poetry
pyproject.toml
  • python ^3.10
  • aiohttp >=3.8.1
  • yarl >=1.7.2
  • pydantic >=1.9.0
  • packaging >=21.3
  • backoff ^2.2.1
  • async-timeout ^4.0.3
  • covdefaults ^2.3.0
  • ruff ^0.1.0
  • aresponses ^3.0.0
  • black ^23.0.0
  • blacken-docs ^1.13.0
  • coverage ^7.0.5
  • flake8 ^7.0.0
  • isort ^5.11.4
  • mypy ^1.0.0
  • pre-commit ^3.0.0
  • pre-commit-hooks ^4.3.0
  • pylint ^3.0.0
  • pytest ^8.0.0
  • pytest-asyncio ^0.23.0
  • pytest-cov ^4.0.0
  • yamllint ^1.29.0
  • pyupgrade ^3.3.1
  • flake8-simplify ^0.21.0
  • vulture ^2.7
  • darglint ^1.8.1
  • safety ^3.0.0
  • codespell ^2.2.2
  • bandit ^1.7.4
  • pytest-mock ^3.10.0

  • Check this box to trigger a request for Renovate to run again on this repository

Add more parameters/attributes to heating circuit

heating_circuit1 = [
    700,  # hvac_mode
    710,  # target_temperature
    711,  # target_temperature_high
    712,  # target_temperature_low
    714,  # min_temp
    730,  # max_temp
    900,  # hvac_action?
    8000,  # status_heating_circuit1
    8740,  # current_temperature room1
    8749,  # Raumthermostat1

test_http_error400, test_not_authorized_401_response are failing with aiohttp>=3.9.0

Describe the bug

Two tests are failing with aiohttp>=3.9.0 They are test_http_errror400 and test_not_authorized_401_response.

To Reproduce
Steps to reproduce the behavior:

  1. Upgrade aiohttp to e.g. 3.9.1, as used by homeassistant 2023.12.0
  2. Run the testsuite

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context

python-bsblan> ============================= test session starts ==============================
python-bsblan> platform linux -- Python 3.11.6, pytest-7.4.3, pluggy-1.3.0
python-bsblan> rootdir: /build/source
python-bsblan> configfile: pyproject.toml
python-bsblan> plugins: aresponses-2.1.6, asyncio-0.21.1, mock-3.11.1, devtools-0.12.2
python-bsblan> asyncio: mode=Mode.AUTO
python-bsblan> collected 16 items                                                             
python-bsblan> 
python-bsblan> tests/test_bsblan.py ......F.F                                           [ 56%]
python-bsblan> tests/test_device.py .                                                   [ 62%]
python-bsblan> tests/test_info.py .                                                     [ 68%]
python-bsblan> tests/test_sensor.py .                                                   [ 75%]
python-bsblan> tests/test_state.py .                                                    [ 81%]
python-bsblan> tests/test_static_state.py .                                             [ 87%]
python-bsblan> tests/test_thermostat.py ..                                              [100%]
python-bsblan> 
python-bsblan> =================================== FAILURES ===================================
python-bsblan> ______________________________ test_http_error400 ______________________________
python-bsblan> 
python-bsblan> aresponses = <aresponses.main.ResponsesMockServer object at 0x7ffff507a410>
python-bsblan> 
python-bsblan>     @pytest.mark.asyncio
python-bsblan>     async def test_http_error400(aresponses: ResponsesMockServer) -> None:
python-bsblan>         """Test HTTP 404 response handling."""
python-bsblan>         aresponses.add(
python-bsblan>             "example.com",
python-bsblan>             "/",
python-bsblan>             "POST",
python-bsblan>             aresponses.Response(text="OMG PUPPIES!", status=404),
python-bsblan>         )
python-bsblan>     
python-bsblan>         async with aiohttp.ClientSession() as session:
python-bsblan>             bsblan = BSBLAN("example.com", session=session)
python-bsblan>             with pytest.raises(BSBLANError):
python-bsblan> >               assert await bsblan._request("/")
python-bsblan> 
python-bsblan> tests/test_bsblan.py:146: 
python-bsblan> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
python-bsblan> /nix/store/pcxqjpwmr1ym8gyhznikdbgn8i1pzq6a-python3.11-backoff-2.2.1/lib/python3.11/site-packages/backoff/_async.py:151: in retry
python-bsblan>     ret = await target(*args, **kwargs)
python-bsblan> /nix/store/qbr3z806smc2x07ypz7dw76sdz8sr5kk-python3.11-python-bsblan-0.5.16/lib/python3.11/site-packages/bsblan/bsblan.py:129: in _request
python-bsblan>     response = await self.session.request(
python-bsblan> /nix/store/glq1cn6g1sh7c6avqmg0y2bsmxsfg58c-python3.11-aiohttp-3.9.1/lib/python3.11/site-packages/aiohttp/client.py:541: in _request
python-bsblan>     req = self._request_class(
python-bsblan> /nix/store/ixq4rwwdgxs08vgm5m3nyxvs67v1620y-python3.11-aresponses-2.1.6/lib/python3.11/site-packages/aresponses/main.py:289: in new_init
python-bsblan>     self._old_init(_self, *largs, **kwargs)
python-bsblan> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
python-bsblan> 
python-bsblan> self = <aiohttp.client_reqrep.ClientRequest object at 0x7ffff5079650>
python-bsblan> method = '/', url = URL('http://example.com:80/JQ')
python-bsblan> 
python-bsblan>     def __init__(
python-bsblan>         self,
python-bsblan>         method: str,
python-bsblan>         url: URL,
python-bsblan>         *,
python-bsblan>         params: Optional[Mapping[str, str]] = None,
python-bsblan>         headers: Optional[LooseHeaders] = None,
python-bsblan>         skip_auto_headers: Iterable[str] = frozenset(),
python-bsblan>         data: Any = None,
python-bsblan>         cookies: Optional[LooseCookies] = None,
python-bsblan>         auth: Optional[BasicAuth] = None,
python-bsblan>         version: http.HttpVersion = http.HttpVersion11,
python-bsblan>         compress: Optional[str] = None,
python-bsblan>         chunked: Optional[bool] = None,
python-bsblan>         expect100: bool = False,
python-bsblan>         loop: Optional[asyncio.AbstractEventLoop] = None,
python-bsblan>         response_class: Optional[Type["ClientResponse"]] = None,
python-bsblan>         proxy: Optional[URL] = None,
python-bsblan>         proxy_auth: Optional[BasicAuth] = None,
python-bsblan>         timer: Optional[BaseTimerContext] = None,
python-bsblan>         session: Optional["ClientSession"] = None,
python-bsblan>         ssl: Union[SSLContext, Literal[False], Fingerprint, None] = None,
python-bsblan>         proxy_headers: Optional[LooseHeaders] = None,
python-bsblan>         traces: Optional[List["Trace"]] = None,
python-bsblan>         trust_env: bool = False,
python-bsblan>         server_hostname: Optional[str] = None,
python-bsblan>     ):
python-bsblan>         if loop is None:
python-bsblan>             loop = asyncio.get_event_loop()
python-bsblan>     
python-bsblan>         match = _CONTAINS_CONTROL_CHAR_RE.search(method)
python-bsblan>         if match:
python-bsblan> >           raise ValueError(
python-bsblan>                 f"Method cannot contain non-token characters {method!r} "
python-bsblan>                 "(found at least {match.group()!r})"
python-bsblan>             )
python-bsblan> E           ValueError: Method cannot contain non-token characters '/' (found at least {match.group()!r})
python-bsblan> 
python-bsblan> /nix/store/glq1cn6g1sh7c6avqmg0y2bsmxsfg58c-python3.11-aiohttp-3.9.1/lib/python3.11/site-packages/aiohttp/client_reqrep.py:290: ValueError
python-bsblan> _______________________ test_not_authorized_401_response _______________________
python-bsblan> 
python-bsblan> aresponses = <aresponses.main.ResponsesMockServer object at 0x7ffff4ea5710>
python-bsblan> 
python-bsblan>     @pytest.mark.asyncio
python-bsblan>     async def test_not_authorized_401_response(aresponses: ResponsesMockServer) -> None:
python-bsblan>         """Test wrong username and password response handling."""
python-bsblan>         aresponses.add(
python-bsblan>             "example.com",
python-bsblan>             "/JQ",
python-bsblan>             "POST",
python-bsblan>             aresponses.Response(
python-bsblan>                 status=401,
python-bsblan>                 headers={"Content-Type": "text/html"},
python-bsblan>             ),
python-bsblan>         )
python-bsblan>     
python-bsblan>         async with aiohttp.ClientSession() as session:
python-bsblan>             bsblan = BSBLAN("example.com", session=session)
python-bsblan>             with pytest.raises(BSBLANError):
python-bsblan> >               assert await bsblan._request("/JQ")
python-bsblan> 
python-bsblan> tests/test_bsblan.py:181: 
python-bsblan> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
python-bsblan> /nix/store/pcxqjpwmr1ym8gyhznikdbgn8i1pzq6a-python3.11-backoff-2.2.1/lib/python3.11/site-packages/backoff/_async.py:151: in retry
python-bsblan>     ret = await target(*args, **kwargs)
python-bsblan> /nix/store/qbr3z806smc2x07ypz7dw76sdz8sr5kk-python3.11-python-bsblan-0.5.16/lib/python3.11/site-packages/bsblan/bsblan.py:129: in _request
python-bsblan>     response = await self.session.request(
python-bsblan> /nix/store/glq1cn6g1sh7c6avqmg0y2bsmxsfg58c-python3.11-aiohttp-3.9.1/lib/python3.11/site-packages/aiohttp/client.py:541: in _request
python-bsblan>     req = self._request_class(
python-bsblan> /nix/store/ixq4rwwdgxs08vgm5m3nyxvs67v1620y-python3.11-aresponses-2.1.6/lib/python3.11/site-packages/aresponses/main.py:289: in new_init
python-bsblan>     self._old_init(_self, *largs, **kwargs)
python-bsblan> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
python-bsblan> 
python-bsblan> self = <aiohttp.client_reqrep.ClientRequest object at 0x7ffff4ea6710>
python-bsblan> method = '/JQ', url = URL('http://example.com:80/JQ')
python-bsblan> 
python-bsblan>     def __init__(
python-bsblan>         self,
python-bsblan>         method: str,
python-bsblan>         url: URL,
python-bsblan>         *,
python-bsblan>         params: Optional[Mapping[str, str]] = None,
python-bsblan>         headers: Optional[LooseHeaders] = None,
python-bsblan>         skip_auto_headers: Iterable[str] = frozenset(),
python-bsblan>         data: Any = None,
python-bsblan>         cookies: Optional[LooseCookies] = None,
python-bsblan>         auth: Optional[BasicAuth] = None,
python-bsblan>         version: http.HttpVersion = http.HttpVersion11,
python-bsblan>         compress: Optional[str] = None,
python-bsblan>         chunked: Optional[bool] = None,
python-bsblan>         expect100: bool = False,
python-bsblan>         loop: Optional[asyncio.AbstractEventLoop] = None,
python-bsblan>         response_class: Optional[Type["ClientResponse"]] = None,
python-bsblan>         proxy: Optional[URL] = None,
python-bsblan>         proxy_auth: Optional[BasicAuth] = None,
python-bsblan>         timer: Optional[BaseTimerContext] = None,
python-bsblan>         session: Optional["ClientSession"] = None,
python-bsblan>         ssl: Union[SSLContext, Literal[False], Fingerprint, None] = None,
python-bsblan>         proxy_headers: Optional[LooseHeaders] = None,
python-bsblan>         traces: Optional[List["Trace"]] = None,
python-bsblan>         trust_env: bool = False,
python-bsblan>         server_hostname: Optional[str] = None,
python-bsblan>     ):
python-bsblan>         if loop is None:
python-bsblan>             loop = asyncio.get_event_loop()
python-bsblan>     
python-bsblan>         match = _CONTAINS_CONTROL_CHAR_RE.search(method)
python-bsblan>         if match:
python-bsblan> >           raise ValueError(
python-bsblan>                 f"Method cannot contain non-token characters {method!r} "
python-bsblan>                 "(found at least {match.group()!r})"
python-bsblan>             )
python-bsblan> E           ValueError: Method cannot contain non-token characters '/JQ' (found at least {match.group()!r})
python-bsblan> 
python-bsblan> /nix/store/glq1cn6g1sh7c6avqmg0y2bsmxsfg58c-python3.11-aiohttp-3.9.1/lib/python3.11/site-packages/aiohttp/client_reqrep.py:290: ValueError

push function for temperature

when not thermostat is available or you want to set the temperature in other toom. It is possible to push temperature using this command
http://<ip-addresse/I10000=19.5

scan for available parameters

Add scan data to two groups. If relevant for thermostat add to state. If not add to another group and for now do nothing with it. This will be added later for the sensor group and binary sensor

rewrite functions

Naming and how stuff work is not optimal. To get development in HomeAssistant up to speed we need better naming and how we can read specific data.

DHW-push support

Within many controllers there is a (nearly) undocumented function available: a manual DHW push. To initiate a manual DHW push, one has to press and hold the DHW-mode-button at the operational unit. After approx. three seconds a message appears at the display and the heating process starts.

With some controllers this function can also be used with BSB-LAN using a SET-command: http:///S1601=1
or json query
url/JS?Parameter=1601&Value=1&Type=1

error timeout

Describe the bug
when starting homeassistant on a slow system a timeout can occur

Logger: homeassistant.components.climate
Source: components/bsblan/climate.py:72
Integration: Climate ([documentation](https://www.home-assistant.io/integrations/climate), [issues](https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+climate%22))
First occurred: 8:56:25 AM (1 occurrences)
Last logged: 8:56:25 AM

Error while setting up bsblan platform for climate
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/bsblan/bsblan.py", line 73, in _request
    response = await self._session.request(
  File "/usr/local/lib/python3.9/site-packages/aiohttp/client.py", line 535, in _request
    conn = await self._connector.connect(
  File "/usr/local/lib/python3.9/site-packages/aiohttp/connector.py", line 542, in connect
    proto = await self._create_connection(req, traces, timeout)
  File "/usr/local/lib/python3.9/site-packages/aiohttp/connector.py", line 907, in _create_connection
    _, proto = await self._create_direct_connection(req, traces, timeout)
  File "/usr/local/lib/python3.9/site-packages/aiohttp/connector.py", line 1154, in _create_direct_connection
    hosts = await asyncio.shield(host_resolved)
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/bsblan/bsblan.py", line 81, in _request
    response.raise_for_status()
  File "/usr/local/lib/python3.9/site-packages/async_timeout/__init__.py", line 129, in __aexit__
    self._do_exit(exc_type)
  File "/usr/local/lib/python3.9/site-packages/async_timeout/__init__.py", line 212, in _do_exit
    raise asyncio.TimeoutError
asyncio.exceptions.TimeoutError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 249, in _async_setup_platform
    await asyncio.shield(task)
  File "/usr/src/homeassistant/homeassistant/components/bsblan/climate.py", line 72, in async_setup_entry
    info = await bsblan.info()
  File "/usr/local/lib/python3.9/site-packages/bsblan/bsblan.py", line 157, in info
    data = await self._request(params={"Parameter": "6224,6225,6226"})
  File "/usr/local/lib/python3.9/site-packages/bsblan/bsblan.py", line 83, in _request
    raise BSBLanConnectionError(
bsblan.exceptions.BSBLanConnectionError: Timeout occurred while connecting to BSBLan device.

Loosen requirements

CI on home assistant is currently raising the following issue:
python-bsblan 0.5.8 has requirement packaging<22.0,>=21.3, but you have packaging 23.0.

See home-assistant/core#86336

I see that packaging requirements was updated recently to packaging = ">=21.3,<24.0" so would you consider publishing a release and updating accordingly on Home Assistant?

Or maybe you would consider loosening some of the requirements?

python = ">=3.9"
aiohttp = ">=3.8.1"
yarl = ">=1.7.2"
pydantic = ">=1.9.0"
packaging = ">=21.3"

BSBLan device indentification with new firmware

new command get info from divice

/JI

returns
{
"version": "0.44.11-20200410111601",
"freeram": 3049,
"uptime": 115800,
"MAC": "00:80:41:19:69:90",
"bus": "BSB",
"buswritable": 1,
"busaddr": 66,
"busdest": 0,
"monitor": 0,
"verbose": 1,
"protectedGPIO": [
{ "pin": 10 },
{ "pin": 11 },
{ "pin": 12 },
{ "pin": 13 },
{ "pin": 50 },
{ "pin": 51 },
{ "pin": 52 },
{ "pin": 53 },
{ "pin": 62 },
{ "pin": 63 },
{ "pin": 64 },
{ "pin": 65 },
{ "pin": 66 },
{ "pin": 67 },
{ "pin": 68 },
{ "pin": 69 }
],
"averages": [
{ "parameter": 8700 },
{ "parameter": 8326 }
],
"loginterval": 3600,
"logged": [
{ "parameter": 8700 },
{ "parameter": 8314 },
{ "parameter": 8830 }
]
}

Error while adding to Home Assistant

Describe the bug
hi, I try to add a bsblan device to home assistant. I can reach the bsblan webinterface and read configuration values.

To Reproduce
When I add the Integration to home assistant with the correct hostname (IP-Adress) and username-password combination it fails to initialize the integration.

The Log shows the following lines:

2023-10-27 06:11:59.259 ERROR (MainThread) [homeassistant.components.bsblan] Unexpected error fetching bsblan_192.168.2.187 data: zip() argument 2 is shorter than argument 1
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.11/site-packages/homeassistant/helpers/update_coordinator.py", line 290, in _async_refresh
    self.data = await self._async_update_data()
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/homeassistant/lib/python3.11/site-packages/homeassistant/components/bsblan/coordinator.py", line 51, in _async_update_data
    return await self.client.state()
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/homeassistant/lib/python3.11/site-packages/bsblan/bsblan.py", line 171, in state
    data = dict(zip(self._heating_params, list(data.values()), strict=True))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: zip() argument 2 is shorter than argument 1

Expected behavior
I would suspect that entities are created.

Additional context
I use Home Assitant Core on a raspberry pi 3.
Here are the installed versions of homeassistant and python-bsblan:

(homeassistant) homeassistant@homepi /srv/homeassistant $ pip show homeassistant python-bsblan
Name: homeassistant
Version: 2023.10.4
Summary: Open-source home automation platform running on Python 3.
Home-page:
Author:
Author-email: The Home Assistant Authors <[email protected]>
License: Apache-2.0
Location: /srv/homeassistant/lib/python3.11/site-packages
Requires: aiohttp, astral, atomicwrites-homeassistant, attrs, awesomeversion, bcrypt, certifi, ciso8601, cryptography, home-assistant-bluetooth, httpx, ifaddr, Jinja2, lru-dict, orjson, packaging, pip, PyJWT, pyOpenSSL, python-slugify, PyYAML, requests, typing-extensions, ulid-transform, voluptuous, voluptuous-serialize, yarl
Required-by:
---
Name: python-bsblan
Version: 0.5.16
Summary: Asynchronous Python client for BSBLAN
Home-page: https://github.com/liudger/python-bsblan
Author: Willem-Jan van Rootselaar
Author-email: [email protected]
License: MIT
Location: /srv/homeassistant/lib/python3.11/site-packages
Requires: aiohttp, backoff, packaging, pydantic, yarl
Required-by:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.