-
-
Notifications
You must be signed in to change notification settings - Fork 37.4k
Add Wibeee energy monitoring integration #168419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 3 commits
e89eee4
c633461
11a0a06
500e050
b72296d
683d672
82a062e
20ad7b9
d190c8a
09ed254
e02601a
ae975a7
6133c75
a8edf92
14a448b
211d9c9
042660c
e1d7e99
d12073a
570c6fd
6b00186
5323c3d
8b88cc1
c1eaa5e
8c4d140
9d74d4b
beb4d58
61e6eec
3eeb385
f3194dd
cfc02ff
58bc6df
5995efe
a0b36f2
13abc52
00dcc3d
687b01f
effed37
70e30a2
65be1d3
e935d73
ed378f8
cc16f05
32862e1
88e883e
12644ca
1dd0bef
0cd4457
608fa8f
63c2b26
0872a3e
b7aa02a
ba45f83
adf39b7
1ff85ba
65b4280
bc48239
d54e23b
62d3a56
209df15
dc21e5f
4b6ef46
d69385d
7c4401a
d6282af
bf13e93
689aeca
0bddaf6
ecbb3af
6d560b0
c3afef3
73f6638
2609965
5aae960
14e3db7
9f2caee
ed20679
e269140
9613bbf
24f1e87
c1b443e
db262df
e381e63
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,155 @@ | ||||||||
| """ | ||||||||
| Wibeee Energy Monitor integration for Home Assistant. | ||||||||
|
|
||||||||
| This integration communicates with Wibeee (formerly Mirubee) energy monitoring | ||||||||
| devices manufactured by Smilics/Circutor over the local network. | ||||||||
|
|
||||||||
| Supports two update modes: | ||||||||
| - **Local Push** (default): The WiBeee pushes data to HA's built-in HTTP | ||||||||
| server (port 8123 by default) at ``/Wibeee/receiverAvg``. | ||||||||
| Can auto-configure the device to point to the HA instance. | ||||||||
| - **Polling**: Periodically fetches status.xml from the device. | ||||||||
|
|
||||||||
| No HACS required - works as a native custom_component. | ||||||||
|
|
||||||||
| Documentation: https://github.com/fquinto/pywibeee | ||||||||
| Device info: http://wibeee.circutor.com/ | ||||||||
| """ | ||||||||
|
|
||||||||
| from __future__ import annotations | ||||||||
|
|
||||||||
| import logging | ||||||||
| from dataclasses import dataclass | ||||||||
| from datetime import timedelta | ||||||||
|
|
||||||||
| from homeassistant.config_entries import ConfigEntry | ||||||||
| from homeassistant.const import CONF_HOST, Platform | ||||||||
| from homeassistant.core import HomeAssistant | ||||||||
| from homeassistant.exceptions import ConfigEntryNotReady | ||||||||
| from homeassistant.helpers.aiohttp_client import async_get_clientsession | ||||||||
|
|
||||||||
| from .api import WibeeeAPI, WibeeeDeviceInfo | ||||||||
| from .const import ( | ||||||||
| CONF_MAC_ADDRESS, | ||||||||
| CONF_SCAN_INTERVAL, | ||||||||
| CONF_UPDATE_MODE, | ||||||||
| CONF_WIBEEE_ID, | ||||||||
| DEFAULT_SCAN_INTERVAL, | ||||||||
| DOMAIN, # noqa: F401 — re-exported for other modules | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we can just import from where its created |
||||||||
| MODE_LOCAL_PUSH, | ||||||||
| MODE_POLLING, | ||||||||
| ) | ||||||||
| from .coordinator import WibeeeCoordinator | ||||||||
|
|
||||||||
| _LOGGER = logging.getLogger(__name__) | ||||||||
|
|
||||||||
| PLATFORMS = [Platform.BUTTON, Platform.SENSOR] | ||||||||
|
|
||||||||
|
Comment on lines
+34
to
+35
|
||||||||
|
|
||||||||
| @dataclass | ||||||||
| class WibeeeRuntimeData: | ||||||||
| """Runtime data stored in entry.runtime_data.""" | ||||||||
|
|
||||||||
| api: WibeeeAPI | ||||||||
| device_info: WibeeeDeviceInfo | ||||||||
| coordinator: WibeeeCoordinator | ||||||||
|
|
||||||||
|
|
||||||||
| WibeeeConfigEntry = ConfigEntry[WibeeeRuntimeData] | ||||||||
|
|
||||||||
|
|
||||||||
| async def async_setup_entry(hass: HomeAssistant, entry: WibeeeConfigEntry) -> bool: | ||||||||
| """Set up Wibeee from a config entry.""" | ||||||||
| mode = entry.options.get(CONF_UPDATE_MODE, MODE_LOCAL_PUSH) | ||||||||
| host = entry.data[CONF_HOST] | ||||||||
| mac_addr = entry.data[CONF_MAC_ADDRESS] | ||||||||
| wibeee_id = entry.data.get(CONF_WIBEEE_ID, "WIBEEE") | ||||||||
|
|
||||||||
| _LOGGER.debug( | ||||||||
| "Setting up Wibeee entry %s (mode=%s, host=%s)", | ||||||||
| entry.entry_id, | ||||||||
| mode, | ||||||||
| host, | ||||||||
| ) | ||||||||
|
|
||||||||
| session = async_get_clientsession(hass) | ||||||||
| api = WibeeeAPI(session, host) | ||||||||
|
|
||||||||
| # Fetch device info | ||||||||
| try: | ||||||||
| device_info = await api.async_fetch_device_info(retries=3) | ||||||||
| except Exception as err: | ||||||||
|
fquinto marked this conversation as resolved.
Outdated
|
||||||||
| raise ConfigEntryNotReady(f"Could not connect to Wibeee at {host}") from err | ||||||||
|
|
||||||||
| if device_info is None: | ||||||||
| _LOGGER.warning("Could not get device info from %s, using fallback", host) | ||||||||
| device_info = WibeeeDeviceInfo( | ||||||||
| wibeee_id=wibeee_id, | ||||||||
| mac_addr=mac_addr, | ||||||||
| model="Unknown", | ||||||||
| firmware_version="Unknown", | ||||||||
| ip_addr=host, | ||||||||
| ) | ||||||||
|
|
||||||||
| # Create coordinator based on mode | ||||||||
| if mode == MODE_POLLING: | ||||||||
| scan_interval = timedelta( | ||||||||
| seconds=entry.options.get( | ||||||||
| CONF_SCAN_INTERVAL, | ||||||||
| int(DEFAULT_SCAN_INTERVAL.total_seconds()), | ||||||||
| ) | ||||||||
| ) | ||||||||
| coordinator = WibeeeCoordinator( | ||||||||
| hass, | ||||||||
| api, | ||||||||
| name=f"Wibeee {device_info.mac_addr_short}", | ||||||||
|
Comment on lines
+83
to
+88
|
||||||||
| update_interval=scan_interval, | ||||||||
| ) | ||||||||
| await coordinator.async_config_entry_first_refresh() | ||||||||
|
Comment on lines
+84
to
+91
|
||||||||
| else: | ||||||||
| # Push mode: no polling, data arrives via async_set_updated_data() | ||||||||
| coordinator = WibeeeCoordinator( | ||||||||
| hass, | ||||||||
| api, | ||||||||
| name=f"Wibeee {device_info.mac_addr_short}", | ||||||||
| update_interval=None, | ||||||||
|
Comment on lines
+94
to
+99
|
||||||||
| ) | ||||||||
| # Do one initial poll to discover available sensors | ||||||||
| initial_data = await api.async_fetch_sensors_data(retries=3) | ||||||||
| if initial_data: | ||||||||
| coordinator.async_push_update(initial_data) | ||||||||
|
|
||||||||
|
fquinto marked this conversation as resolved.
Outdated
Comment on lines
+102
to
+112
|
||||||||
| coordinator.async_set_updated_data(initial_data) |
Copilot
AI
Apr 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Register the push receiver with a concrete device IP (or resolve hostnames) so IP validation doesn’t reject legitimate push requests when the user configured the device via hostname.
Uh oh!
There was an error while loading. Please reload this page.