Skip to content

Commit

Permalink
Adding all the switches and sensors (channels) to the system.
Browse files Browse the repository at this point in the history
  • Loading branch information
zachi40 committed Jun 16, 2024
1 parent 29c9d18 commit 54145df
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 54 deletions.
89 changes: 60 additions & 29 deletions custom_components/mycodo_app/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,32 +35,39 @@ async def async_setup_entry(hass, config_entry, async_add_entities):

try:
# Attempt to extract necessary measurement details
device_measurements = details["device measurements"][0]
unit = device_measurements.get("unit", "")
device_class = device_measurements["measurement"]
for device in details["device measurements"]:
# device_measurements = details["device measurements"][0]
unit = device.get("unit", "")
device_class = device.get("measurement", "")

data = await hass.async_add_executor_job(
mycodo_client.get_sensor_data, sensor["unique_id"], unit
)
if data:
state = data.get("value")
if state is not None:
state = "{:.2f}".format(float(state))
else:
_LOGGER.error(
f"Failed to update sensor ID {sensor["unique_id"]} sensor"
)
channel = device.get("channel", "")

sensor_entities.append(
MycodoSensor(
mycodo_client,
sensor["name"],
sensor["unique_id"],
unit,
device_class,
state,
data = await hass.async_add_executor_job(
mycodo_client.get_sensor_data,
device.get("device_id"),
device.get("unique_id"),
)
if data:
state = data[1]
if state is not None:
state = "{:.2f}".format(float(state))
else:
_LOGGER.error(
f"Failed to update sensor ID {sensor["unique_id"]} sensor"
)

sensor_entities.append(
MycodoSensor(
mycodo_client,
sensor["name"],
device.get("unique_id"),
unit,
device_class,
channel,
device.get("device_id"),
state,
)
)
)
except (IndexError, KeyError, TypeError) as e:
_LOGGER.error(f"Error processing sensor {sensor['name']} details: {e}")
continue
Expand All @@ -72,16 +79,25 @@ class MycodoSensor(Entity):
"""Representation of a Sensor from Mycodo."""

def __init__(
self, mycodo_client, name, unique_id, unit_of_measurement, device_class, state
self,
mycodo_client,
name,
unique_id,
unit_of_measurement,
device_class,
channel,
device_id,
state,
):
"""Initialize the sensor."""
self.mycodo_client = mycodo_client
self._name = f"Mycodo {name}"
self._name = f"Mycodo {name} {device_class}"
self._unique_id = unique_id
self._unit_of_measurement = unit_of_measurement
self._unit = unit_of_measurement
self._channel = channel
self._device_class = device_class

self._device_id = device_id
self._state = state

@property
Expand Down Expand Up @@ -109,7 +125,12 @@ def unit_of_measurement(self):
return TEMP_FAHRENHEIT
elif unit == "K":
return TEMP_KELVIN
return unit
elif unit == "percent":
return "%"
elif unit == "m_s":
return "m/s"
else:
return unit

@property
def unit(self):
Expand All @@ -121,13 +142,23 @@ def device_class(self):
"""Return the device class of the sensor."""
return self._device_class

@property
def channel(self):
"""Return the device channel of the sensor."""
return self._channel

@property
def channel(self):
"""Return the device_id of the sensor."""
return self._device_id

async def async_update(self):
"""Fetch new state data for the sensor."""
data = await self.hass.async_add_executor_job(
self.mycodo_client.get_sensor_data, self._unique_id, self._unit
self.mycodo_client.get_sensor_data, self._device_id, self._unique_id
)
if data:
self._state = data.get("value")
self._state = data[1]
if self._state is not None:
self._state = "{:.2f}".format(float(self._state))
else:
Expand Down
56 changes: 39 additions & 17 deletions custom_components/mycodo_app/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,50 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up the Mycodo switches."""
mycodo_client = hass.data[DOMAIN]["client"]
switches = await hass.async_add_executor_job(mycodo_client.get_switches)
# switches_output = self.utils.mycodo_send("/api/outputs/")
# switches=switches_output.get('output devices', [])

if not switches or "output devices" not in switches:
_LOGGER.error("Failed to fetch switches from Mycodo.")
return
switches_states = switches.get("output states", [])

switch_entities = []
output_devices = switches.get("output devices", []) or []
output_devices = switches.get("output devices", [])
for switch in output_devices:
state = switches_states.get(switch["unique_id"])
switch_entities.append(
MycodoSwitch(
mycodo_client,
switch["name"],
switch["unique_id"],
state["0"] == "on",
)
# get all channel from switch
switch_options = await hass.async_add_executor_job(
mycodo_client.get_switch, switch["unique_id"]
)
for output in switch_options.get("output device channels", []):
channel = output.get("channel")
output_id = output.get("output_id")
unique_id = output.get("unique_id")
name = f'{switch_options["output device"].get("name")} {output.get("name")}'
state = switch_options["output device channel states"].get(str(channel))
if state is None:
continue
switch_entities.append(
MycodoSwitch(
mycodo_client,
name,
unique_id,
output_id,
channel,
state == "on",
)
)

async_add_entities(switch_entities)


class MycodoSwitch(SwitchEntity):
"""Representation of a Mycodo Switch."""

def __init__(self, mycodo_client, name, unique_id, is_on):
def __init__(self, mycodo_client, name, unique_id, output_id, channel, is_on):
"""Initialize the switch."""
self._client = mycodo_client
self._name = f"Mycodo {name}"
self._unique_id = unique_id
self._output_id = output_id
self._channel = channel
self._state = is_on

@property
Expand All @@ -53,6 +65,16 @@ def unique_id(self):
"""Return the unique ID of the switch."""
return self._unique_id

@property
def output_id(self):
"""Return the output ID of the switch."""
return self._output_id

@property
def channel(self):
"""Return the channel of the switch."""
return self._channel

@property
def is_on(self):
"""Return true if the switch is on."""
Expand All @@ -61,7 +83,7 @@ def is_on(self):
async def async_turn_on(self, **kwargs):
"""Turn the switch on."""
result = await self.hass.async_add_executor_job(
self._client.set_switch_state, self._unique_id, True
self._client.set_switch_state, self._output_id, self._channel, True
)
if result and "Success" in result.get("message", ""):
self._state = True
Expand All @@ -72,7 +94,7 @@ async def async_turn_on(self, **kwargs):
async def async_turn_off(self, **kwargs):
"""Turn the switch off."""
result = await self.hass.async_add_executor_job(
self._client.set_switch_state, self._unique_id, False
self._client.set_switch_state, self._output_id, self._channel, False
)
if result and "Success" in result.get("message", ""):
self._state = False
Expand All @@ -83,10 +105,10 @@ async def async_turn_off(self, **kwargs):
async def async_update(self):
"""Fetch new state data for the switch."""
result = await self.hass.async_add_executor_job(
self._client.get_switch_state, self._unique_id
self._client.get_switch, self._output_id
)
if result:
switch_state = result.get("output device channel states", [])
self._state = switch_state.get("0", "off") == "on"
self._state = switch_state.get(str(self._channel), "off") == "on"
else:
_LOGGER.error(f"Failed to update {self._name}")
23 changes: 15 additions & 8 deletions custom_components/mycodo_app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ def make_request(self, endpoint, method="get", data=None):

if response.status_code == 200:
return response.json()
elif response.status_code == 500:
return None
else:
_LOGGER.error(
f"HTTP request to {url} failed with status {response.status_code}: {response.text}"
Expand All @@ -53,31 +55,36 @@ def get_sensor_details(self, sensor_id):
"""Get detailed information for a specific sensor from Mycodo."""
return self.make_request(f"api/inputs/{sensor_id}")

def get_sensor_data(self, sensor_id, unit):
def get_sensor_data(self, sensor_device_id, unique_id):
NOT_value = True
count = 0
"""Get the latest data for a specific sensor from Mycodo."""
respose = self.make_request(f"api/measurements/last/{sensor_id}/{unit}/0/30")
respose = self.make_request(f"last/{sensor_device_id}/input/{unique_id}/30")
while NOT_value:
if respose.get("value") == None:
random_number = random.randint(10, 60)
if count == 3:
return None
# 204 -noc data
elif respose is None:
random_number = random.randint(30, 60)
respose = self.make_request(
f"api/measurements/last/{sensor_id}/{unit}/0/{random_number}"
f"last/{sensor_device_id}/input/{unique_id}/{random_number}"
)
count += 1
else:
return respose

def get_switches(self):
"""Get switches from Mycodo."""
return self.make_request("api/outputs")

def get_switch_state(self, switch_id):
def get_switch(self, switch_id):
"""Get the current state of a switch."""
return self.make_request(f"api/outputs/{switch_id}")

def set_switch_state(self, switch_id, state):
def set_switch_state(self, switch_id, channel, state):
"""Set the state of a switch."""
return self.make_request(
endpoint=f"api/outputs/{switch_id}",
method="post",
data={"channel": 0, "state": state},
data={"channel": channel, "state": state},
)

0 comments on commit 54145df

Please sign in to comment.