Skip to content

Commit

Permalink
Bug fixes after first integration run
Browse files Browse the repository at this point in the history
  • Loading branch information
Jean-Marc Collin committed Jun 13, 2023
1 parent 602ab70 commit 8a6dadf
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 35 deletions.
9 changes: 7 additions & 2 deletions custom_components/solar_optimizer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Initialisation du package de l'intégration HACS Tuto"""
import logging

from homeassistant.const import EVENT_HOMEASSISTANT_START
from homeassistant.core import HomeAssistant
from homeassistant.config_entries import ConfigEntry
from homeassistant.helpers.typing import ConfigType
Expand Down Expand Up @@ -33,11 +34,15 @@ async def async_setup(
hass, solar_optimizer_config
)

await coordinator.async_config_entry_first_refresh()

await async_setup_entry_sensor(hass)
await async_setup_entry_binary_sensor(hass)

# refresh data on startup
async def _internal_startup(*_):
await coordinator.async_config_entry_first_refresh()

hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, _internal_startup)

# Return boolean to indicate that initialization was successful.
return True

Expand Down
2 changes: 2 additions & 0 deletions custom_components/solar_optimizer/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ def update_custom_attributes(self, device):
"can_change_power": device.can_change_power,
"current_power": device.current_power,
"requested_power": device.requested_power,
"duration_sec": device.duration_sec,
"duration_power_sec": device.duration_power_sec,
"next_date_available": device.next_date_available.astimezone(
current_tz
).isoformat(),
Expand Down
33 changes: 13 additions & 20 deletions custom_components/solar_optimizer/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,29 +92,22 @@ async def _async_update_data(self):
for _, device in enumerate(self._devices):
# Initialize current power if not set and is active
if device.is_active and device.current_power == 0:
device.init_power(
device.power_max if device.can_change_power else device.power_min
)
power = device.power_max
if device.can_change_power:
state = self.hass.states.get(device.power_entity_id)
if power is not None:
power = round(
float(state.state) * device.convert_power_divide_factor
)
else:
power = device.power_min
device.reset_next_date_available()
device.reset_next_date_available_power()

device.init_power(power)
if not device.is_active:
device.init_power(0)

# calculate a device_states (not used)
# device_states[device.name] = {
# "name": device.name,
# "is_active": device.is_active,
# "is_usable": device.is_usable,
# "is_waiting": device.is_waiting,
# "current_power": device.current_power,
# "requested_power": device.requested_power,
# }
# _LOGGER.debug(
# "Evaluation of %s, device_active: %s, device_usable: %s",
# device.name,
# device.is_active,
# device.is_usable,
# )
# calculated_data["device_states"] = device_states

# Add a power_consumption and power_production
calculated_data["power_production"] = get_safe_float(
self.hass, self._power_production_entity_id
Expand Down
26 changes: 22 additions & 4 deletions custom_components/solar_optimizer/managed_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,10 @@ async def _apply_action(self, action_type: str, requested_power=None):
entity_id = self._entity_id
if action_type == ACTION_ACTIVATE:
method = self._activation_service
self.reset_next_date_available()
elif action_type == ACTION_DEACTIVATE:
method = self._deactivation_service
self.reset_next_date_available()
elif action_type == ACTION_CHANGE_POWER:
assert (
self._can_change_power
Expand Down Expand Up @@ -221,8 +223,6 @@ async def _apply_action(self, action_type: str, requested_power=None):
)

self._current_power = self._requested_power
if action_type == ACTION_ACTIVATE or action_type == ACTION_DEACTIVATE:
self.reset_next_date_available()

async def activate(self, requested_power=None):
"""Use this method to activate this ManagedDevice"""
Expand Down Expand Up @@ -258,6 +258,9 @@ def reset_next_date_available_power(self):

def init_power(self, power: int):
"""Initialise current_power and requested_power to the given value"""
_LOGGER.debug(
"Initializing power for entity '%s' with %s value", self._name, power
)
self._requested_power = self._current_power = power

@property
Expand Down Expand Up @@ -328,11 +331,21 @@ def duration_sec(self) -> int:
"""The duration a device is not available after a change of the managed device"""
return self._duration_sec

@property
def duration_power_sec(self) -> int:
"""The duration a device is not available after a change of the managed device for power change"""
return self._duration_power_sec

@property
def entity_id(self) -> str:
"""The entity_id of the device"""
return self._entity_id

@property
def power_entity_id(self) -> str:
"""The entity_id of the device which gives the current power"""
return self._power_entity_id

@property
def current_power(self) -> int:
"""The current_power of the device"""
Expand All @@ -350,10 +363,15 @@ def can_change_power(self) -> bool:

@property
def next_date_available(self) -> datetime:
"""true is the device can change its power"""
"""returns the next available date for state change"""
return self._next_date_available

@property
def next_date_available_power(self) -> datetime:
"""true is the device can change its power"""
"""return the next available date for power change"""
return self._next_date_available_power

@property
def convert_power_divide_factor(self) -> int:
"""return"""
return self._convert_power_divide_factor
16 changes: 7 additions & 9 deletions custom_components/solar_optimizer/simulated_annealing_algo.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,14 @@ def recuit_simule(
# Calculer les objectifs pour la solution actuelle et le voisin
objectif_voisin = self.calculer_objectif(voisin)
if DEBUG:
_LOGGER.debug("Objecttif voisin : %2.f", objectif_voisin)
_LOGGER.debug("Objectif voisin : %2.f", objectif_voisin)

# Accepter le voisin si son objectif est meilleur ou si la consommation totale n'excède pas la production solaire
if objectif_voisin < objectif_actuel:
if DEBUG:
_LOGGER.debug("---> On garde l'objectif voisin")
_LOGGER.debug("---> On garde l'objectif voisin")
solution_actuelle = voisin
if objectif_voisin < self.calculer_objectif(meilleure_solution):
if DEBUG:
_LOGGER.debug("---> C'est la meilleure jusque là")
_LOGGER.debug("---> C'est la meilleure jusque là")
meilleure_solution = voisin
meilleure_objectif = objectif_voisin
else:
Expand Down Expand Up @@ -312,7 +310,7 @@ def permuter_equipement(self, solution):
requested_power > 0
), "Requested_power should be > 0 because is_waiting is True"

if state and can_change_power and not is_waiting:
elif state and can_change_power and not is_waiting:
# change power and accept switching off
requested_power = self.calculer_new_power(
current_power, power_step, power_min, power_max, True
Expand All @@ -322,17 +320,17 @@ def permuter_equipement(self, solution):
eqt["state"] = False
requested_power = 0

if not state and not is_waiting:
elif not state and not is_waiting:
# Allumage
eqt["state"] = not state
requested_power = power_min

if state and not is_waiting:
elif state and not is_waiting:
# Extinction
eqt["state"] = not state
requested_power = 0

if "requested_power" not in locals():
elif "requested_power" not in locals():
_LOGGER.error("We should not be there. eqt=%s", eqt)
assert False, "Requested power n'a pas été calculé. Ce n'est pas normal"

Expand Down

0 comments on commit 8a6dadf

Please sign in to comment.