|
29 | 29 | from typing import List
|
30 | 30 |
|
31 | 31 | import babel.dates
|
| 32 | +import requests |
| 33 | +from ping3 import ping |
32 | 34 | from psutil._common import bytes2human
|
33 | 35 | from uptime import uptime
|
34 | 36 |
|
|
42 | 44 | WLO_CARD = config.CONFIG_DATA["config"].get("WLO", "")
|
43 | 45 | HW_SENSORS = config.CONFIG_DATA["config"].get("HW_SENSORS", "AUTO")
|
44 | 46 | CPU_FAN = config.CONFIG_DATA["config"].get("CPU_FAN", "AUTO")
|
| 47 | +PING_DEST = config.CONFIG_DATA["config"].get("PING", "127.0.0.1") |
45 | 48 |
|
46 | 49 | if HW_SENSORS == "PYTHON":
|
47 | 50 | if platform.system() == 'Windows':
|
@@ -824,3 +827,104 @@ def stats():
|
824 | 827 | theme_data = config.THEME_DATA['STATS']['CUSTOM'][custom_stat].get("LINE_GRAPH", None)
|
825 | 828 | if theme_data is not None and last_values is not None:
|
826 | 829 | display_themed_line_graph(theme_data=theme_data, values=last_values)
|
| 830 | + |
| 831 | + |
| 832 | +class Weather: |
| 833 | + @staticmethod |
| 834 | + def stats(): |
| 835 | + WEATHER_UNITS = {'metric': '°C', 'imperial': '°F', 'standard': '°K'} |
| 836 | + |
| 837 | + weather_theme_data = config.THEME_DATA['STATS'].get('WEATHER', {}) |
| 838 | + wtemperature_theme_data = weather_theme_data.get('TEMPERATURE', {}).get('TEXT', {}) |
| 839 | + wfelt_theme_data = weather_theme_data.get('TEMPERATURE_FELT', {}).get('TEXT', {}) |
| 840 | + wupdatetime_theme_data = weather_theme_data.get('UPDATE_TIME', {}).get('TEXT', {}) |
| 841 | + wdescription_theme_data = weather_theme_data.get('WEATHER_DESCRIPTION', {}).get('TEXT', {}) |
| 842 | + whumidity_theme_data = weather_theme_data.get('HUMIDITY', {}).get('TEXT', {}) |
| 843 | + |
| 844 | + activate = True if wtemperature_theme_data.get("SHOW") or wfelt_theme_data.get( |
| 845 | + "SHOW") or wupdatetime_theme_data.get("SHOW") or wdescription_theme_data.get( |
| 846 | + "SHOW") or whumidity_theme_data.get("SHOW") else False |
| 847 | + |
| 848 | + if activate: |
| 849 | + temp = None |
| 850 | + feel = None |
| 851 | + time = None |
| 852 | + humidity = None |
| 853 | + if HW_SENSORS in ["STATIC", "STUB"]: |
| 854 | + temp = "17.5°C" |
| 855 | + feel = "(17.2°C)" |
| 856 | + desc = "Cloudy" |
| 857 | + time = "@15:33" |
| 858 | + humidity = "45%" |
| 859 | + else: |
| 860 | + # API Parameters |
| 861 | + lat = config.CONFIG_DATA['config'].get('WEATHER_LATITUDE', "") |
| 862 | + lon = config.CONFIG_DATA['config'].get('WEATHER_LONGITUDE', "") |
| 863 | + api_key = config.CONFIG_DATA['config'].get('WEATHER_API_KEY', "") |
| 864 | + units = config.CONFIG_DATA['config'].get('WEATHER_UNITS', "metric") |
| 865 | + lang = config.CONFIG_DATA['config'].get('WEATHER_LANGUAGE', "en") |
| 866 | + deg = WEATHER_UNITS.get(units, '°?') |
| 867 | + if api_key: |
| 868 | + url = f'https://api.openweathermap.org/data/3.0/onecall?lat={lat}&lon={lon}&exclude=minutely,hourly,daily,alerts&appid={api_key}&units={units}&lang={lang}' |
| 869 | + try: |
| 870 | + response = requests.get(url) |
| 871 | + if response.status_code == 200: |
| 872 | + data = response.json() |
| 873 | + temp = f"{data['current']['temp']:.1f}{deg}" |
| 874 | + feel = f"({data['current']['feels_like']:.1f}{deg})" |
| 875 | + desc = data['current']['weather'][0]['description'].capitalize() |
| 876 | + humidity = f"{data['current']['humidity']:.0f}%" |
| 877 | + now = datetime.datetime.now() |
| 878 | + time = f"@{now.hour:02d}:{now.minute:02d}" |
| 879 | + else: |
| 880 | + logger.error(f"Error {response.status_code} fetching OpenWeatherMap API:") |
| 881 | + # logger.error(f"Response content: {response.content}") |
| 882 | + # logger.error(response.text) |
| 883 | + desc = response.json().get('message') |
| 884 | + except Exception as e: |
| 885 | + logger.error(f"Error fetching OpenWeatherMap API: {str(e)}") |
| 886 | + desc = "Error fetching OpenWeatherMap API" |
| 887 | + else: |
| 888 | + logger.warning("No OpenWeatherMap API key provided in config.yaml") |
| 889 | + desc = "No OpenWeatherMap API key" |
| 890 | + |
| 891 | + if activate: |
| 892 | + # Display Temperature |
| 893 | + display_themed_value(theme_data=wtemperature_theme_data, value=temp) |
| 894 | + # Display Temperature Felt |
| 895 | + display_themed_value(theme_data=wfelt_theme_data, value=feel) |
| 896 | + # Display Update Time |
| 897 | + display_themed_value(theme_data=wupdatetime_theme_data, value=time) |
| 898 | + # Display Humidity |
| 899 | + display_themed_value(theme_data=whumidity_theme_data, value=humidity) |
| 900 | + # Display Weather Description (or error message) |
| 901 | + display_themed_value(theme_data=wdescription_theme_data, value=desc) |
| 902 | + |
| 903 | + |
| 904 | +class Ping: |
| 905 | + last_values_ping = [] |
| 906 | + |
| 907 | + @classmethod |
| 908 | + def stats(cls): |
| 909 | + theme_data = config.THEME_DATA['STATS']['PING'] |
| 910 | + |
| 911 | + delay = ping(dest_addr=PING_DEST, unit="ms") |
| 912 | + |
| 913 | + save_last_value(delay, cls.last_values_ping, |
| 914 | + theme_data['LINE_GRAPH'].get("HISTORY_SIZE", DEFAULT_HISTORY_SIZE)) |
| 915 | + # logger.debug(f"Ping delay: {delay}ms") |
| 916 | + |
| 917 | + display_themed_progress_bar(theme_data['GRAPH'], delay) |
| 918 | + display_themed_radial_bar( |
| 919 | + theme_data=theme_data['RADIAL'], |
| 920 | + value=int(delay), |
| 921 | + unit="ms", |
| 922 | + min_size=6 |
| 923 | + ) |
| 924 | + display_themed_value( |
| 925 | + theme_data=theme_data['TEXT'], |
| 926 | + value=int(delay), |
| 927 | + unit="ms", |
| 928 | + min_size=6 |
| 929 | + ) |
| 930 | + display_themed_line_graph(theme_data['LINE_GRAPH'], cls.last_values_ping) |
0 commit comments