Compare commits
2 Commits
8454cc95f5
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 05a910ba80 | |||
| 875e0abd37 |
155
smartobject.py
155
smartobject.py
@@ -1,8 +1,6 @@
|
|||||||
import appdaemon.plugins.hass.hassapi as hass
|
import appdaemon.plugins.hass.hassapi as hass
|
||||||
import pickle
|
import pickle
|
||||||
import os
|
import os
|
||||||
import json
|
|
||||||
import re
|
|
||||||
from virtualsensors import VirtualSensors
|
from virtualsensors import VirtualSensors
|
||||||
from expressionparser import ParsingException
|
from expressionparser import ParsingException
|
||||||
from logger_interface import LoggerInterface
|
from logger_interface import LoggerInterface
|
||||||
@@ -20,8 +18,6 @@ from logger_interface import LoggerInterface
|
|||||||
# - Templates library : shared named-template provider from another app
|
# - Templates library : shared named-template provider from another app
|
||||||
# - Virtual sensors : declarative derived sensors defined in YAML
|
# - Virtual sensors : declarative derived sensors defined in YAML
|
||||||
# - Attributes override : map HA sensor states onto entity attributes
|
# - Attributes override : map HA sensor states onto entity attributes
|
||||||
# - MQTT discovery : entities created via create_entity() are auto-
|
|
||||||
# published as HA MQTT discovery sensors
|
|
||||||
#
|
#
|
||||||
# YAML CONFIGURATION
|
# YAML CONFIGURATION
|
||||||
# ------------------
|
# ------------------
|
||||||
@@ -68,15 +64,6 @@ from logger_interface import LoggerInterface
|
|||||||
# - A HA entity_id → attribute tracks that entity's state live.
|
# - A HA entity_id → attribute tracks that entity's state live.
|
||||||
# - A static value → attribute is set once at startup.
|
# - A static value → attribute is set once at startup.
|
||||||
#
|
#
|
||||||
# mqtt_device_name: <friendly name>
|
|
||||||
# Human-readable device name used in HA MQTT discovery payloads.
|
|
||||||
# Defaults to the AppDaemon app name (self.name) if omitted.
|
|
||||||
# Requires the MQTT integration to be available in HA.
|
|
||||||
# Used by the MQTT discovery feature (see create_entity()).
|
|
||||||
# When you create a new entity with create_entity(), it will be attached to a device through MQTT discovery with this name
|
|
||||||
# and will appear in HA as a child of that device.
|
|
||||||
# Since MQTT keep those entity forever, you might have to clean up some entities with MQTT Explorer if you change some entity names or delete some entities from your app.
|
|
||||||
#
|
|
||||||
# DATASET PERSISTENCE
|
# DATASET PERSISTENCE
|
||||||
# -------------------
|
# -------------------
|
||||||
# Subclasses can store arbitrary data in self.dataset (any pickle-able
|
# Subclasses can store arbitrary data in self.dataset (any pickle-able
|
||||||
@@ -97,8 +84,8 @@ class SmartObject(hass.Hass,LoggerInterface):
|
|||||||
# Public API
|
# Public API
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
# Create (or update) a HA entity and, when MQTT is available, register
|
# Create (or update) a HA entity and tag it with the originating app
|
||||||
# it with HA via MQTT discovery so it appears as a proper device entity.
|
# through the ad_app attribute.
|
||||||
#
|
#
|
||||||
# Parameters
|
# Parameters
|
||||||
# ----------
|
# ----------
|
||||||
@@ -110,43 +97,29 @@ class SmartObject(hass.Hass,LoggerInterface):
|
|||||||
# unit_of_measurement : e.g. "°C", "%", "W"
|
# unit_of_measurement : e.g. "°C", "%", "W"
|
||||||
# device_class : HA sensor device class, e.g. "temperature"
|
# device_class : HA sensor device class, e.g. "temperature"
|
||||||
# state_class : "measurement", "total", "total_increasing"
|
# state_class : "measurement", "total", "total_increasing"
|
||||||
#
|
|
||||||
# The entity's live state is kept in sync with MQTT automatically via
|
|
||||||
# a listen_state subscription set up at registration time.
|
|
||||||
# Returns the AppDaemon entity handle.
|
# Returns the AppDaemon entity handle.
|
||||||
def create_entity(self, entity_id, state=None, attributes=None, name=None, icon=None, unit_of_measurement=None, device_class=None, state_class=None):
|
def create_entity(self, entity_id, state=None, attributes=None, friendly_name=None, icon=None, unit_of_measurement=None, device_class=None, state_class=None):
|
||||||
entity = self.get_entity(entity_id, check_existence=False)
|
entity = self.get_entity(entity_id, check_existence=False)
|
||||||
if self._mqtt_lazy_init() and entity_id not in self._mqtt['entities']:
|
if attributes is not None:
|
||||||
node_id = self._mqtt['node_id']
|
attributes = dict(attributes)
|
||||||
obj = self._sanitize_for_topic(entity_id.split('.')[-1])
|
else:
|
||||||
state_topic = f"appdaemon/{node_id}/{obj}/state"
|
attributes = dict()
|
||||||
availability_topic = f"appdaemon/{node_id}/{obj}/availability"
|
|
||||||
config = {
|
attributes['ad_app'] = self.name
|
||||||
'name': name or entity_id,
|
|
||||||
'unique_id': f"{node_id}_{obj}",
|
if friendly_name is not None: attributes['friendly_name'] = friendly_name
|
||||||
'state_topic': state_topic,
|
if icon is not None: attributes['icon'] = icon
|
||||||
'value_template': '{{ value_json.state }}',
|
if unit_of_measurement is not None: attributes['unit_of_measurement'] = unit_of_measurement
|
||||||
'availability_topic': availability_topic,
|
if device_class is not None: attributes['device_class'] = device_class
|
||||||
'payload_available': 'online',
|
if state_class is not None: attributes['state_class'] = state_class
|
||||||
'payload_not_available': 'offline',
|
|
||||||
'device': self._mqtt['device'],
|
if state is not None:
|
||||||
}
|
entity.set_state(state=state, attributes=attributes)
|
||||||
if icon: config['icon'] = icon
|
else:
|
||||||
if unit_of_measurement: config['unit_of_measurement'] = unit_of_measurement
|
if not entity.exists():
|
||||||
if device_class: config['device_class'] = device_class
|
entity.set_state(state='unknown')
|
||||||
if state_class: config['state_class'] = state_class
|
entity.set_state(attributes=attributes)
|
||||||
self._mqtt_publish(f"homeassistant/sensor/{node_id}/{obj}/config", config, retain=True)
|
|
||||||
self._mqtt_publish(availability_topic, 'online', retain=True)
|
|
||||||
self._mqtt['entities'].add(entity_id)
|
|
||||||
self._mqtt['handles'][entity_id] = self.listen_state(self._mqtt_sync_state, entity_id)
|
|
||||||
if state is not None and attributes is not None:
|
|
||||||
self.set_state(entity_id, state=state, attributes=attributes)
|
|
||||||
elif state is not None:
|
|
||||||
self.set_state(entity_id, state=state)
|
|
||||||
elif attributes is not None:
|
|
||||||
self.set_state(entity_id, attributes=attributes)
|
|
||||||
elif not entity.exists():
|
|
||||||
self.set_state(entity_id, state='unknown')
|
|
||||||
return entity
|
return entity
|
||||||
|
|
||||||
# Override this in a subclass to return a default state string when the
|
# Override this in a subclass to return a default state string when the
|
||||||
@@ -162,82 +135,6 @@ class SmartObject(hass.Hass,LoggerInterface):
|
|||||||
# Called at the end of initialize() after all YAML args are processed.
|
# Called at the end of initialize() after all YAML args are processed.
|
||||||
def on_initialize_smart_object(self): pass
|
def on_initialize_smart_object(self): pass
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
|
||||||
# MQTT Discovery (internal)
|
|
||||||
# ------------------------------------------------------------------
|
|
||||||
# Called lazily on the first create_entity() call. Checks whether the
|
|
||||||
# MQTT publish service is available and, if so, initialises self._mqtt
|
|
||||||
# with the device metadata used in discovery payloads.
|
|
||||||
# Returns True when MQTT is ready, False otherwise (MQTT not installed
|
|
||||||
# or the service is not available).
|
|
||||||
def _mqtt_lazy_init(self):
|
|
||||||
if hasattr(self, '_mqtt'):
|
|
||||||
return self._mqtt is not None
|
|
||||||
self._mqtt = None
|
|
||||||
try:
|
|
||||||
available = any(
|
|
||||||
i.get('domain') == 'mqtt' and i.get('service') == 'publish'
|
|
||||||
for i in self.list_services('global')
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
available = False
|
|
||||||
if not available:
|
|
||||||
return False
|
|
||||||
node_id = self._sanitize_for_topic(self.name)
|
|
||||||
device_name = self.args.get('mqtt_device_name', self.name)
|
|
||||||
self._mqtt = {
|
|
||||||
'node_id': node_id,
|
|
||||||
'device': {
|
|
||||||
'identifiers': [node_id],
|
|
||||||
'name': device_name,
|
|
||||||
'manufacturer': 'AppDaemon',
|
|
||||||
'model': self.__class__.__name__,
|
|
||||||
},
|
|
||||||
'entities': set(),
|
|
||||||
'handles': {},
|
|
||||||
}
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _sanitize_for_topic(self, value):
|
|
||||||
return re.sub(r"[^a-zA-Z0-9_]+", "_", str(value)).strip("_").lower()
|
|
||||||
|
|
||||||
# Serialize payload to JSON if it is not already a string, then call
|
|
||||||
# the mqtt/publish service. retain=True is used for state and config
|
|
||||||
# topics so HA picks them up immediately after a broker restart.
|
|
||||||
def _mqtt_publish(self, topic, payload, retain=False):
|
|
||||||
if not isinstance(payload, str):
|
|
||||||
payload = json.dumps(payload)
|
|
||||||
self.call_service('mqtt/publish', topic=topic, payload=payload, retain=retain)
|
|
||||||
|
|
||||||
# listen_state callback — re-publishes the full state + attributes of
|
|
||||||
# entity_id to its MQTT state topic whenever the HA state changes.
|
|
||||||
def _mqtt_sync_state(self, entity_id, attribute, old, new, kwargs):
|
|
||||||
if not getattr(self, '_mqtt', None) or entity_id not in self._mqtt['entities']:
|
|
||||||
return
|
|
||||||
state_data = self.get_state(entity_id, attribute='all') or {}
|
|
||||||
payload = {'state': state_data.get('state')}
|
|
||||||
payload.update(state_data.get('attributes', {}))
|
|
||||||
node_id = self._mqtt['node_id']
|
|
||||||
obj = self._sanitize_for_topic(entity_id.split('.')[-1])
|
|
||||||
self._mqtt_publish(f"appdaemon/{node_id}/{obj}/state", payload, retain=True)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Called from terminate(). Publishes "offline" availability for every
|
|
||||||
# registered entity so HA marks them as unavailable, then cancels all
|
|
||||||
# listen_state subscriptions created during create_entity().
|
|
||||||
def _mqtt_terminate(self):
|
|
||||||
if not getattr(self, '_mqtt', None):
|
|
||||||
return
|
|
||||||
for entity_id in self._mqtt['entities']:
|
|
||||||
node_id = self._mqtt['node_id']
|
|
||||||
obj = self._sanitize_for_topic(entity_id.split('.')[-1])
|
|
||||||
try: self._mqtt_publish(f"appdaemon/{node_id}/{obj}/availability", 'offline', retain=True)
|
|
||||||
except Exception: pass
|
|
||||||
for handle in self._mqtt['handles'].values():
|
|
||||||
try: self.cancel_listen_state(handle, silent=True)
|
|
||||||
except Exception: pass
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# Dataset persistence helpers
|
# Dataset persistence helpers
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
@@ -325,7 +222,7 @@ class SmartObject(hass.Hass,LoggerInterface):
|
|||||||
|
|
||||||
# virtual_sensors: {...} → create derived sensors from YAML spec
|
# virtual_sensors: {...} → create derived sensors from YAML spec
|
||||||
if 'virtual_sensors' in self.args:
|
if 'virtual_sensors' in self.args:
|
||||||
self.virtual_sensors = VirtualSensors(ad_api = self.get_ad_api(),logger_interface = self,super_entity_id = self.entity_id,yaml_block = self.args['virtual_sensors'],templates_library = self.templates_library,constants = self.constants)
|
self.virtual_sensors = VirtualSensors(ad_api = self,logger_interface = self,super_entity_id = self.entity_id,yaml_block = self.args['virtual_sensors'],templates_library = self.templates_library,constants = self.constants,app_name = self.name)
|
||||||
|
|
||||||
# attributes_override: {attr: entity_id | static_value, ...}
|
# attributes_override: {attr: entity_id | static_value, ...}
|
||||||
# Each attribute either mirrors a live HA sensor or holds a
|
# Each attribute either mirrors a live HA sensor or holds a
|
||||||
@@ -362,12 +259,10 @@ class SmartObject(hass.Hass,LoggerInterface):
|
|||||||
except ParsingException as e: self.log_error(str(e),stop_app = True)
|
except ParsingException as e: self.log_error(str(e),stop_app = True)
|
||||||
|
|
||||||
|
|
||||||
# AppDaemon shutdown hook. Persists self.dataset to disk (if set),
|
# AppDaemon shutdown hook. Persists self.dataset to disk (if set).
|
||||||
# publishes MQTT offline availability, and cancels all state listeners.
|
|
||||||
def terminate(self):
|
def terminate(self):
|
||||||
self.event_dispatchers = None
|
self.event_dispatchers = None
|
||||||
self.virtual_sensors = None
|
self.virtual_sensors = None
|
||||||
self._mqtt_terminate()
|
|
||||||
try: has_dataset = self.dataset != None
|
try: has_dataset = self.dataset != None
|
||||||
except AttributeError: has_dataset = False
|
except AttributeError: has_dataset = False
|
||||||
if has_dataset:
|
if has_dataset:
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import time
|
|||||||
from logger_interface import LoggerInterface
|
from logger_interface import LoggerInterface
|
||||||
|
|
||||||
class VirtualSensorBase:
|
class VirtualSensorBase:
|
||||||
def __init__(self,ad_api,logger_interface, virtual_sensor_name = None, sensor_name = None,super_entity_id = None, yaml_block = None,templates_library = None, constants = None,self_initialize = False):
|
def __init__(self,ad_api,logger_interface, virtual_sensor_name = None, sensor_name = None,super_entity_id = None, yaml_block = None,templates_library = None, constants = None, app_name = None,self_initialize = False):
|
||||||
self.ad_api = ad_api
|
self.ad_api = ad_api
|
||||||
self.logger_interface = logger_interface
|
self.logger_interface = logger_interface
|
||||||
|
|
||||||
@@ -32,6 +32,9 @@ class VirtualSensorBase:
|
|||||||
try: self.attributes = self.yaml_block['attributes']
|
try: self.attributes = self.yaml_block['attributes']
|
||||||
except (TypeError,KeyError): self.attributes = dict()
|
except (TypeError,KeyError): self.attributes = dict()
|
||||||
|
|
||||||
|
if app_name:
|
||||||
|
self.attributes['ad_app'] = app_name
|
||||||
|
|
||||||
if constants:
|
if constants:
|
||||||
self.constants = dict(constants) # we don't want to modify the parent dict
|
self.constants = dict(constants) # we don't want to modify the parent dict
|
||||||
self.constants['self'] = self.sensor_name # we need to set self by ourself
|
self.constants['self'] = self.sensor_name # we need to set self by ourself
|
||||||
@@ -554,7 +557,7 @@ class ValueSensor(VirtualSensorBase):
|
|||||||
|
|
||||||
class VirtualSensors():
|
class VirtualSensors():
|
||||||
|
|
||||||
def __init__(self, ad_api = None,logger_interface = None, super_entity_id = None, yaml_block = None ,args_to_ignore_in_validation = [], constants = None, templates_library = None):
|
def __init__(self, ad_api = None,logger_interface = None, super_entity_id = None, yaml_block = None ,args_to_ignore_in_validation = [], constants = None, templates_library = None, app_name = None):
|
||||||
assert ad_api
|
assert ad_api
|
||||||
assert yaml_block
|
assert yaml_block
|
||||||
assert logger_interface
|
assert logger_interface
|
||||||
@@ -572,20 +575,20 @@ class VirtualSensors():
|
|||||||
|
|
||||||
averagers = parser.parse_args('averagers',{})
|
averagers = parser.parse_args('averagers',{})
|
||||||
for averager in averagers:
|
for averager in averagers:
|
||||||
self.virtual_sensors[f"sensor.{averager}"] = Averager(self.ad_api,self.logger_interface,averager,super_entity_id = super_entity_id,yaml_block = yaml_block['averagers'][averager],constants = constants, templates_library = templates_library)
|
self.virtual_sensors[f"sensor.{averager}"] = Averager(self.ad_api,self.logger_interface,averager,super_entity_id = super_entity_id,yaml_block = yaml_block['averagers'][averager],constants = constants, templates_library = templates_library,app_name = app_name)
|
||||||
|
|
||||||
continuous_conditions = parser.parse_args('continuous_conditions',{})
|
continuous_conditions = parser.parse_args('continuous_conditions',{})
|
||||||
for continuous_condition in continuous_conditions:
|
for continuous_condition in continuous_conditions:
|
||||||
self.virtual_sensors[f"binary_sensor.{continuous_condition}"] = ContinuousCondition(self.ad_api,self.logger_interface,continuous_condition,super_entity_id = super_entity_id,yaml_block = yaml_block['continuous_conditions'][continuous_condition],templates_library = templates_library)
|
self.virtual_sensors[f"binary_sensor.{continuous_condition}"] = ContinuousCondition(self.ad_api,self.logger_interface,continuous_condition,super_entity_id = super_entity_id,yaml_block = yaml_block['continuous_conditions'][continuous_condition],templates_library = templates_library,app_name = app_name)
|
||||||
|
|
||||||
binary_sensors = parser.parse_args('binary_sensors',{})
|
binary_sensors = parser.parse_args('binary_sensors',{})
|
||||||
for binary_sensor in binary_sensors:
|
for binary_sensor in binary_sensors:
|
||||||
#self.logger_interface.log_info(f"Creating Binary Sensor: binary_sensor = {binary_sensor}, super_entity_id = {super_entity_id}, yaml_block = {yaml_block['binary_sensors']}")
|
#self.logger_interface.log_info(f"Creating Binary Sensor: binary_sensor = {binary_sensor}, super_entity_id = {super_entity_id}, yaml_block = {yaml_block['binary_sensors']}")
|
||||||
self.virtual_sensors[f"binary_sensor.{binary_sensor}"] = BinarySensor(self.ad_api,self.logger_interface,binary_sensor,super_entity_id = super_entity_id,yaml_block = yaml_block['binary_sensors'][binary_sensor],constants = constants,templates_library = templates_library)
|
self.virtual_sensors[f"binary_sensor.{binary_sensor}"] = BinarySensor(self.ad_api,self.logger_interface,binary_sensor,super_entity_id = super_entity_id,yaml_block = yaml_block['binary_sensors'][binary_sensor],constants = constants,templates_library = templates_library,app_name = app_name)
|
||||||
|
|
||||||
value_selectors = parser.parse_args('value_selectors',{})
|
value_selectors = parser.parse_args('value_selectors',{})
|
||||||
for value_selector in value_selectors:
|
for value_selector in value_selectors:
|
||||||
self.virtual_sensors[f"sensor.{value_selector}"] = ValueSelector(self.ad_api,self.logger_interface,value_selector,super_entity_id = super_entity_id,yaml_block = yaml_block['value_selectors'][value_selector],constants = constants,templates_library = templates_library)
|
self.virtual_sensors[f"sensor.{value_selector}"] = ValueSelector(self.ad_api,self.logger_interface,value_selector,super_entity_id = super_entity_id,yaml_block = yaml_block['value_selectors'][value_selector],constants = constants,templates_library = templates_library,app_name = app_name)
|
||||||
|
|
||||||
sensors = parser.parse_args('sensors',{})
|
sensors = parser.parse_args('sensors',{})
|
||||||
for sensor in sensors:
|
for sensor in sensors:
|
||||||
@@ -594,22 +597,20 @@ class VirtualSensors():
|
|||||||
self.logger_interface.log_error(f"Invalid sensor name {splitted_sensor}")
|
self.logger_interface.log_error(f"Invalid sensor name {splitted_sensor}")
|
||||||
|
|
||||||
if splitted_sensor[0] == 'binary_sensor':
|
if splitted_sensor[0] == 'binary_sensor':
|
||||||
self.virtual_sensors[f"binary_sensor.{splitted_sensor[1]}"] = BinarySensor(self.ad_api,self.logger_interface,splitted_sensor[1],super_entity_id = super_entity_id,yaml_block = yaml_block['sensors'][sensor],constants = constants,templates_library = templates_library)
|
self.virtual_sensors[f"binary_sensor.{splitted_sensor[1]}"] = BinarySensor(self.ad_api,self.logger_interface,splitted_sensor[1],super_entity_id = super_entity_id,yaml_block = yaml_block['sensors'][sensor],constants = constants,templates_library = templates_library,app_name = app_name)
|
||||||
elif splitted_sensor[0] == 'sensor':
|
elif splitted_sensor[0] == 'sensor':
|
||||||
self.virtual_sensors[f"sensor.{splitted_sensor[1]}"] = ValueSensor(self.ad_api,self.logger_interface,splitted_sensor[1],super_entity_id = super_entity_id,yaml_block = yaml_block['sensors'][sensor],constants = constants,templates_library = templates_library)
|
self.virtual_sensors[f"sensor.{splitted_sensor[1]}"] = ValueSensor(self.ad_api,self.logger_interface,splitted_sensor[1],super_entity_id = super_entity_id,yaml_block = yaml_block['sensors'][sensor],constants = constants,templates_library = templates_library,app_name = app_name)
|
||||||
elif splitted_sensor[0] == 'continuous_condition':
|
elif splitted_sensor[0] == 'continuous_condition':
|
||||||
self.virtual_sensors[f"binary_sensor.{splitted_sensor[1]}"] = ContinuousCondition(self.ad_api,self.logger_interface,splitted_sensor[1],super_entity_id = super_entity_id,yaml_block = yaml_block['sensors'][sensor],constants = constants,templates_library = templates_library)
|
self.virtual_sensors[f"binary_sensor.{splitted_sensor[1]}"] = ContinuousCondition(self.ad_api,self.logger_interface,splitted_sensor[1],super_entity_id = super_entity_id,yaml_block = yaml_block['sensors'][sensor],constants = constants,templates_library = templates_library,app_name = app_name)
|
||||||
elif splitted_sensor[0] == 'averager':
|
elif splitted_sensor[0] == 'averager':
|
||||||
self.virtual_sensors[f"sensor.{splitted_sensor[1]}"] = Averager(self.ad_api,self.logger_interface,splitted_sensor[1],super_entity_id = super_entity_id,yaml_block = yaml_block['sensors'][sensor],constants = constants,templates_library = templates_library)
|
self.virtual_sensors[f"sensor.{splitted_sensor[1]}"] = Averager(self.ad_api,self.logger_interface,splitted_sensor[1],super_entity_id = super_entity_id,yaml_block = yaml_block['sensors'][sensor],constants = constants,templates_library = templates_library,app_name = app_name)
|
||||||
elif splitted_sensor[0] == 'value_selector':
|
elif splitted_sensor[0] == 'value_selector':
|
||||||
self.virtual_sensors[f"sensor.{splitted_sensor[1]}"] = ValueSelector(self.ad_api,self.logger_interface,splitted_sensor[1],super_entity_id = super_entity_id,yaml_block = yaml_block['sensors'][sensor],constants = constants,templates_library = templates_library)
|
self.virtual_sensors[f"sensor.{splitted_sensor[1]}"] = ValueSelector(self.ad_api,self.logger_interface,splitted_sensor[1],super_entity_id = super_entity_id,yaml_block = yaml_block['sensors'][sensor],constants = constants,templates_library = templates_library,app_name = app_name)
|
||||||
elif splitted_sensor[0] == 'retain_condition':
|
elif splitted_sensor[0] == 'retain_condition':
|
||||||
self.virtual_sensors[f"binary_sensor.{splitted_sensor[1]}"] = RetainCondition(self.ad_api,self.logger_interface,splitted_sensor[1],super_entity_id = super_entity_id,yaml_block = yaml_block['sensors'][sensor],constants = constants,templates_library = templates_library)
|
self.virtual_sensors[f"binary_sensor.{splitted_sensor[1]}"] = RetainCondition(self.ad_api,self.logger_interface,splitted_sensor[1],super_entity_id = super_entity_id,yaml_block = yaml_block['sensors'][sensor],constants = constants,templates_library = templates_library,app_name = app_name)
|
||||||
else:
|
else:
|
||||||
self.logger_interface.log_error(f"Invalid sensor prefix {splitted_sensor[0]}")
|
self.logger_interface.log_error(f"Invalid sensor prefix {splitted_sensor[0]}")
|
||||||
|
|
||||||
parser.validate_args(args_to_ignore_in_validation)
|
|
||||||
|
|
||||||
dependencies_graph = dict()
|
dependencies_graph = dict()
|
||||||
for sensor_name, virtual_sensor in self.virtual_sensors.items():
|
for sensor_name, virtual_sensor in self.virtual_sensors.items():
|
||||||
try:
|
try:
|
||||||
@@ -672,4 +673,4 @@ class VirtualSensors():
|
|||||||
class VirtualSensorsApp(hass.Hass):
|
class VirtualSensorsApp(hass.Hass):
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
self.logger_interface = LoggerInterface(self.get_ad_api(),default_log = "virtualsensors_log")
|
self.logger_interface = LoggerInterface(self.get_ad_api(),default_log = "virtualsensors_log")
|
||||||
self.virtual_sensors = VirtualSensors(ad_api = self.get_ad_api(),logger_interface = self.logger_interface,yaml_block = self.args,args_to_ignore_in_validation = ['module','class','global_dependencies','priority','name','config_path'])
|
self.virtual_sensors = VirtualSensors(ad_api = self.get_ad_api(),logger_interface = self.logger_interface,yaml_block = self.args,args_to_ignore_in_validation = ['module','class','global_dependencies','priority','name','config_path'],app_name = self.name)
|
||||||
Reference in New Issue
Block a user