Skip to content

Commit

Permalink
Version 0.9.8b
Browse files Browse the repository at this point in the history
  • Loading branch information
bergdahl committed Jun 28, 2024
1 parent 334e868 commit 2523443
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 50 deletions.
133 changes: 85 additions & 48 deletions custom_components/growcube/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,28 @@
from typing import Optional, List, Tuple

from growcube_client import GrowcubeClient, GrowcubeReport, Channel, WateringMode
from growcube_client import (WaterStateGrowcubeReport,
DeviceVersionGrowcubeReport,
MoistureHumidityStateGrowcubeReport,
PumpOpenGrowcubeReport,
PumpCloseGrowcubeReport,
CheckSensorGrowcubeReport,
CheckPumpBlockedGrowcubeReport,
CheckSensorNotConnectedGrowcubeReport,
CheckSensorLockGrowcubeReport,
LockStateGrowcubeReport,
CheckOutletLockGrowcubeReport)
from growcube_client import (
WaterStateGrowcubeReport,
DeviceVersionGrowcubeReport,
MoistureHumidityStateGrowcubeReport,
PumpOpenGrowcubeReport,
PumpCloseGrowcubeReport,
CheckSensorGrowcubeReport,
CheckOutletBlockedGrowcubeReport,
CheckSensorNotConnectedGrowcubeReport,
LockStateGrowcubeReport,
CheckOutletLockedGrowcubeReport,
)
from growcube_client import WateringModeCommand, SyncTimeCommand
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.const import STATE_UNAVAILABLE, STATE_OK, STATE_PROBLEM, STATE_LOCKED, STATE_OPEN, STATE_CLOSED
from homeassistant.const import (
STATE_UNAVAILABLE,
STATE_OK,
STATE_PROBLEM,
STATE_LOCKED,
STATE_OPEN,
STATE_CLOSED,
)
import logging

from homeassistant.helpers.device_registry import DeviceInfo
Expand Down Expand Up @@ -52,9 +60,9 @@ def __init__(self, host: str):

class GrowcubeDataCoordinator(DataUpdateCoordinator):
def __init__(self, host: str, hass: HomeAssistant):
self.client = GrowcubeClient(host, self.handle_report,
self.on_connected,
self.on_disconnected)
self.client = GrowcubeClient(
host, self.handle_report, self.on_connected, self.on_disconnected
)
super().__init__(hass, _LOGGER, name=DOMAIN)
self.entities = []
self.device_id = None
Expand All @@ -68,7 +76,7 @@ def set_device_id(self, device_id: str) -> None:
"identifiers": {(DOMAIN, self.data.device_id)},
"manufacturer": "Elecrow",
"model": "Growcube",
"sw_version": self.data.version
"sw_version": self.data.version,
}

async def _async_update_data(self):
Expand All @@ -90,7 +98,7 @@ async def connect(self) -> Tuple[bool, str]:

@staticmethod
async def get_device_id(host: str) -> tuple[bool, str]:
""" This is used in the config flow to check for a valid device """
"""This is used in the config flow to check for a valid device"""
device_id = ""

def _handle_device_id_report(report: GrowcubeReport):
Expand All @@ -113,16 +121,19 @@ async def _check_device_id_assigned():
client.disconnect()
except asyncio.TimeoutError:
client.disconnect()
return False, 'Timed out waiting for device ID'
return False, "Timed out waiting for device ID"

return True, device_id

def on_connected(self, host: str) -> None:
_LOGGER.debug(f"Connection to {host} established")

def on_disconnected(self, host: str) -> None:
_LOGGER.debug(f"{self.data.device_id}: Connection to {host} lost")
self.hass.states.async_set(DOMAIN + '.' + self.data.device_id, STATE_UNAVAILABLE)
_LOGGER.debug(f"Connection to {host} lost")
if self.data.device_id is not None:
self.hass.states.async_set(
DOMAIN + "." + self.data.device_id, STATE_UNAVAILABLE
)

def disconnect(self) -> None:
"""Disconnect from the Growcube device."""
Expand All @@ -132,7 +143,9 @@ def handle_report(self, report: GrowcubeReport):
"""Handle a report from the Growcube."""
# 24 - RepDeviceVersion
if isinstance(report, DeviceVersionGrowcubeReport):
_LOGGER.debug(f"Device device_id: {report.device_id}, version {report.version}")
_LOGGER.debug(
f"Device device_id: {report.device_id}, version {report.version}"
)
self.data.version = report.version
self.set_device_id(report.device_id)

Expand All @@ -143,11 +156,13 @@ def handle_report(self, report: GrowcubeReport):

# 21 - RepSTHSate
elif isinstance(report, MoistureHumidityStateGrowcubeReport):
_LOGGER.debug(f"{self.data.device_id}: Sensor reading, channel %s, humidity %s, temperature %s, moisture %s",
report.channel,
report.humidity,
report.temperature,
report.moisture)
_LOGGER.debug(
f"{self.data.device_id}: Sensor reading, channel %s, humidity %s, temperature %s, moisture %s",
report.channel,
report.humidity,
report.temperature,
report.moisture,
)
self.data.humidity = report.humidity
self.data.temperature = report.temperature
self.data.moisture[report.channel.value] = report.moisture
Expand All @@ -159,22 +174,30 @@ def handle_report(self, report: GrowcubeReport):

