Skip to content

Commit

Permalink
feat: basic legacy api support
Browse files Browse the repository at this point in the history
Adds basic legacy api sensor support. I.e. reading of values.

Squashed from the following commits:

* refactor: switch to httpx
* docs(readme): add legacy support notice
* feat: support legacy websocket messages
* refactor: parallel legacy node calls
* fix: use correct previous key for legacy
* fix: stricter node value checks
* fix: don't pull energy on legacy
* refactor: simplify nexa api calls
* docs(readme): update description
* refactor: move ws port to const
* refactor: clean up ws class constructor
* refactor: prepare for legacy energy metering support
* refactor: split node value property population
* docs(help): update compatiblity
* refactor: remove unwanted newline
* refactor: update energy model population
* chore: auth digest detection for perf
* feat: auto discovery for legacy (maybe)
  • Loading branch information
andersevenrud committed Feb 13, 2023
1 parent 4538226 commit b940de2
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 77 deletions.
2 changes: 2 additions & 0 deletions HELP.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ This project was developed using a bridge with firmware version `2.4.1`.
Assuming Nexa uses appropriate versioning, this integration *should* be compatible with any
firmware version starting with `2`.

> The legacy "Nexa Bridge" (non-X) with version `1` firmware is supported, but with limited functionality.

## I can't connect

Ensure that you're connecting to the correct IP and with the correct credentials.
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

This is a custom Home Assistant integration for the [Nexa Bridge X](https://nexa.se/nexa-bridge-x).

> The legacy "Nexa Bridge" (non-X) is also supported, but with limited functionality.
Makes it possible to view and control devices set up in the Nexa App/Web UI.

> This project is a **unofficial** integration and not affiliated with Nexa in any way.
Expand Down
15 changes: 11 additions & 4 deletions custom_components/nexa_bridge_x/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
vol.Required("host"): str,
vol.Required("username", default=DEFAULT_USERNAME): str,
vol.Required("password", default=DEFAULT_PASSWORD): str,
vol.Required("legacy", default=False): bool,
}
)

Expand All @@ -43,7 +44,7 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str,
"""

try:
api = NexaApi(data["host"], data["username"], data["password"])
api = NexaApi(hass, data["host"], data["username"], data["password"], data["legacy"])
info = await api.test_connection()
except Exception:
raise InvalidAuth
Expand All @@ -60,14 +61,16 @@ class NexaBridgeXFlowHandler(ConfigFlow, domain=DOMAIN):
_discovered_host: str | None = None
_discovered_username: str | None = None
_discovered_password: str | None = None
_discovered_legacy: bool = False

async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle the initial step."""
if user_input is None:
return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA
step_id="user",
data_schema=STEP_USER_DATA_SCHEMA
)

errors = {}
Expand Down Expand Up @@ -102,6 +105,7 @@ async def async_step_zeroconf(
host: str = discovery_info.host
username: str = DEFAULT_USERNAME
password: str = DEFAULT_PASSWORD
is_legacy: bool = "nexabridge2" not in uid

await self.async_set_unique_id(uid.upper())

Expand All @@ -110,7 +114,7 @@ async def async_step_zeroconf(
})

try:
api = NexaApi(host, 'nexa', 'nexa')
api = NexaApi(self.hass, host, 'nexa', 'nexa', is_legacy)
info = await api.test_connection()
except Exception: # pylint: disable=broad-except
return self.async_abort(reason="unknown")
Expand All @@ -119,13 +123,15 @@ async def async_step_zeroconf(
self._discovered_host = host
self._discovered_username = username
self._discovered_password = password
self._discovered_legacy = is_legacy

self._set_confirm_only()

self.context["title_placeholders"] = {
"host": host,
"username": username,
"password": password
"password": password,
"legacy": is_legacy,
}

return await self.async_step_discovery_confirm()
Expand All @@ -141,6 +147,7 @@ async def async_step_discovery_confirm(
"host": self._discovered_host,
"username": self._discovered_username,
"password": self._discovered_password,
"legacy": self._discovered_legacy,
}

if user_input is None:
Expand Down
10 changes: 10 additions & 0 deletions custom_components/nexa_bridge_x/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@

DEFAULT_PASSWORD = "nexa"

WS_PORT = 8887

HTTP_BASIC_AUTH = False

SWITCH_LEVEL_SENSOR = True

SWITCH_BINARY_SENSOR = True
Expand Down Expand Up @@ -71,6 +75,12 @@
"month_kilowatt_hours"
]

# TODO: Add support for legacy energy metering
LEGACY_ENERGY_ATTRS = [
#"total_kilowatt_hours",
#"current_wattage",
]

BINARY_MAP = {
"notificationContact": {
"name": "Contact"
Expand Down
6 changes: 5 additions & 1 deletion custom_components/nexa_bridge_x/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
{
"type": "_ssh._tcp.local.",
"name": "nexabridge2"
},
{
"type": "_ssh._tcp.local.",
"name": "nexabridge"
}
],
"dependencies": [
Expand All @@ -20,4 +24,4 @@
],
"iot_class": "local_polling",
"integration_type": "hub"
}
}
Loading

0 comments on commit b940de2

Please sign in to comment.