Custom component for iZone air conditioner

I just did:

https://github.com/home-assistant/core/issues/53071

Hope it’s in the right place.

Cheers,
Miroslav

Hi, any chance to support the other iZone products in this integration? I have the power monitors and those would be great with the new energy dashboards. Not really keen on getting another power monitor installed. Thanks

As it happens, I have a power monitor sitting in a box waiting for a sparkie to install it. Once I have it working I was intending on coding the integration in.

Not sure when I’ll get around to doing it though, will have to see.

Good to hear its intended, thanks in advance! no pressure :slight_smile:

What are the chances you got that power monitor installed and had any chance to look at the integration? I have a small collection of the API docs and some other third party scripts etc if it is useful, its all on github as well. Would really love to see the power monitoring brought in, i think it would open up some amazing automations etc

Hi,

I actually coded this up and submitted a PR to get it accepted. I couldn’t get anyone to review the code though, they asked me to break it up into smaller parts but I have other stuff going on IRL so don’t really have time.

If I could have some coders who would also work with me on anything HA related for iZone that would be great because then we could get stuff accepted more easily.

1 Like

I know absoultely nothing, but im willing to learn - i managed to use some udp and tcp nodes in Node Red to ping the controller and get some data back, that was fun but really im pretty useless with it. There seems to be a python piZone script on github someone has written including the power stuff, (edit - just realised thats probably yours!) but no idea how to impliment that inside home assistant. But anything I can do to help, point me in the right direction and i’ll try my best…

Yeh that’s mine. :slight_smile:

Am trying to recruit any coders who’d like to team with me to review any iZone HA stuff.

1 Like

I am learning, slowly slowly slowly. I am managing to get local data with a small python script, but I had to learn python from scratch and have only gotten this far - is this of any use towards getting the power monitoring integrated? This is geting me just the raw current info but it is matching up to correct channel numbers and the figures are correct, for my system at least

Script as follows, and unfortunately has dependencies which I assume the izone integration already uses some of anyway:

import asyncio
import json

import aiohttp

# Replace with the IP address and port of your iZone controller
CONTROLLER_ADDRESS = "192.168.1.100:80"

async def main():
    async with aiohttp.ClientSession() as session:
        # Construct the request payload
        payload = {"PowerRequest": {"Type": 2, "No": 0, "No1": 0}}

        # Send the request to the iZone controller
        async with session.post(f"http://{CONTROLLER_ADDRESS}/PowerRequest", json=payload) as resp:
            if resp.status != 200:
                print("Failed to get power monitoring data")
                return

            # Parse the response
            data = json.loads(await resp.text())
            print("Power monitoring data:", data)

asyncio.run(main())

And after all that it seems the pyZone project has the energy monitoring brought in already -

thats your onw @Swamp-Ig - is there a straightforward way to get that across into Home Assistant?

Of course you did this a year ago now :confused: I told you i’m completely green to this.

I’m probably being a hinderance rather than a help here, but I am just doing this off the docs, I havent setup a development environment to test this stuff yet - its likely all gibberish. But heres what i’ve got on my end using your pyZone mostly and some guesses as to getting it into HA.

Add power as a sensor in climate.py - i think you have it fleshed out properly in the pyZone release I am going cross eyed staring at the screen at the moment

