Skip to content
Snippets Groups Projects
SensorLineChartTile.py 3.45 KiB
Newer Older
  • Learn to ignore specific revisions
  • Robert Goldmann's avatar
    Robert Goldmann committed
    import os
    
    Robert Goldmann's avatar
    Robert Goldmann committed
    import uuid
    
    from datetime import datetime, timedelta
    
    from typing import Dict, Tuple, List
    
    Robert Goldmann's avatar
    Robert Goldmann committed
    
    from flask import Blueprint
    
    
    Robert Goldmann's avatar
    Robert Goldmann committed
    from logic import Constants, Helpers
    
    Robert Goldmann's avatar
    Robert Goldmann committed
    from logic.service.ServiceManager import ServiceManager
    from logic.tile.Tile import Tile
    
    
    LOGGER = logging.getLogger(Constants.APP_NAME)
    
    
    Robert Goldmann's avatar
    Robert Goldmann committed
    
    class SensorLineChartTile(Tile):
    
        EXAMPLE_SETTINGS = {
            "title": "My Room",
            "url": "http://127.0.0.1:10003",
            "sensorID": 1,
    
    Robert Goldmann's avatar
    Robert Goldmann committed
            "numberOfHoursToShow": 4,
    
    Robert Goldmann's avatar
    Robert Goldmann committed
            "decimals": 1,
    
    Robert Goldmann's avatar
    Robert Goldmann committed
            "lineColor": "rgba(254, 151, 0, 1)",
            "fillColor": "rgba(254, 151, 0, 0.2)"
    
    Robert Goldmann's avatar
    Robert Goldmann committed
        UNIT_BY_SENSOR_TYPE = {
            'temperature': '&degC',
            'humidity': '%'
        }
    
        ICON_BY_SENSOR_TYPE = {
            'temperature': 'wi-thermometer',
            'humidity': 'wi-humidity'
        }
    
    
        DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
    
    
    Robert Goldmann's avatar
    Robert Goldmann committed
        def __init__(self, uniqueName: str, settings: Dict, intervalInSeconds: int):
            super().__init__(uniqueName, settings, intervalInSeconds)
    
        def fetch(self, pageName: str) -> Dict:
            storageLeafService = ServiceManager.get_instance().get_service_by_type_name('StorageLeafService')
            cacheKey = f'{pageName}_{self._uniqueName}'
    
    
            serviceSettings = {
                'url': self._settings['url'],
                'sensorID': self._settings['sensorID'],
    
                'fetchType': 'all',
                'fetchLimit': 1000,
    
            sensorData = storageLeafService.get_data(cacheKey, self._intervalInSeconds, serviceSettings)
    
    Robert Goldmann's avatar
    Robert Goldmann committed
    
    
            x, y = self.__filter_measurements(sensorData['sensorValue'])
    
    Robert Goldmann's avatar
    Robert Goldmann committed
            latest = y[-1] if y else ''
    
    Robert Goldmann's avatar
    Robert Goldmann committed
    
    
            return {
                'latest': latest,
                'x': x,
                'y': y,
                'sensorInfo': sensorData['sensorInfo']
            }
    
        def __filter_measurements(self, measurements: List[Dict]) -> Tuple[List[str], List[str]]:
    
            x = []
            y = []
    
            timeLimit = datetime.now() - timedelta(hours=self._settings['numberOfHoursToShow'])
    
            for measurement in measurements:
    
                timestamp = measurement['timestamp']
                parsedTime = datetime.strptime(timestamp, self.DATE_FORMAT)
                if parsedTime < timeLimit:
                    break
                x.append(timestamp)
    
    Robert Goldmann's avatar
    Robert Goldmann committed
                value = float(measurement['value'])
                y.append(Helpers.round_to_decimals(value, self._settings['decimals']))
    
            LOGGER.debug(f'Filtered {len(measurements)} to {len(x)} for sensor {self._settings["sensorID"]}')
    
            x.reverse()
            y.reverse()
    
            return x, y
    
        def render(self, data: Dict) -> str:
            sensorType = data['sensorInfo']['type']
            unit = self.UNIT_BY_SENSOR_TYPE.get(sensorType, '')
            icon = self.ICON_BY_SENSOR_TYPE.get(sensorType, '')
    
    Robert Goldmann's avatar
    Robert Goldmann committed
            return Tile.render_template(os.path.dirname(__file__), __class__.__name__,
    
                                        x=data['x'],
                                        y=data['y'],
                                        latest=data['latest'],
                                        unit=unit,
                                        icon=icon,
                                        title=self._settings['title'],
    
    Robert Goldmann's avatar
    Robert Goldmann committed
                                        lineColor=self._settings['lineColor'],
                                        fillColor=self._settings['fillColor'],
                                        chartId=str(uuid.uuid4()))
    
    Robert Goldmann's avatar
    Robert Goldmann committed
    
    
        def construct_blueprint(self, pageName: str, *args, **kwargs):
            return Blueprint(f'{pageName}_{__class__.__name__}_{self.get_uniqueName()}', __name__)