Better dynamic entities discovery

This commit is contained in:
Fabio Manganiello 2022-04-13 11:25:14 +02:00
parent 332c91252c
commit e6bfa1c50f
Signed by: blacklight
GPG key ID: D90FBA7F76362774
5 changed files with 43 additions and 37 deletions

View file

@ -143,20 +143,8 @@ export default {
}, },
async refresh() { async refresh() {
const actions = Object.keys( this.loadingEntities = Object.entries(this.entities).reduce((obj, [id, entity]) => {
Object.values(this.selector.selectedEntities).reduce((obj, entity) => {
if (entity.plugin)
obj[entity.plugin] = true
return obj
}, {})
).map((plugin) => `${plugin}.status`)
this.loadingEntities = {
...this.loadingEntities,
...Object.keys(this.selector.selectedEntities).reduce((obj, id) => {
const self = this const self = this
const entity = this.entities[id]
if (this.entityTimeouts[id]) if (this.entityTimeouts[id])
clearTimeout(this.entityTimeouts[id]) clearTimeout(this.entityTimeouts[id])
@ -176,11 +164,9 @@ export default {
obj[id] = true obj[id] = true
return obj return obj
}, {}), }, {})
}
// Force refresh by calling `.status` on all the selected plugins await this.request('entities.scan')
await Promise.all(actions.map((act) => this.request(act)))
}, },
async sync() { async sync() {
@ -231,6 +217,7 @@ export default {
...event.entity, ...event.entity,
meta: { meta: {
...(this.entities[entityId]?.meta || {}), ...(this.entities[entityId]?.meta || {}),
...(meta[event.entity.type] || {}),
...(event.entity?.meta || {}), ...(event.entity?.meta || {}),
}, },
} }

View file

@ -1,3 +1,4 @@
import json
from logging import getLogger from logging import getLogger
from queue import Queue, Empty from queue import Queue, Empty
from threading import Thread, Event, RLock from threading import Thread, Event, RLock
@ -23,6 +24,7 @@ class EntitiesEngine(Thread):
self.logger = getLogger(name=obj_name) self.logger = getLogger(name=obj_name)
self._queue = Queue() self._queue = Queue()
self._should_stop = Event() self._should_stop = Event()
self._entities_awaiting_flush = set()
self._entities_cache_lock = RLock() self._entities_cache_lock = RLock()
self._entities_cache = { self._entities_cache = {
'by_id': {}, 'by_id': {},
@ -110,6 +112,16 @@ class EntitiesEngine(Thread):
self._populate_entity_id_from_cache(entity) self._populate_entity_id_from_cache(entity)
if entity.id: if entity.id:
get_bus().post(EntityUpdateEvent(entity=entity)) get_bus().post(EntityUpdateEvent(entity=entity))
else:
self._entities_awaiting_flush.add(self._to_entity_awaiting_flush(entity))
@staticmethod
def _to_entity_awaiting_flush(entity: Entity):
e = entity.to_json()
return json.dumps(
{k: v for k, v in e.items() if k in {'external_id', 'name', 'plugin'}},
sort_keys=True,
)
def post(self, *entities: Entity): def post(self, *entities: Entity):
for entity in entities: for entity in entities:
@ -226,3 +238,10 @@ class EntitiesEngine(Thread):
with self._entities_cache_lock: with self._entities_cache_lock:
for entity in entities: for entity in entities:
self._cache_entities(entity, overwrite_cache=True) self._cache_entities(entity, overwrite_cache=True)
entities_awaiting_flush = {*self._entities_awaiting_flush}
for entity in entities:
e = self._to_entity_awaiting_flush(entity)
if e in entities_awaiting_flush:
self._process_event(entity)
self._entities_awaiting_flush.remove(e)

View file

@ -6,7 +6,7 @@ from ._base import Entity
class Device(Entity): class Device(Entity):
__tablename__ = 'device' __tablename__ = 'device'
id = Column(Integer, ForeignKey(Entity.id), primary_key=True) id = Column(Integer, ForeignKey(Entity.id, ondelete='CASCADE'), primary_key=True)
__mapper_args__ = { __mapper_args__ = {
'polymorphic_identity': __tablename__, 'polymorphic_identity': __tablename__,

View file

@ -6,7 +6,7 @@ from .devices import Device
class Light(Device): class Light(Device):
__tablename__ = 'light' __tablename__ = 'light'
id = Column(Integer, ForeignKey(Device.id), primary_key=True) id = Column(Integer, ForeignKey(Device.id, ondelete='CASCADE'), primary_key=True)
__mapper_args__ = { __mapper_args__ = {
'polymorphic_identity': __tablename__, 'polymorphic_identity': __tablename__,

View file

@ -6,7 +6,7 @@ from .devices import Device
class Switch(Device): class Switch(Device):
__tablename__ = 'switch' __tablename__ = 'switch'
id = Column(Integer, ForeignKey(Device.id), primary_key=True) id = Column(Integer, ForeignKey(Device.id, ondelete='CASCADE'), primary_key=True)
state = Column(Boolean) state = Column(Boolean)
__mapper_args__ = { __mapper_args__ = {