changes for use_dictionary_unpacking
This commit is contained in:
@@ -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
131
apps/hello_world/weather.py
Normal 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,
|
||||||
|
# )
|
||||||
Submodule apps/room_control updated: 0f58ac4cc6...1b3fc4afb7
@@ -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))
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user