forked from platypush/platypush
- icon_class should not be part of the backend model
- Interaction with entities should occur through the `entities.action` method, not by implementing native methods on each of the model objects
This commit is contained in:
parent
947b50b937
commit
f52b556219
5 changed files with 35 additions and 48 deletions
|
@ -52,12 +52,6 @@ class Entity(Base):
|
||||||
'polymorphic_on': type,
|
'polymorphic_on': type,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def _meta(self) -> dict:
|
|
||||||
return {
|
|
||||||
'icon_class': 'fa-solid fa-circle-question',
|
|
||||||
}
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@property
|
@property
|
||||||
def columns(cls) -> Tuple[ColumnProperty]:
|
def columns(cls) -> Tuple[ColumnProperty]:
|
||||||
|
@ -73,13 +67,7 @@ class Entity(Base):
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def to_json(self) -> dict:
|
def to_json(self) -> dict:
|
||||||
return {
|
return {col.key: self._serialize_value(col) for col in self.columns}
|
||||||
**{col.key: self._serialize_value(col) for col in self.columns},
|
|
||||||
'meta': {
|
|
||||||
**self._meta,
|
|
||||||
**(self.meta or {}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_plugin(self):
|
def get_plugin(self):
|
||||||
from platypush.context import get_plugin
|
from platypush.context import get_plugin
|
||||||
|
@ -88,6 +76,12 @@ class Entity(Base):
|
||||||
assert plugin, f'No such plugin: {plugin}'
|
assert plugin, f'No such plugin: {plugin}'
|
||||||
return plugin
|
return plugin
|
||||||
|
|
||||||
|
def run(self, action: str, *args, **kwargs):
|
||||||
|
plugin = self.get_plugin()
|
||||||
|
method = getattr(plugin, action, None)
|
||||||
|
assert method, f'No such action: {self.plugin}.{action}'
|
||||||
|
return method(self.external_id or self.name, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
# Inject the JSONAble mixin (Python goes nuts if done through
|
# Inject the JSONAble mixin (Python goes nuts if done through
|
||||||
# standard multiple inheritance with an SQLAlchemy ORM class)
|
# standard multiple inheritance with an SQLAlchemy ORM class)
|
||||||
|
|
|
@ -11,10 +11,3 @@ class Device(Entity):
|
||||||
__mapper_args__ = {
|
__mapper_args__ = {
|
||||||
'polymorphic_identity': __tablename__,
|
'polymorphic_identity': __tablename__,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def _meta(self):
|
|
||||||
return {
|
|
||||||
**super()._meta,
|
|
||||||
'icon_class': 'fa-solid fa-gear',
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,10 +11,3 @@ class Light(Device):
|
||||||
__mapper_args__ = {
|
__mapper_args__ = {
|
||||||
'polymorphic_identity': __tablename__,
|
'polymorphic_identity': __tablename__,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def _meta(self):
|
|
||||||
return {
|
|
||||||
**super()._meta,
|
|
||||||
'icon_class': 'fa-solid fa-lightbulb',
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,19 +12,3 @@ class Switch(Device):
|
||||||
__mapper_args__ = {
|
__mapper_args__ = {
|
||||||
'polymorphic_identity': __tablename__,
|
'polymorphic_identity': __tablename__,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def _meta(self):
|
|
||||||
return {
|
|
||||||
**super()._meta,
|
|
||||||
'icon_class': 'fa-solid fa-light-switch',
|
|
||||||
}
|
|
||||||
|
|
||||||
def on(self):
|
|
||||||
return self.get_plugin().on(self)
|
|
||||||
|
|
||||||
def off(self):
|
|
||||||
return self.get_plugin().off(self)
|
|
||||||
|
|
||||||
def toggle(self):
|
|
||||||
return self.get_plugin().toggle(self)
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
from queue import Queue, Empty
|
from queue import Queue, Empty
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from time import time
|
from time import time
|
||||||
from typing import Optional
|
from typing import Optional, Any
|
||||||
|
|
||||||
from platypush.context import get_plugin
|
from platypush.context import get_plugin
|
||||||
from platypush.entities import get_plugin_entity_registry, get_entities_registry
|
from platypush.entities import Entity, get_plugin_entity_registry, get_entities_registry
|
||||||
from platypush.plugins import Plugin, action
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,6 +17,11 @@ class EntitiesPlugin(Plugin):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
def _get_db(self):
|
||||||
|
db = get_plugin('db')
|
||||||
|
assert db
|
||||||
|
return db
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def get(self, type: str = 'entity', **filter):
|
def get(self, type: str = 'entity', **filter):
|
||||||
"""
|
"""
|
||||||
|
@ -35,9 +40,7 @@ class EntitiesPlugin(Plugin):
|
||||||
entity_type
|
entity_type
|
||||||
), f'No such entity type: {type}. Supported types: {list(all_types.keys())}'
|
), f'No such entity type: {type}. Supported types: {list(all_types.keys())}'
|
||||||
|
|
||||||
db = get_plugin('db')
|
db = self._get_db()
|
||||||
assert db
|
|
||||||
|
|
||||||
with db.get_session() as session:
|
with db.get_session() as session:
|
||||||
query = session.query(entity_type)
|
query = session.query(entity_type)
|
||||||
if filter:
|
if filter:
|
||||||
|
@ -127,5 +130,25 @@ class EntitiesPlugin(Plugin):
|
||||||
|
|
||||||
return self.get(**filter)
|
return self.get(**filter)
|
||||||
|
|
||||||
|
@action
|
||||||
|
def execute(self, id: Any, action: str, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Execute an action on an entity (for example `on`/`off` on a switch, or `get`
|
||||||
|
on a sensor).
|
||||||
|
|
||||||
|
:param id: Entity ID (i.e. the entity's db primary key, not the plugin's external
|
||||||
|
or "logical" key)
|
||||||
|
:param action: Action that should be run. It should be a method implemented
|
||||||
|
by the entity's class.
|
||||||
|
:param args: Action's extra positional arguments.
|
||||||
|
:param kwargs: Action's extra named arguments.
|
||||||
|
"""
|
||||||
|
db = self._get_db()
|
||||||
|
with db.get_session() as session:
|
||||||
|
entity = session.query(Entity).filter_by(id=id).one_or_none()
|
||||||
|
|
||||||
|
assert entity, f'No such entity ID: {id}'
|
||||||
|
return entity.run(action, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
Loading…
Reference in a new issue