Skip to content

Commit

Permalink
Add error handling and connection closing
Browse files Browse the repository at this point in the history
  • Loading branch information
Aki committed Jul 29, 2024
1 parent 38855bf commit 96f162b
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 76 deletions.
18 changes: 15 additions & 3 deletions custom_components/emonio/__init__.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,37 @@
import asyncio
import logging

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant

from .const import DOMAIN

_LOGGER = logging.getLogger(__name__)

async def async_setup(hass: HomeAssistant, config: dict):
"""Set up the Emonio component."""
return True

async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
"""Set up Emonio from a config entry."""
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.entry_id] = {
"client": None, # Placeholder for the Modbus client
"entities": [], # Placeholder for the entities
}
await hass.config_entries.async_forward_entry_setups(entry, ["sensor"])

return True

async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
"""Unload a config entry."""
await hass.config_entries.async_unload_platforms(entry, ["sensor"])
hass.data[DOMAIN].pop(entry.entry_id)
if entry.entry_id in hass.data[DOMAIN]:
# Close Modbus client connections for all entities
for entity in hass.data[DOMAIN][entry.entry_id]["entities"]:
entity.close_connection()

return True
# Remove the entry from hass.data
hass.data[DOMAIN].pop(entry.entry_id)

await hass.config_entries.async_unload_platforms(entry, ["sensor"])
return True
39 changes: 34 additions & 5 deletions custom_components/emonio/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import voluptuous as vol
import ipaddress
from pymodbus.client.sync import ModbusTcpClient
from scapy.all import ARP, Ether, srp

from .const import DOMAIN

Expand All @@ -13,6 +14,22 @@ def validate_ip(value):
except ValueError:
raise vol.Invalid("Invalid IP address")

def get_mac_address(ip_address):
"""Get the MAC address of a device by IP address."""
try:
arp_request = ARP(pdst=ip_address)
broadcast = Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast / arp_request
answered_list = srp(arp_request_broadcast, timeout=1, verbose=False)[0]

for sent, received in answered_list:
return received.hwsrc

return None
except Exception as e:
_LOGGER.error(f"Error getting MAC address for {ip_address}: {e}")
return None

class EmonioModbusConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Emonio Modbus."""

Expand Down Expand Up @@ -50,13 +67,25 @@ async def async_step_test_connection(self, user_input):
host = user_input['host']
port = user_input['port']

client = ModbusTcpClient(host, port)
if client.connect():
def connect_client():
client = ModbusTcpClient(host, port)
connection_result = client.connect()
client.close()
return self.async_create_entry(title=f"Emonio P3 {host}", data=user_input)
return connection_result

def fetch_mac_address():
return get_mac_address(host)

connection_result = await self.hass.async_add_executor_job(connect_client)
if connection_result:
mac_address = await self.hass.async_add_executor_job(fetch_mac_address)
if mac_address:
mac_suffix = mac_address.replace(':', '')[-6:].upper()
return self.async_create_entry(title=f"Emonio P3 {mac_suffix}", data=user_input)
else:
errors["base"] = "Could not get MAC address. Ensure the device is reachable."
else:
errors["base"] = "Connection was not possible. Ensure Modbus server is enabled."
client.close()

return self.async_show_form(
step_id="user",
Expand All @@ -67,4 +96,4 @@ async def async_step_test_connection(self, user_input):
}
),
errors=errors,
)
)
2 changes: 1 addition & 1 deletion custom_components/emonio/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
"requirements": [
"pymodbus==2.5.3"
],
"version": "0.1.4"
"version": "0.1.5"
}
Loading

0 comments on commit 96f162b

Please sign in to comment.