Skip to content
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

Allow reloading the integration #209

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions custom_components/nhc2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ async def async_setup(hass, config):
"update",
)

async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
for platform in FORWARD_PLATFORMS:
hass.add_job(
hass.config_entries.async_forward_entry_unload(entry, platform)
)
coco: CoCo = hass.data[KEY_GATEWAY][entry.entry_id]
coco.disconnect()
return True

async def async_setup_entry(hass, entry):
"""Create a NHC2 gateway."""
Expand Down
4 changes: 3 additions & 1 deletion custom_components/nhc2/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Config flow to configure component."""
import socket
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import CONF_HOST, CONF_USERNAME, CONF_PASSWORD, CONF_ADDRESS, CONF_PORT
Expand Down Expand Up @@ -97,7 +98,8 @@ async def async_step_manual_host(self, user_input=None):

try:
host = socket.gethostbyaddr(user_input_host)[0]
except:
except Exception as e:
_LOGGER.warning(e)
host = None

self._all_cocos = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def __init__(self, device_instance: CocoAlarmsAction, hub, gateway):
self._attr_supported_features = AlarmControlPanelEntityFeature.ARM_AWAY

@property
def state(self) -> str:
def alarm_state(self) -> str:
if self._device.is_basic_state_off:
return AlarmControlPanelState.DISARMED
if self._device.is_basic_state_on:
Expand Down
22 changes: 6 additions & 16 deletions custom_components/nhc2/nhccoco/coco.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import sys
import json
import os
import threading
from time import sleep
import sys
import uuid

import paho.mqtt.client as mqtt
from time import sleep
from .mqtt import NHCMQTTClient

from .devices.accesscontrol_action import CocoAccesscontrolAction
from .devices.airco_hvac import CocoAircoHvac
Expand Down Expand Up @@ -40,6 +38,7 @@
from .devices.overallcomfort_action import CocoOverallcomfortAction
from .devices.pir_action import CocoPirAction
from .devices.peakmode_action import CocoPeakmodeAction
from .devices.solarmode_action import CocoSolarmodeAction
from .devices.playerstatus_action import CocoPlayerstatusAction
from .devices.reynaers_action import CocoReynaersAction
from .devices.robinsip_videodoorstation import CocoRobinsipVideodoorstation
Expand Down Expand Up @@ -76,7 +75,7 @@


class CoCo:
def __init__(self, address, username, password, port=8884, ca_path=None):
def __init__(self, address, username, password, port=8884):
# The device control buffer fields
self._keep_thread_running = True
self._device_control_buffer = {}
Expand All @@ -86,17 +85,8 @@ def __init__(self, address, username, password, port=8884, ca_path=None):
self._device_control_buffer_thread = threading.Thread(target=self._publish_device_control_commands)
self._device_control_buffer_thread.start()

if ca_path is None:
ca_path = os.path.dirname(os.path.realpath(__file__)) + MQTT_CERT_FILE

# Configure the client
client = mqtt.Client(client_id="homeassistant-" + str(uuid.uuid1()), protocol=MQTT_PROTOCOL,
transport=MQTT_TRANSPORT)
client.username_pw_set(username, password)
client.tls_set(ca_path)
client.tls_insecure_set(True)

self._client = client
self._client = NHCMQTTClient.create(username, password)
self._address = address
self._port = port
self._profile_creation_id = username
Expand Down
24 changes: 5 additions & 19 deletions custom_components/nhc2/nhccoco/coco_login_validation.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import asyncio
import os

import paho.mqtt.client as mqtt

from .const import MQTT_PROTOCOL, MQTT_TRANSPORT

loop = asyncio.get_event_loop()
from .mqtt import NHCMQTTClient


class CoCoLoginValidation:
""" Validate one can login on the CoCo
"""

def __init__(self, address, username, password, port=8883, ca_path=None):
def __init__(self, address, username, password, port=8883):
self._address = address
self._username = username
self._password = password
self._port = port
self._ca_path = ca_path

"""
Try to connect with given parameters
Expand All @@ -34,7 +28,8 @@ def __init__(self, address, username, password, port=8883, ca_path=None):
async def check_connection(self, timeout=10):
result_code = 0
done_testing = asyncio.Event()
client = self._generate_client()
loop = asyncio.get_running_loop()
client = NHCMQTTClient.create(self._username, self._password)

