def extra_state_attributes(self): """Return the attributes of the sensor.""" val = {ATTR_ATTRIBUTION: ATTRIBUTION} if self._email not in self._data.data: return val for idx, value in enumerate(self._data.data[self._email]): tmpname = f"breach {idx + 1}" datetime_local = dt_util.as_local( dt_util.parse_datetime(value["AddedDate"])) tmpvalue = f"{value['Title']} {datetime_local.strftime(DATE_STR_FORMAT)}" val[tmpname] = tmpvalue return val
async def test_intervals(opp): """Test timing intervals of sensors.""" device = time_date.TimeDateSensor(opp, "time") now = dt_util.utc_from_timestamp(45.5) with patch("openpeerpower.util.dt.utcnow", return_value=now): next_time = device.get_next_interval() assert next_time == dt_util.utc_from_timestamp(60) device = time_date.TimeDateSensor(opp, "beat") now = dt_util.parse_datetime("2020-11-13 00:00:29+01:00") with patch("openpeerpower.util.dt.utcnow", return_value=now): next_time = device.get_next_interval() assert next_time == dt_util.parse_datetime("2020-11-13 00:01:26.4+01:00") device = time_date.TimeDateSensor(opp, "date_time") now = dt_util.utc_from_timestamp(1495068899) with patch("openpeerpower.util.dt.utcnow", return_value=now): next_time = device.get_next_interval() assert next_time == dt_util.utc_from_timestamp(1495068900) now = dt_util.utcnow() device = time_date.TimeDateSensor(opp, "time_date") next_time = device.get_next_interval() assert next_time > now
def __init__(self, config: typing.Dict) -> None: """Initialize a select input.""" self._config = config self.editable = True self._current_datetime = None initial = config.get(CONF_INITIAL) if initial: if self.has_date and self.has_time: self._current_datetime = dt_util.parse_datetime(initial) elif self.has_date: date = dt_util.parse_date(initial) self._current_datetime = datetime.datetime.combine(date, DEFAULT_TIME) else: time = dt_util.parse_time(initial) self._current_datetime = datetime.datetime.combine(DEFAULT_DATE, time)
def async_update_callback(self): """Fire the event if reason is that state is updated.""" if (self.sensor.state == self._last_state or # Filter out old states. Can happen when events fire while refreshing dt_util.parse_datetime(self.sensor.state["lastupdated"]) <= dt_util.parse_datetime(self._last_state["lastupdated"])): return # Extract the press code as state if hasattr(self.sensor, "rotaryevent"): state = self.sensor.rotaryevent else: state = self.sensor.buttonevent self._last_state = dict(self.sensor.state) # Fire event data = { CONF_ID: self.event_id, CONF_UNIQUE_ID: self.unique_id, CONF_EVENT: state, CONF_LAST_UPDATED: self.sensor.lastupdated, } self.bridge.opp.bus.async_fire(CONF_HUE_EVENT, data)
def _get_daily_forecast_from_weather_response(self, weather_response, now): if weather_response.daily: parse = False forecast = [] for day in weather_response.daily[ATTR_DATA][0][ AEMET_ATTR_FORECAST][AEMET_ATTR_DAY]: day_date = dt_util.parse_datetime(day[AEMET_ATTR_DATE]) if now.date() == day_date.date(): parse = True if parse: cur_forecast = self._convert_forecast_day(day_date, day) if cur_forecast: forecast.append(cur_forecast) return forecast return None
async def load_auth_tokens(store) -> tuple[dict, dict | None]: app_storage = await store.async_load() tokens = dict(app_storage or {}) if tokens.pop(CONF_USERNAME, None) != config[DOMAIN][CONF_USERNAME]: # any tokens won't be valid, and store might be be corrupt await store.async_save({}) return ({}, None) # evohomeasync2 requires naive/local datetimes as strings if tokens.get(ACCESS_TOKEN_EXPIRES) is not None: tokens[ACCESS_TOKEN_EXPIRES] = _dt_aware_to_naive( dt_util.parse_datetime(tokens[ACCESS_TOKEN_EXPIRES])) user_data = tokens.pop(USER_DATA, None) return (tokens, user_data)
def _async_handle_update(self, *args, **kwargs) -> None: """Update the state using webhook data.""" if self._cancel_update: self._cancel_update() self._cancel_update = None if args[0][0][KEY_SUBTYPE] == SUBTYPE_RAIN_DELAY_ON: endtime = parse_datetime(args[0][0][KEY_RAIN_DELAY_END]) _LOGGER.debug("Rain delay expires at %s", endtime) self._state = True self._cancel_update = async_track_point_in_utc_time( self.opp, self._delay_expiration, endtime) elif args[0][0][KEY_SUBTYPE] == SUBTYPE_RAIN_DELAY_OFF: self._state = False self.async_write_op_state()
def log_rate_limits(opp, target, resp, level=20): """Output rate limit log line at given level.""" rate_limits = resp["rateLimits"] resetsAt = dt_util.parse_datetime(rate_limits["resetsAt"]) resetsAtTime = resetsAt - dt_util.utcnow() rate_limit_msg = ("iOS push notification rate limits for %s: " "%d sent, %d allowed, %d errors, " "resets in %s") _LOGGER.log( level, rate_limit_msg, ios.device_name_for_push_id(opp, target), rate_limits["successful"], rate_limits["maximum"], rate_limits["errors"], str(resetsAtTime).split(".")[0], )
async def async_parse_last_reboot(uid: str, msg) -> Event: """Handle parsing event message. Topic: tns1:Monitoring/OperatingTime/LastReboot """ try: return Event( f"{uid}_{msg.Topic._value_1}", "Last Reboot", "sensor", "timestamp", None, dt_util.as_local( dt_util.parse_datetime(msg.Message._value_1.Data.SimpleItem[0].Value) ), ) except (AttributeError, KeyError, ValueError): return None
def last_run_was_recently_clean(cursor): """Verify the last recorder run was recently clean.""" cursor.execute("SELECT end FROM recorder_runs ORDER BY start DESC LIMIT 1;") end_time = cursor.fetchone() if not end_time or not end_time[0]: return False last_run_end_time = process_timestamp(dt_util.parse_datetime(end_time[0])) now = dt_util.utcnow() _LOGGER.debug("The last run ended at: %s (now: %s)", last_run_end_time, now) if last_run_end_time + MAX_RESTART_TIME < now: return False return True
async def test_form_duplicated_id(opp): """Test setting up duplicated entry.""" now = dt_util.parse_datetime("2021-01-09 12:00:00+00:00") with patch("openpeerpower.util.dt.now", return_value=now), patch( "openpeerpower.util.dt.utcnow", return_value=now), requests_mock.mock() as _m: aemet_requests_mock(_m) entry = MockConfigEntry(domain=DOMAIN, unique_id="40.30403754--3.72935236", data=CONFIG) entry.add_to_opp(opp) result = await opp.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, data=CONFIG) assert result["type"] == "abort" assert result["reason"] == "already_configured"
async def async_callback(self, payload): """Handle received data.""" errors = payload.get("errors") if errors: _LOGGER.error(errors[0]) return data = payload.get("data") if data is None: return live_measurement = data.get("liveMeasurement") if live_measurement is None: return timestamp = dt_util.parse_datetime(live_measurement.pop("timestamp")) new_entities = [] for sensor_type, state in live_measurement.items(): if state is None or sensor_type not in RT_SENSOR_MAP: continue if sensor_type in self._entities: async_dispatcher_send( self.opp, SIGNAL_UPDATE_ENTITY.format(self._entities[sensor_type]), state, timestamp, ) else: sensor_name, device_class, unit, state_class = RT_SENSOR_MAP[ sensor_type ] if sensor_type == "accumulatedCost": unit = self._tibber_home.currency entity = TibberSensorRT( self._tibber_home, sensor_name, device_class, unit, state, state_class, ) new_entities.append(entity) self._entities[sensor_type] = entity.unique_id if new_entities: self._async_add_entities(new_entities)
async def async_set_operation_mode(self, operation_mode: str) -> None: """Set new operation mode for a DHW controller. Except for Auto, the mode is only until the next SetPoint. """ if operation_mode == STATE_AUTO: await self._evo_broker.call_client_api( self._evo_device.set_dhw_auto()) else: await self._update_schedule() until = dt_util.parse_datetime( self.setpoints.get("next_sp_from", "")) until = dt_util.as_utc(until) if until else None if operation_mode == STATE_ON: await self._evo_broker.call_client_api( self._evo_device.set_dhw_on(until=until)) else: # STATE_OFF await self._evo_broker.call_client_api( self._evo_device.set_dhw_off(until=until))
def log_rate_limits(opp, device_name, resp, level=logging.INFO): """Output rate limit log line at given level.""" if ATTR_PUSH_RATE_LIMITS not in resp: return rate_limits = resp[ATTR_PUSH_RATE_LIMITS] resetsAt = rate_limits[ATTR_PUSH_RATE_LIMITS_RESETS_AT] resetsAtTime = dt_util.parse_datetime(resetsAt) - dt_util.utcnow() rate_limit_msg = ("mobile_app push notification rate limits for %s: " "%d sent, %d allowed, %d errors, " "resets in %s") _LOGGER.log( level, rate_limit_msg, device_name, rate_limits[ATTR_PUSH_RATE_LIMITS_SUCCESSFUL], rate_limits[ATTR_PUSH_RATE_LIMITS_MAXIMUM], rate_limits[ATTR_PUSH_RATE_LIMITS_ERRORS], str(resetsAtTime).split(".")[0], )
def update_from_latest_data(self): """Update the state.""" data = self.openuv.data[DATA_UV].get("result") if not data: self._available = False return self._available = True if self._sensor_type == TYPE_CURRENT_OZONE_LEVEL: self._state = data["ozone"] elif self._sensor_type == TYPE_CURRENT_UV_INDEX: self._state = data["uv"] elif self._sensor_type == TYPE_CURRENT_UV_LEVEL: if data["uv"] >= 11: self._state = UV_LEVEL_EXTREME elif data["uv"] >= 8: self._state = UV_LEVEL_VHIGH elif data["uv"] >= 6: self._state = UV_LEVEL_HIGH elif data["uv"] >= 3: self._state = UV_LEVEL_MODERATE else: self._state = UV_LEVEL_LOW elif self._sensor_type == TYPE_MAX_UV_INDEX: self._state = data["uv_max"] self._attrs.update({ ATTR_MAX_UV_TIME: as_local(parse_datetime(data["uv_max_time"])) }) elif self._sensor_type in ( TYPE_SAFE_EXPOSURE_TIME_1, TYPE_SAFE_EXPOSURE_TIME_2, TYPE_SAFE_EXPOSURE_TIME_3, TYPE_SAFE_EXPOSURE_TIME_4, TYPE_SAFE_EXPOSURE_TIME_5, TYPE_SAFE_EXPOSURE_TIME_6, ): self._state = data["safe_exposure_time"][EXPOSURE_TYPE_MAP[ self._sensor_type]]
async def async_get_events(self, opp, start_date, end_date): """Get all tasks in a specific time frame.""" if self._id is None: project_task_data = [ task for task in self._api.state[TASKS] if not self._project_id_whitelist or task[PROJECT_ID] in self._project_id_whitelist ] else: project_data = await opp.async_add_executor_job( self._api.projects.get_data, self._id) project_task_data = project_data[TASKS] events = [] for task in project_task_data: if task["due"] is None: continue due_date = _parse_due_date( task["due"], self._api.state["user"]["tz_info"]["gmt_string"]) midnight = dt.as_utc( dt.parse_datetime( due_date.strftime("%Y-%m-%d") + "T00:00:00" + self._api.state["user"]["tz_info"]["gmt_string"])) if start_date < due_date < end_date: if due_date == midnight: # If the due date has no time data, return just the date so that it # will render correctly as an all day event on a calendar. due_date_value = due_date.strftime("%Y-%m-%d") else: due_date_value = due_date.isoformat() event = { "uid": task["id"], "title": task["content"], "start": due_date_value, "end": due_date_value, "allDay": True, "summary": task["content"], } events.append(event) return events
async def async_added_to_opp(self) -> None: """Startup with initial state or previous state.""" await super().async_added_to_opp() self._logger = logging.getLogger( f"{__name__}.{split_entity_id(self.entity_id)[1]}" ) self.action_script.update_logger(self._logger) state = await self.async_get_last_state() if state: enable_automation = state.state == STATE_ON last_triggered = state.attributes.get("last_triggered") if last_triggered is not None: self.action_script.last_triggered = parse_datetime(last_triggered) self._logger.debug( "Loaded automation %s with state %s from state " " storage last state %s", self.entity_id, enable_automation, state, ) else: enable_automation = DEFAULT_INITIAL_STATE self._logger.debug( "Automation %s not in state storage, state %s from default is used", self.entity_id, enable_automation, ) if self._initial_state is not None: enable_automation = self._initial_state self._logger.debug( "Automation %s initial state %s overridden from " "config initial_state", self.entity_id, enable_automation, ) if enable_automation: await self.async_enable()
async def test_unload_entry(opp): """Test that the options form.""" now = dt_util.parse_datetime("2021-01-09 12:00:00+00:00") with patch("openpeerpower.util.dt.now", return_value=now), patch( "openpeerpower.util.dt.utcnow", return_value=now), requests_mock.mock() as _m: aemet_requests_mock(_m) config_entry = MockConfigEntry(domain=DOMAIN, unique_id="aemet_unique_id", data=CONFIG) config_entry.add_to_opp(opp) assert await opp.config_entries.async_setup(config_entry.entry_id) await opp.async_block_till_done() assert config_entry.state is ConfigEntryState.LOADED await opp.config_entries.async_unload(config_entry.entry_id) await opp.async_block_till_done() assert config_entry.state is ConfigEntryState.NOT_LOADED
def _get_hourly_forecast_from_weather_response(self, weather_response, now): if weather_response.hourly: parse = False hour = now.hour forecast = [] for day in weather_response.hourly[ATTR_DATA][0][ AEMET_ATTR_FORECAST][AEMET_ATTR_DAY]: day_date = dt_util.parse_datetime(day[AEMET_ATTR_DATE]) hour_start = 0 if now.date() == day_date.date(): parse = True hour_start = now.hour if parse: for hour in range(hour_start, 24): cur_forecast = self._convert_forecast_hour( day_date, day, hour) if cur_forecast: forecast.append(cur_forecast) return forecast return None
async def async_set_preset_mode(self, preset_mode: str | None) -> None: """Set the preset mode; if None, then revert to following the schedule.""" evo_preset_mode = HA_PRESET_TO_EVO.get(preset_mode, EVO_FOLLOW) if evo_preset_mode == EVO_FOLLOW: await self._evo_broker.call_client_api( self._evo_device.cancel_temp_override() ) return temperature = self._evo_device.setpointStatus["targetHeatTemperature"] if evo_preset_mode == EVO_TEMPOVER: await self._update_schedule() until = dt_util.parse_datetime(self.setpoints.get("next_sp_from", "")) else: # EVO_PERMOVER until = None until = dt_util.as_utc(until) if until else None await self._evo_broker.call_client_api( self._evo_device.set_temperature(temperature, until=until) )
async def _test_self_reset(opp, config, start_time, expect_reset=True): """Test energy sensor self reset.""" assert await async_setup_component(opp, DOMAIN, config) assert await async_setup_component(opp, SENSOR_DOMAIN, config) await opp.async_block_till_done() opp.bus.async_fire(EVENT_OPENPEERPOWER_START) entity_id = config[DOMAIN]["energy_bill"]["source"] now = dt_util.parse_datetime(start_time) with alter_time(now): async_fire_time_changed(opp, now) opp.states.async_set(entity_id, 1, {"unit_of_measurement": "kWh"}) await opp.async_block_till_done() now += timedelta(seconds=30) with alter_time(now): async_fire_time_changed(opp, now) opp.states.async_set(entity_id, 3, {"unit_of_measurement": "kWh"}, force_update=True) await opp.async_block_till_done() now += timedelta(seconds=30) with alter_time(now): async_fire_time_changed(opp, now) await opp.async_block_till_done() opp.states.async_set(entity_id, 6, {"unit_of_measurement": "kWh"}, force_update=True) await opp.async_block_till_done() state = opp.states.get("sensor.energy_bill") if expect_reset: assert state.attributes.get("last_period") == "2" assert state.state == "3" else: assert state.attributes.get("last_period") == 0 assert state.state == "5"
def update(self) -> None: """Read new state data from the library.""" _LOGGER.debug("Updating %s", self._vehicle.name) vehicle_state = self._vehicle.state vehicle_last_trip = self._vehicle.state.last_trip if self._attribute == "charging_status": self._state = getattr(vehicle_state, self._attribute).value elif self.unit_of_measurement == VOLUME_GALLONS: value = getattr(vehicle_state, self._attribute) value_converted = self.opp.config.units.volume(value, VOLUME_LITERS) self._state = round(value_converted) elif self.unit_of_measurement == LENGTH_MILES: value = getattr(vehicle_state, self._attribute) value_converted = self.opp.config.units.length(value, LENGTH_KILOMETERS) self._state = round(value_converted) elif self._service is None: self._state = getattr(vehicle_state, self._attribute) elif self._service == SERVICE_LAST_TRIP: if self._attribute == "date_utc": date_str = getattr(vehicle_last_trip, "date") self._state = dt_util.parse_datetime(date_str).isoformat() else: self._state = getattr(vehicle_last_trip, self._attribute)
def handle_new_task(call): """Call when a user creates a new Todoist Task from Open Peer Power.""" project_name = call.data[PROJECT_NAME] project_id = project_id_lookup[project_name] # Create the task item = api.items.add(call.data[CONTENT], project_id=project_id) if LABELS in call.data: task_labels = call.data[LABELS] label_ids = [ label_id_lookup[label.lower()] for label in task_labels ] item.update(labels=label_ids) if PRIORITY in call.data: item.update(priority=call.data[PRIORITY]) _due: dict = {} if DUE_DATE_STRING in call.data: _due["string"] = call.data[DUE_DATE_STRING] if DUE_DATE_LANG in call.data: _due["lang"] = call.data[DUE_DATE_LANG] if DUE_DATE in call.data: due_date = dt.parse_datetime(call.data[DUE_DATE]) if due_date is None: due = dt.parse_date(call.data[DUE_DATE]) due_date = datetime(due.year, due.month, due.day) # Format it in the manner Todoist expects due_date = dt.as_utc(due_date) date_format = "%Y-%m-%dT%H:%M%S" due_date = datetime.strftime(due_date, date_format) _due["date"] = due_date if _due: item.update(due=_due) _reminder_due: dict = {} if REMINDER_DATE_STRING in call.data: _reminder_due["string"] = call.data[REMINDER_DATE_STRING] if REMINDER_DATE_LANG in call.data: _reminder_due["lang"] = call.data[REMINDER_DATE_LANG] if REMINDER_DATE in call.data: due_date = dt.parse_datetime(call.data[REMINDER_DATE]) if due_date is None: due = dt.parse_date(call.data[REMINDER_DATE]) due_date = datetime(due.year, due.month, due.day) # Format it in the manner Todoist expects due_date = dt.as_utc(due_date) date_format = "%Y-%m-%dT%H:%M:%S" due_date = datetime.strftime(due_date, date_format) _reminder_due["date"] = due_date if _reminder_due: api.reminders.add(item["id"], due=_reminder_due) # Commit changes api.commit() _LOGGER.debug("Created Todoist task: %s", call.data[CONTENT])
async def test_setting_rising(opp, legacy_patchable_time): """Test retrieving sun setting and rising.""" utc_now = datetime(2016, 11, 1, 8, 0, 0, tzinfo=dt_util.UTC) with patch("openpeerpower.helpers.condition.dt_util.utcnow", return_value=utc_now): await async_setup_component( opp, sun.DOMAIN, {sun.DOMAIN: {sun.CONF_ELEVATION: 0}} ) await opp.async_block_till_done() state = opp.states.get(sun.ENTITY_ID) from astral import LocationInfo import astral.sun utc_today = utc_now.date() location = LocationInfo( latitude=opp.config.latitude, longitude=opp.config.longitude ) mod = -1 while True: next_dawn = astral.sun.dawn( location.observer, date=utc_today + timedelta(days=mod) ) if next_dawn > utc_now: break mod += 1 mod = -1 while True: next_dusk = astral.sun.dusk( location.observer, date=utc_today + timedelta(days=mod) ) if next_dusk > utc_now: break mod += 1 mod = -1 while True: next_midnight = astral.sun.midnight( location.observer, date=utc_today + timedelta(days=mod) ) if next_midnight > utc_now: break mod += 1 mod = -1 while True: next_noon = astral.sun.noon( location.observer, date=utc_today + timedelta(days=mod) ) if next_noon > utc_now: break mod += 1 mod = -1 while True: next_rising = astral.sun.sunrise( location.observer, date=utc_today + timedelta(days=mod) ) if next_rising > utc_now: break mod += 1 mod = -1 while True: next_setting = astral.sun.sunset( location.observer, date=utc_today + timedelta(days=mod) ) if next_setting > utc_now: break mod += 1 assert next_dawn == dt_util.parse_datetime( state.attributes[sun.STATE_ATTR_NEXT_DAWN] ) assert next_dusk == dt_util.parse_datetime( state.attributes[sun.STATE_ATTR_NEXT_DUSK] ) assert next_midnight == dt_util.parse_datetime( state.attributes[sun.STATE_ATTR_NEXT_MIDNIGHT] ) assert next_noon == dt_util.parse_datetime( state.attributes[sun.STATE_ATTR_NEXT_NOON] ) assert next_rising == dt_util.parse_datetime( state.attributes[sun.STATE_ATTR_NEXT_RISING] ) assert next_setting == dt_util.parse_datetime( state.attributes[sun.STATE_ATTR_NEXT_SETTING] )
def last_update(self): """Return the last_update time for the device.""" last_update = parse_datetime(self.device.last_update) return last_update
async def _build_media_items(self, title, category): """Fetch requested gameclip/screenshot media.""" title_id, _, thumbnail = title.split("#", 2) owner, kind = category.split("#", 1) items: list[XboxMediaItem] = [] with suppress(ValidationError): # Unexpected API response if kind == "gameclips": if owner == "my": response: GameclipsResponse = ( await self.client.gameclips.get_recent_clips_by_xuid( self.client.xuid, title_id ) ) elif owner == "community": response: GameclipsResponse = await self.client.gameclips.get_recent_community_clips_by_title_id( title_id ) else: return None items = [ XboxMediaItem( item.user_caption or dt_util.as_local( dt_util.parse_datetime(item.date_recorded) ).strftime("%b. %d, %Y %I:%M %p"), item.thumbnails[0].uri, item.game_clip_uris[0].uri, MEDIA_CLASS_VIDEO, ) for item in response.game_clips ] elif kind == "screenshots": if owner == "my": response: ScreenshotResponse = ( await self.client.screenshots.get_recent_screenshots_by_xuid( self.client.xuid, title_id ) ) elif owner == "community": response: ScreenshotResponse = await self.client.screenshots.get_recent_community_screenshots_by_title_id( title_id ) else: return None items = [ XboxMediaItem( item.user_caption or dt_util.as_local(item.date_taken).strftime( "%b. %d, %Y %I:%M%p" ), item.thumbnails[0].uri, item.screenshot_uris[0].uri, MEDIA_CLASS_IMAGE, ) for item in response.screenshots ] return BrowseMediaSource( domain=DOMAIN, identifier=f"{title}~~{category}", media_class=MEDIA_CLASS_DIRECTORY, media_content_type="", title=f"{owner.title()} {kind.title()}", can_play=False, can_expand=True, children=[_build_media_item(title, category, item) for item in items], children_media_class=MEDIA_CLASS_MAP[kind], thumbnail=thumbnail, )
def is_valid_datetime(string: str) -> bool: """Test if string dt is a valid datetime.""" try: return dt_util.parse_datetime(string) is not None except ValueError: return False
async def updating_devices(self, *_): """Find the current data from self.data.""" if not self.data: return now = dt_util.utcnow() forecast_time = now + dt_util.dt.timedelta(hours=self._forecast) # Find the correct time entry. Since not all time entries contain all # types of data, we cannot just select one. Instead, we order them by # distance from the desired forecast_time, and for every device iterate # them in order of increasing distance, taking the first time_point # that contains the desired data. ordered_entries = [] for time_entry in self.data["product"]["time"]: valid_from = dt_util.parse_datetime(time_entry["@from"]) valid_to = dt_util.parse_datetime(time_entry["@to"]) if now >= valid_to: # Has already passed. Never select this. continue average_dist = abs( (valid_to - forecast_time).total_seconds()) + abs( (valid_from - forecast_time).total_seconds()) ordered_entries.append((average_dist, time_entry)) ordered_entries.sort(key=lambda item: item[0]) # Update all devices tasks = [] if ordered_entries: for dev in self.devices: new_state = None for (_, selected_time_entry) in ordered_entries: loc_data = selected_time_entry["location"] if dev.type not in loc_data: continue if dev.type == "precipitation": new_state = loc_data[dev.type]["@value"] elif dev.type == "symbol": new_state = loc_data[dev.type]["@number"] elif dev.type in ( "temperature", "pressure", "humidity", "dewpointTemperature", ): new_state = loc_data[dev.type]["@value"] elif dev.type in ("windSpeed", "windGust"): new_state = loc_data[dev.type]["@mps"] elif dev.type == "windDirection": new_state = float(loc_data[dev.type]["@deg"]) elif dev.type in ( "fog", "cloudiness", "lowClouds", "mediumClouds", "highClouds", ): new_state = loc_data[dev.type]["@percent"] break # pylint: disable=protected-access if new_state != dev._state: dev._state = new_state tasks.append(dev.async_update_op_state()) if tasks: await asyncio.wait(tasks)
async def async_added_to_opp(self): """Handle entity which will be added.""" await super().async_added_to_opp() if self._period == QUARTER_HOURLY: for quarter in range(4): async_track_time_change( self.opp, self._async_reset_meter, minute=(quarter * 15) + self._period_offset.seconds % (15 * 60) // 60, second=self._period_offset.seconds % 60, ) elif self._period == HOURLY: async_track_time_change( self.opp, self._async_reset_meter, minute=self._period_offset.seconds // 60, second=self._period_offset.seconds % 60, ) elif self._period in [ DAILY, WEEKLY, MONTHLY, BIMONTHLY, QUARTERLY, YEARLY ]: async_track_time_change( self.opp, self._async_reset_meter, hour=self._period_offset.seconds // 3600, minute=self._period_offset.seconds % 3600 // 60, second=self._period_offset.seconds % 3600 % 60, ) async_dispatcher_connect(self.opp, SIGNAL_RESET_METER, self.async_reset_meter) state = await self.async_get_last_state() if state: self._state = Decimal(state.state) self._unit_of_measurement = state.attributes.get( ATTR_UNIT_OF_MEASUREMENT) self._last_period = state.attributes.get(ATTR_LAST_PERIOD) self._last_reset = dt_util.as_utc( dt_util.parse_datetime(state.attributes.get(ATTR_LAST_RESET))) if state.attributes.get(ATTR_STATUS) == COLLECTING: # Fake cancellation function to init the meter in similar state self._collecting = lambda: None @callback def async_source_tracking(event): """Wait for source to be ready, then start meter.""" if self._tariff_entity is not None: _LOGGER.debug("<%s> tracks utility meter %s", self.name, self._tariff_entity) async_track_state_change_event(self.opp, [self._tariff_entity], self.async_tariff_change) tariff_entity_state = self.opp.states.get(self._tariff_entity) self._change_status(tariff_entity_state.state) return _LOGGER.debug("<%s> collecting from %s", self.name, self._sensor_source_id) self._collecting = async_track_state_change_event( self.opp, [self._sensor_source_id], self.async_reading) self.opp.bus.async_listen_once(EVENT_OPENPEERPOWER_START, async_source_tracking)
async def get(self, request, datetime=None): """Return history over a period of time.""" timer_start = time.perf_counter() if datetime: datetime = dt_util.parse_datetime(datetime) if datetime is None: return self.json_message("Invalid datetime", HTTP_BAD_REQUEST) now = dt_util.utcnow() one_day = timedelta(days=1) if datetime: start_time = dt_util.as_utc(datetime) else: start_time = now - one_day if start_time > now: return self.json([]) end_time = request.query.get("end_time") if end_time: end_time = dt_util.parse_datetime(end_time) if end_time: end_time = dt_util.as_utc(end_time) else: return self.json_message("Invalid end_time", HTTP_BAD_REQUEST) else: end_time = start_time + one_day entity_ids = request.query.get("filter_entity_id") if entity_ids: entity_ids = entity_ids.lower().split(",") include_start_time_state = "skip_initial_state" not in request.query opp = request.app["opp"] result = await opp.async_add_job( get_significant_states, opp, start_time, end_time, entity_ids, self.filters, include_start_time_state, ) result = list(result.values()) if _LOGGER.isEnabledFor(logging.DEBUG): elapsed = time.perf_counter() - timer_start _LOGGER.debug("Extracted %d states in %fs", sum(map(len, result)), elapsed) # Optionally reorder the result to respect the ordering given # by any entities explicitly included in the configuration. if self.use_include_order: sorted_result = [] for order_entity in self.filters.included_entities: for state_list in result: if state_list[0].entity_id == order_entity: sorted_result.append(state_list) result.remove(state_list) break sorted_result.extend(result) result = sorted_result return await opp.async_add_job(self.json, result)