class ClimateDevice:
    def __init__(self, ctrl, zone: pizone.Zone):
        self._ctrl = ctrl
        self._zone = zone
        # Add a reference to the Power object
        self._power = None

    @property
    def should_poll(self):
        return True

    @property
    def unique_id(self):
        return f"{self._ctrl.uid}_{self._zone.zone_id}"

    @property
    def name(self):
        return self._zone.name

    @property
    def device_info(self):
        return {
            "identifiers": {(IZONE, self._ctrl.uid)},
            "name": self._ctrl.name,
            "manufacturer": "iZone",
            "model": "iZone Aircon",
            "sw_version": self._ctrl.firmware

add power to the discovery service

class DiscoveryService(pizone.Listener):
    """Discovery data and interfacing with pizone library."""

    def __init__(self, hass):
        """Initialise discovery service."""
        super().__init__()
        self.hass = hass
        self.pi_disco = None

    # Listener interface
    def controller_discovered(self, ctrl: pizone.Controller) -> None:
        """Handle new controller discoverery."""
        async_dispatcher_send(self.hass, DISPATCH_CONTROLLER_DISCOVERED, ctrl)

    def controller_disconnected(self, ctrl: pizone.Controller, ex: Exception) -> None:
        """On disconnect from controller."""
        async_dispatcher_send(self.hass, DISPATCH_CONTROLLER_DISCONNECTED, ctrl, ex)

    def controller_reconnected(self, ctrl: pizone.Controller) -> None:
        """On reconnect to controller."""
        async_dispatcher_send(self.hass, DISPATCH_CONTROLLER_RECONNECTED, ctrl)

    def controller_update(self, ctrl: pizone.Controller) -> None:
        """System update message is received from the controller."""
        async_dispatcher_send(self.hass, DISPATCH_CONTROLLER_UPDATE, ctrl)

        # Send the power monitoring data along with the controller update
        power = ctrl.power()
        if power:
            async_dispatcher_send(self.hass, DISPATCH_POWER_UPDATE, power)

    def zone_update(self, ctrl: pizone.Controller, zone: pizone.Zone) -> None:
        """Zone update message is received from the controller."""
        async_dispatcher_send(self.hass, DISPATCH_ZONE_UPDATE, ctrl, zone)

Add the dispatch power update to the const.py

DISPATCH_POWER_UPDATE = "izone_power_update"

update the async_start_discovery_service() function to listen for this

async def async_start_discovery_service(hass: HomeAssistant):
    """Set up the pizone internal discovery."""
    if disco := hass.data.get(DATA_DISCOVERY_SERVICE):
        # Already started
        return disco

    # discovery local services
    disco = DiscoveryService(hass

Update the DiscoveryService class

class DiscoveryService(pizone.Listener):
    # ...

    async def get_power_monitoring_data(self):
        """Make a request to the controller to get power monitoring data"""
        payload = {"PowerRequest": {"Type": 2, "No": 0, "No1": 0}}
        async with self.hass.aiohttp_client.async_get_clientsession() as session:
            async with session.post(f"http://{self.pi_disco.controller.address}/PowerRequest", json=payload) as resp:
                if resp.status != 200:
                    _LOG.error("Failed to get power monitoring data")
                    return
                data = json.loads(await resp.text())
                _LOG.debug("Power monitoring data: %s", data)
                self._power_data = data

    # ...

And maybe making it an optional toggle in the config to not bug everyone who doesn’t have power monitoring but does have the izone AC

# In your configuration.yaml

izone:
  # other configuration options
  power_monitoring: true


and a custom component for the power monitoring

import asyncio

from homeassistant.helpers.entity import Entity
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant

from .const import (
    DOMAIN,
    DATA_CONFIG,
    DISPATCH_CONTROLLER_DISCOVERED,
    DISPATCH_CONTROLLER_DISCONNECTED,
    DISPATCH_CONTROLLER_RECONNECTED,
    DISPATCH_CONTROLLER_UPDATE,
    DISPATCH_ZONE_UPDATE,
)
from .power import Power


async def async_setup_entry(
    hass: HomeAssistant,
    entry: ConfigEntry,
    async_add_entities,
):
    # Get the discovery service
    discovery_service = hass.data[DATA_DISCOVERY_SERVICE]

    # Create a data update coordinator to manage updates to the power data
    coordinator = PowerDataUpdateCoordinator(hass, discovery_service.controller)
    await coordinator.async_refresh()

    # Create an entity for each power group
    entities = [PowerGroupEntity(coordinator, group) for group in coordinator.data.groups]

    # Add the entities to Home Assistant
    async_add_entities(entities, update_before_add=True)


class PowerGroupEntity(Entity):
    """Power group entity"""

    def __init__(self, coordinator: PowerDataUpdateCoordinator, group: PowerGroup):
        self._coordinator = coordinator
        self._group = group

    @property
    def unique_id(self) -> str:
        """Unique ID"""
        return f"power_group_{self._group.number}"

    @property
    def name(self) -> str:
        """Name"""
        return f"Power Group {self._group.number}"

    @property
    def state(self) -> int:
        """Power consumption in watts"""
        return self._group.consumed

    @property
    def unit_of_measurement(self) -> str:
        """Unit of measurement"""
        return "W"

    async def async_update(self):
        """Refresh the data"""
        await self._coordinator.async_refresh()


class PowerDataUpdateCoordinator(DataUpdateCoordinator):
   

But i think this all leaves it in as a climate entity, rather than an enrgy entity, so it might not play nice with the built in HA energy components… Also theres like a 99% chance that the above is useless and wont help or work anyway. If i can find another free weekend I might set up a development environment and make a fork and see about trying to get it to work on that, but I live in the hope that someone who knows much more than me can impliment it in the meantime!

Maybe template sensor would show in as energy properly?

- platform: template
  sensors:
    izone_power:
      value_template: "{{ state_attr('climate.zone_1', 'power_data')['Groups'][0]['Total'] }}"
      unit_of_measurement: W

I actually did all the coding to get power integrated into HA and submitted a PR with the completed work.

It sat there for a while waiting for review and eventually I was asked to change the code. I’ve not taken this any further as I don’t really have the time to faff around trying to get stuff pass review, and overall I’m a bit demoralised regarding trying to contribute to HA since this pretty much always happens.

So… unfortunately as it stands I’ve given up for the moment. If I had someone else who wanted to work on HA stuff with me to get things past review for iZone then we could probably move forward, but I’m pretty time poor as it is these days.

Here’s the branch with the PR in it: GitHub - Swamp-Ig/home-assistant at izone-power-monitor

Thank you, yeah know what that is like, being time poor - but I keep coming back to this wishing it was a thing, and especially since you’ve already done the hard yards, seems a shame to fall at the last hurdle as it were. Ill see if i can figure out what needs to be done from here to help try to get it across the line

I’m more thaan happy to try to help, im also time poor and this isn’t my forte, but I’m in WA as well and can somewhat muddle my way through the docs and whatnot if i know where to look. hopefully.

**Edit, OK found the pull request. They want it broken down into smaller, easier to review parts. Facepalm. I see why you got discouraged :confused: off to work now but i have something to look into now at least

Sounds good.

The guts of the work in the PR was actually in developing the update handler that was asked for in another PR. The adding the power stuff was actually pretty minor. Please feel free to PM me on the home assistant discord. I’m Penny#7205 I don’t always have discord open, but I’ll leave it open the next few days plus I think it’s going on my phone.

I moved my HA setup from a Odroid N2+ to a KVM VM on a linux host.

Since doing so, the iZone integration no longer works.
The VM is running using a bridge interface working of a real ethernet adapter on the same subnet.
The integration works great with HA running on the host machine, but not the HAOS guest.

When loading the integration in the guest OS , I get “No devices found on the network” after a while.

Any ideas what I could be missing? I understand that iZone uses UDP broadcast, but I would have assumed it “just” worked when using a bridge network interface

I use mine in a VM too with bridge and it works fine, however mine is Core so there is no additional 2nd virtualisation layer (Docker).

If you are sure the VM is definitely bridged properly, I’d guess there is an issue with docker in HAOS, not properly bridging to the VM NIC?

Hey,

This is probably because the broadcast messages aren’t being transmitted back and forth between the controller and home assistant. It’s an issue with the underlying network setup, it’s probably not the only thing where the discovery won’t work.

I haven’t done much dev work for the iZone integration in a while. I really need someone to test it and to work together on PRs so that I can get them reviewed and accepted. The core devs are too busy to do it and I can’t do tiny bits of work occasionally, I need to have proper bites at it.

By changing the network adapter type from virtio to e1000e it now works. No idea on why.