# 27 - RepPumpClose
elif isinstance(report, PumpCloseGrowcubeReport):
_LOGGER.debug(f"{self.data.device_id}: Pump closed, channel {report.channel}")
_LOGGER.debug(
f"{self.data.device_id}: Pump closed, channel {report.channel}"
)
self.data.pump_open[report.channel.value] = False

# 28 - RepCheckSenSorNotConnected
elif isinstance(report, CheckSensorGrowcubeReport):
_LOGGER.debug(f"{self.data.device_id}: Sensor abnormal, channel {report.channel}")
_LOGGER.debug(
f"{self.data.device_id}: Sensor abnormal, channel {report.channel}"
)
self.data.sensor_abnormal[report.channel.value] = True

# 29 - Pump channel blocked
elif isinstance(report, CheckSensorLockGrowcubeReport):
_LOGGER.debug(f"{self.data.device_id}: Pump blocked, channel {report.channel}")
elif isinstance(report, CheckOutletBlockedGrowcubeReport):
_LOGGER.debug(
f"{self.data.device_id}: Outlet blocked, channel {report.channel}"
)
self.data.outlet_blocked_state[report.channel.value] = True

# 30 - RepCheckSenSorNotConnect
elif isinstance(report, CheckSensorNotConnectedGrowcubeReport):
_LOGGER.debug(f"{self.data.device_id}: Check sensor, channel {report.channel}")
_LOGGER.debug(
f"{self.data.device_id}: Check sensor, channel {report.channel}"
)
self.data.sensor_disconnected[report.channel.value] = True
# self.moisture_sensors[report.channel.value].update(None)

Expand All @@ -184,18 +207,20 @@ def handle_report(self, report: GrowcubeReport):
self.data.device_lock_state = report.lock_state

# 34 - ReqCheckSenSorLock
elif isinstance(report, CheckOutletLockGrowcubeReport):
_LOGGER.debug(f"{self.data.device_id}: Check outlet, channel {report.channel}")
elif isinstance(report, CheckOutletLockedGrowcubeReport):
_LOGGER.debug(
f"{self.data.device_id}: Check outlet, channel {report.channel}"
)
self.data.outlet_locked_state[report.channel.value] = True

async def water_plant(self, channel: int) -> None:
await self.client.water_plant(Channel(channel), 5)

async def handle_water_plant(self, call: ServiceCall):
# Validate channel
channel_str = call.data.get('channel')
duration_str = call.data.get('duration')
channel_names = ['A', 'B', 'C', 'D']
channel_str = call.data.get("channel")
duration_str = call.data.get("duration")
channel_names = ["A", "B", "C", "D"]

# Validate data
if channel_str not in channel_names:
Expand All @@ -209,7 +234,9 @@ async def handle_water_plant(self, call: ServiceCall):
return

if duration < 1 or duration > 60:
_LOGGER.error("Invalid duration '%s' for water_plant, should be 1-60", duration)
_LOGGER.error(
"Invalid duration '%s' for water_plant, should be 1-60", duration
)
return

channel = Channel(channel_names.index(channel_str))
Expand All @@ -218,30 +245,40 @@ async def handle_water_plant(self, call: ServiceCall):
await self.client.water_plant(channel, duration)

async def handle_set_watering_mode(self, call: ServiceCall):
channel_str = call.data.get('channel')
min_value = call.data.get('min_value')
max_value = call.data.get('max_value')
channel_names = ['A', 'B', 'C', 'D']
# Set watering mode
channel_str = call.data.get("channel")
min_value = call.data.get("min_value")
max_value = call.data.get("max_value")
channel_names = ["A", "B", "C", "D"]

# Validate data
if channel_str not in channel_names:
_LOGGER.error("Invalid channel specified for set_watering_mode: %s", channel_str)
_LOGGER.error(
"Invalid channel specified for set_watering_mode: %i", channel_str
)
return

if min_value <= 0 or min_value > 100:
_LOGGER.error("Invalid value specified for min_value: %s", min_value_str)
_LOGGER.error("Invalid value specified for min_value: %i", min_value)
return

if max_value <=0 or max_value > 100:
_LOGGER.error("Invalid value specified for max_value: %s", max_value_str)
if max_value <= 0 or max_value > 100:
_LOGGER.error("Invalid value specified for max_value: %i", max_value)
return

if max_value <= min_value:
_LOGGER.error("Invalid values specified, max_value must be bigger than min_value")
_LOGGER.error(
"Invalid values specified, max_value must be bigger than min_value"
)
return

channel = Channel(channel_names.index(channel_str))
command = WateringModeCommand(channel, WateringMode.Smart, min_value, max_value)

_LOGGER.debug("Service set_watering_mode called, %s, %i, %i", channel_str, min_value, max_value)
self.client.send_command(command)
_LOGGER.debug(
"Service set_watering_mode called, %s, %i, %i",
channel_str,
min_value,
max_value,
)
self.client.send_command(command)
4 changes: 2 additions & 2 deletions custom_components/growcube/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"issue_tracker": "https://github.com/jonnybergdahl/homeassistant_growcube/issues",
"iot_class": "local_push",
"requirements": [
"growcube-client==1.0.16"
"growcube-client==1.1.0"
],
"version": "0.9.7"
"version": "0.9.8b"
}

0 comments on commit 2523443

Please sign in to comment.