Skip to content

Commit 4230d88

Browse files
add filter option, to set threholfs for minimal and maximal values of states
1 parent cb81862 commit 4230d88

File tree

2 files changed

+78
-4
lines changed

2 files changed

+78
-4
lines changed

README.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,15 @@ remote_homeassistant:
7676
exclude:
7777
entities:
7878
- group.all_switches
79-
79+
filter:
80+
- entity_id: sensor.faulty_pc_energy
81+
above: 100
82+
- unit_of_measurement: W
83+
above: 0
84+
below: 1000
85+
- entity_id: sensor.faulty_*_power
86+
unit_of_measurement: W
87+
below: 500
8088
subscribe_events:
8189
- zwave.network_ready
8290
- zwave.node_event
@@ -134,6 +142,26 @@ exclude:
134142
domains:
135143
description: The list of domains to be excluded from the remote instance
136144
type: list
145+
filter:
146+
description: Filters out states above or below a certain threshold, e.g. outliers reported by faulty sensors
147+
required: false
148+
type: list of
149+
entity_id:
150+
description: which entities the filter should match, supports wildcards
151+
required: false
152+
type: string
153+
unit_of_measurement
154+
description: which units of measurement the filter should match
155+
required: false
156+
type: string
157+
above:
158+
description: states above this threshold will be ignored
159+
required: false
160+
type: float
161+
below:
162+
description: states below this threshold will be ignored
163+
required: false
164+
type: float
137165
subscribe_events:
138166
description: Further list of events, which should be forwarded from the remote instance. If you override this, you probably will want to add state_changed!!
139167
required: false

custom_components/remote_homeassistant/__init__.py

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
For more details about this component, please refer to the documentation at
55
https://home-assistant.io/components/remote_homeassistant/
66
"""
7-
7+
import fnmatch
88
import logging
99
import copy
1010
import asyncio
1111
import aiohttp
12+
import re
1213

1314
import voluptuous as vol
1415

@@ -18,8 +19,9 @@
1819
from homeassistant.helpers.typing import HomeAssistantType, ConfigType
1920
from homeassistant.const import (CONF_HOST, CONF_PORT, EVENT_CALL_SERVICE,
2021
EVENT_HOMEASSISTANT_STOP,
21-
EVENT_STATE_CHANGED, EVENT_SERVICE_REGISTERED, CONF_EXCLUDE, CONF_ENTITIES,
22-
CONF_DOMAINS, CONF_INCLUDE)
22+
EVENT_STATE_CHANGED, EVENT_SERVICE_REGISTERED,
23+
CONF_EXCLUDE, CONF_ENTITIES, CONF_ENTITY_ID,
24+
CONF_DOMAINS, CONF_INCLUDE, CONF_UNIT_OF_MEASUREMENT, CONF_ABOVE, CONF_BELOW)
2325
from homeassistant.config import DATA_CUSTOMIZE
2426
from homeassistant.helpers.aiohttp_client import async_get_clientsession
2527
import homeassistant.helpers.config_validation as cv
@@ -33,6 +35,7 @@
3335
CONF_API_PASSWORD = 'api_password'
3436
CONF_SUBSCRIBE_EVENTS = 'subscribe_events'
3537
CONF_ENTITY_PREFIX = 'entity_prefix'
38+
CONF_FILTER = 'filter'
3639

3740
DOMAIN = 'remote_homeassistant'
3841

@@ -63,6 +66,19 @@
6366
),
6467
}
6568
),
69+
vol.Optional(CONF_FILTER, default=[]): vol.All(
70+
cv.ensure_list,
71+
[
72+
vol.Schema(
73+
{
74+
vol.Optional(CONF_ENTITY_ID): cv.string,
75+
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
76+
vol.Optional(CONF_ABOVE): vol.Coerce(float),
77+
vol.Optional(CONF_BELOW): vol.Coerce(float),
78+
}
79+
)
80+
]
81+
),
6682
vol.Optional(CONF_SUBSCRIBE_EVENTS,
6783
default=DEFAULT_SUBSCRIBED_EVENTS): cv.ensure_list,
6884
vol.Optional(CONF_ENTITY_PREFIX, default=DEFAULT_ENTITY_PREFIX): cv.string,
@@ -109,6 +125,16 @@ def __init__(self, hass, conf):
109125
self._blacklist_e = set(exclude.get(CONF_ENTITIES, []))
110126
self._blacklist_d = set(exclude.get(CONF_DOMAINS, []))
111127

128+
self._filter = [
129+
{
130+
CONF_ENTITY_ID: re.compile(fnmatch.translate(f.get(CONF_ENTITY_ID))) if f.get(CONF_ENTITY_ID) else None,
131+
CONF_UNIT_OF_MEASUREMENT: f.get(CONF_UNIT_OF_MEASUREMENT),
132+
CONF_ABOVE: f.get(CONF_ABOVE),
133+
CONF_BELOW: f.get(CONF_BELOW)
134+
}
135+
for f in conf.get(CONF_FILTER, [])
136+
]
137+
112138
self._subscribe_events = conf.get(CONF_SUBSCRIBE_EVENTS)
113139
self._entity_prefix = conf.get(CONF_ENTITY_PREFIX)
114140

@@ -311,6 +337,26 @@ def state_changed(entity_id, state, attr):
311337
):
312338
return
313339

340+
for f in self._filter:
341+
if f[CONF_ENTITY_ID] and not f[CONF_ENTITY_ID].match(entity_id):
342+
continue
343+
if f[CONF_UNIT_OF_MEASUREMENT]:
344+
if CONF_UNIT_OF_MEASUREMENT not in attr:
345+
continue
346+
if f[CONF_UNIT_OF_MEASUREMENT] != attr[CONF_UNIT_OF_MEASUREMENT]:
347+
continue
348+
try:
349+
if f[CONF_BELOW] and float(state) < f[CONF_BELOW]:
350+
_LOGGER.info("%s: ignoring state '%s', because "
351+
"below '%s'", entity_id, state, f[CONF_BELOW])
352+
return
353+
if f[CONF_ABOVE] and float(state) > f[CONF_ABOVE]:
354+
_LOGGER.info("%s: ignoring state '%s', because "
355+
"above '%s'", entity_id, state, f[CONF_ABOVE])
356+
return
357+
except ValueError:
358+
pass
359+
314360
if self._entity_prefix:
315361
object_id = self._entity_prefix + object_id
316362
entity_id = domain + '.' + object_id

0 commit comments

Comments
 (0)