def done():
nonlocal done_testing
Expand All @@ -47,7 +42,7 @@ def on_connect(x, xx, xxx, reason_code):

client.on_connect = on_connect
client.loop_start()
client.connect_async(self._address, self._port, keepalive=timeout)
client.connect_async(self._address, self._port)

try:
await asyncio.wait_for(done_testing.wait(), timeout + 2)
Expand All @@ -57,12 +52,3 @@ def on_connect(x, xx, xxx, reason_code):
client.disconnect()
client.loop_stop()
return result_code

def _generate_client(self):
if self._ca_path is None:
self._ca_path = os.path.dirname(os.path.realpath(__file__)) + '/coco_ca.pem'
client = mqtt.Client(protocol=MQTT_PROTOCOL, transport=MQTT_TRANSPORT)
client.username_pw_set(self._username, self._password)
client.tls_set(self._ca_path)
client.tls_insecure_set(True)
return client
16 changes: 6 additions & 10 deletions custom_components/nhc2/nhccoco/coco_profiles.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import json
import os
import asyncio

import paho.mqtt.client as mqtt
from .mqtt import NHCMQTTClient

from .const import MQTT_TOPIC_PUBLIC_AUTH_RSP, MQTT_PROTOCOL, MQTT_TRANSPORT, MQTT_TOPIC_PUBLIC_AUTH_CMD
from .const import MQTT_TOPIC_PUBLIC_AUTH_RSP, MQTT_TOPIC_PUBLIC_AUTH_CMD


class CoCoProfiles:
"""CoCoDiscover will collect a list of profiles on a NHC2
"""CoCoProfiles will collect a list of profiles on a NHC2
"""

def __init__(self, address, port=8883, ca_path=None):
if ca_path is None:
ca_path = os.path.dirname(os.path.realpath(__file__)) + '/coco_ca.pem'
client = mqtt.Client(protocol=MQTT_PROTOCOL, transport=MQTT_TRANSPORT)
client.tls_set(ca_path)
client.tls_insecure_set(True)
def __init__(self, address, port=8883):
client = NHCMQTTClient.create()

self._client = client
self._address = address
self._loop = 0
Expand Down
19 changes: 19 additions & 0 deletions custom_components/nhc2/nhccoco/devices/solarmode_action.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from ..const import PROPERTY_BASIC_STATE, PROPERTY_BASIC_STATE_VALUE_ON, PROPERTY_BASIC_STATE_VALUE_TRIGGERED
from .device import CoCoDevice


class CocoSolarmodeAction(CoCoDevice):
@property
def basic_state(self) -> str:
return self.extract_property_value(PROPERTY_BASIC_STATE)

@property
def is_basic_state_on(self) -> bool:
return self.basic_state == PROPERTY_BASIC_STATE_VALUE_ON

def press(self, gateway):
gateway.add_device_control(
self.uuid,
PROPERTY_BASIC_STATE,
PROPERTY_BASIC_STATE_VALUE_TRIGGERED
)
29 changes: 29 additions & 0 deletions custom_components/nhc2/nhccoco/mqtt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import os
import ssl
import uuid
import logging
import paho.mqtt.client as mqtt
from .const import MQTT_PROTOCOL, MQTT_TRANSPORT, MQTT_CERT_FILE

_LOGGER = logging.getLogger(__name__)

def create_ssl_context():
context = ssl.create_default_context()
ca_path = os.path.dirname(os.path.realpath(__file__)) + MQTT_CERT_FILE
context.load_verify_locations(ca_path)
context.check_hostname = False
return context

# Fix blocking load_verify_locations call in event loop
ssl_context = create_ssl_context()

class NHCMQTTClient():
@staticmethod
def create(username=None, password=None):
client = mqtt.Client(client_id="homeassistant-" + str(uuid.uuid1()), protocol=MQTT_PROTOCOL,
transport=MQTT_TRANSPORT)
client.enable_logger(_LOGGER)
if username != None or password != None:
client.username_pw_set(username, password)
client.tls_set_context(ssl_context)
return client