Files
ad-nix/apps/hello_world/weather.py
2024-08-27 19:14:26 -05:00

100 lines
3.4 KiB
Python

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)