platypush/platypush/entities/__init__.py
Fabio Manganiello 5fc9c1199b Fixed the root cause of the failure on the time module.
The previous commit prompted a new error:

```
2024-06-01 10:54:08,310|ERROR|platypush:plugin:bluetooth|module 'platypush.entities.time' has no attribute 'time'
Traceback (most recent call last):
  File "/usr/lib/python3.9/dist-packages/platypush/plugins/__init__.py", line 247, in _runner
    self.main()
  File "/usr/lib/python3.9/dist-packages/platypush/plugins/bluetooth/__init__.py", line 590, in main
    self._refresh_cache()
  File "/usr/lib/python3.9/dist-packages/platypush/plugins/bluetooth/__init__.py", line 146, in _refresh_cache
    get_entities_engine().wait_start()
  File "/usr/lib/python3.9/dist-packages/platypush/entities/__init__.py", line 48, in get_entities_engine
    time_start = time.time()
AttributeError: module 'platypush.entities.time' has no attribute 'time'
```

Which explains even the previous error: `import time` in that module
won't use the `time` module from the Python library, but the `.time`
module within the same directory.

This error only happens when the current directory is part of PYTHONPATH
(and usually it shouldn't), but for sake of keeping things safe I've
replaced `time()` with `utcnow().timestamp()`, with `utcnow` imported
from `platypush.utils`.
2024-06-01 09:01:07 +00:00

98 lines
2.3 KiB
Python

import logging
from threading import Event
from typing import Collection, Optional
from platypush.utils import utcnow
from ._base import (
Entity,
EntityKey,
EntitySavedCallback,
get_entities_registry,
init_entities_db,
)
from ._engine import EntitiesEngine
from .managers import (
EntityManager,
get_plugin_entity_registry,
register_entity_manager,
)
from .managers.lights import LightEntityManager
from .managers.sensors import SensorEntityManager
from .managers.switches import (
DimmerEntityManager,
EnumSwitchEntityManager,
SwitchEntityManager,
)
_engine: Optional[EntitiesEngine] = None
logger = logging.getLogger(__name__)
def init_entities_engine() -> EntitiesEngine:
"""
Initialize and start the entities engine.
"""
global _engine # pylint: disable=global-statement
init_entities_db()
_engine = EntitiesEngine()
_engine.start()
return _engine
def get_entities_engine(timeout: Optional[float] = None) -> EntitiesEngine:
"""
Return the running entities engine.
:param timeout: Timeout in seconds (default: None).
"""
time_start = utcnow().timestamp()
while not timeout or (utcnow().timestamp() - time_start < timeout):
if _engine:
break
Event().wait(1)
if not _engine:
raise TimeoutError('The entities engine has not been initialized')
return _engine
def publish_entities(
entities: Collection[Entity], callback: Optional[EntitySavedCallback] = None
) -> None:
"""
Publish a collection of entities to be processed by the engine.
The engine will:
- Normalize and merge the provided entities.
- Trigger ``EntityUpdateEvent`` events.
- Persist the new state to the local database.
:param entities: Entities to be published.
"""
if not _engine:
logger.debug('No entities engine registered')
return
_engine.post(*entities, callback=callback)
__all__ = (
'DimmerEntityManager',
'EntitiesEngine',
'Entity',
'EntityKey',
'EntityManager',
'EntitySavedCallback',
'EnumSwitchEntityManager',
'LightEntityManager',
'SensorEntityManager',
'SwitchEntityManager',
'get_entities_registry',
'get_plugin_entity_registry',
'init_entities_engine',
'publish_entities',
'register_entity_manager',
)