changes for use_dictionary_unpacking

This commit is contained in:
John Lancaster
2024-08-27 00:42:19 -05:00
parent de31b6ca5a
commit a8e0b53c53
5 changed files with 136 additions and 4 deletions

View File

@@ -1,6 +1,6 @@
appdaemon: appdaemon:
uvloop: True uvloop: True
# use_dictionary_unpacking: True use_dictionary_unpacking: True
# check_app_updates_profile: True # check_app_updates_profile: True
import_method: expert import_method: expert

131
apps/hello_world/weather.py Normal file
View File

@@ -0,0 +1,131 @@
from datetime import timedelta
from pathlib import Path
import aiohttp
import yaml
from appdaemon.plugins.hass.hassapi import Hass
def convert_vals_dict(vals):
weather_codes = {
0: 'Unknown',
1000: 'Clear',
1001: 'Cloudy',
1100: 'Mostly Clear',
1101: 'Partly Cloudy',
1102: 'Mostly Cloudy',
2000: 'Fog',
2100: 'Light Fog',
3000: 'Light Wind',
3001: 'Wind',
3002: 'Strong Wind',
4000: 'Drizzle',
4001: 'Rain',
4200: 'Light Rain',
4201: 'Heavy Rain',
5000: 'Snow',
5001: 'Flurries',
5100: 'Light Snow',
5101: 'Heavy Snow',
6000: 'Freezing Drizzle',
6001: 'Freezing Rain',
6200: 'Light Freezing Rain',
6201: 'Heavy Freezing Rain',
7000: 'Ice Pellets',
7101: 'Heavy Ice Pellets',
7102: 'Light Ice Pellets',
8000: 'Thunderstorm',
}
return {
'cloud_coverage': int(round(vals['cloudCover'], 0)),
'condition': weather_codes[vals['weatherCode']],
'humidity': vals['humidity'],
'native_apparent_temperature': vals['temperatureApparent'],
'native_dew_point': vals['dewPoint'],
'native_precipitation_unit': 'in.',
'native_pressure': vals['pressureSurfaceLevel'],
'native_pressure_unit': 'inHg',
'native_temperature': vals['temperature'],
'native_temperature_unit': 'F',
'native_wind_gust_speed': vals['windGust'],
'native_wind_speed': vals['windSpeed'],
'native_wind_speed_unit': 'mph',
'uv_index': vals['uvIndex'],
'wind_bearing': vals['windDirection'],
}
class Weather(Hass):
def initialize(self):
with (Path(self.AD.config_dir) / 'secrets.yaml').open('r') as f:
apikey = yaml.safe_load(f)['tomorrow.io']
self.log('API key loaded')
lat = self.AD.sched.location.latitude
long = self.AD.sched.location.longitude
self.request_kwargs = {
'url': 'https://api.tomorrow.io/v4/weather/forecast',
'params': {
'apikey': apikey,
'location': f'{lat},{long}',
'timesteps': '1h',
'units': 'imperial',
},
}
if loc := self.args.get('location'):
self.request_kwargs['params']['location'] = loc
self.log(f'Updated location to {loc}', level='DEBUG')
interval = timedelta(minutes=5)
self.run_every(self.get_weather_async, 'now', interval.total_seconds())
self.log(f'Getting weather every {interval}')
async def get_weather_async(self, **kwargs):
async with aiohttp.ClientSession() as session:
async with session.get(**self.request_kwargs) as resp:
if resp.status == 200:
self.log('Got weather async', level='DEBUG')
json_data = await resp.json()
await self.publish_temp(json_data)
elif resp.status == 429:
self.log('Rate limited when getting weather', level='WARNING')
else:
self.log(f'Error getting weather async: {resp.status}', level='ERROR')
async def publish_temp(self, json_data):
vals = convert_vals_dict(json_data['timelines']['hourly'][0]['values'])
await self.set_state('weather.tomorrowio', state=vals['condition'], **vals)
# def create_sensor(self, name: str, **kwargs) -> None:
# mqtt = self.app.get_plugin_api("MQTT")
# if "friendly_name" in kwargs:
# friendly_name = kwargs["friendly_name"]
# del kwargs["friendly_name"]
# else:
# friendly_name = name
# self.mqtt_registry[name] = {"entity_id": f"sensor.{name}"}
# if "initial_value" in kwargs:
# # create the state topic first and set the value
# self.set_state(name, state=kwargs["initial_value"])
# del kwargs["initial_value"]
# config = {
# "name": friendly_name,
# "object_id": name,
# "state_topic": f"appdaemon/{name}/state",
# "value_template": "{{ value_json.state }}",
# }
# for key, value in kwargs.items():
# config[key] = value
# mqtt.mqtt_publish(
# f"homeassistant/sensor/appdaemon/{name}/config",
# json.dumps(config),
# retain=True,
# )

View File

@@ -41,6 +41,7 @@ class MotionCanceller(SceneDetector):
for handle, info in callbacks.items(): for handle, info in callbacks.items():
if info['entity'] == app.motion.sensor_entity_id and 'new=off' in info['kwargs']: if info['entity'] == app.motion.sensor_entity_id and 'new=off' in info['kwargs']:
self.cancel_listen_state(handle)
await self.AD.state.cancel_state_callback(handle, app.name) await self.AD.state.cancel_state_callback(handle, app.name)
self.log(f'Cancelled motion callback for {app.name}') self.log(f'Cancelled motion callback for {app.name}')
# self.log(json.dumps(info, indent=4)) # self.log(json.dumps(info, indent=4))

View File

@@ -65,7 +65,7 @@ class SleepSetter(Hass, Mqtt):
assert isinstance(state, float) assert isinstance(state, float)
return state return state
def handle_state(self, entity, attribute, old, new, kwargs): def handle_state(self, entity, attribute, old, new, **kwargs):
self.log(f'new state: {self.state}') self.log(f'new state: {self.state}')
if self.state: if self.state:
self.all_off() self.all_off()
@@ -77,7 +77,7 @@ class SleepSetter(Hass, Mqtt):
self.log(f'Turned on scene: {self.scene}') self.log(f'Turned on scene: {self.scene}')
# self.turn_on(self.scene) # self.turn_on(self.scene)
def handle_button(self, event_name, data, kwargs): def handle_button(self, event_name, data, **kwargs):
topic = data['topic'] topic = data['topic']
# self.log(f'Button event for: {topic}') # self.log(f'Button event for: {topic}')
try: try: