Sollte dann pluginname oder „bezeichner“ angegeben werden..? Bei mir gibt es die Methode offenbar aber es wird nichts gefunden
Ankündigung
Einklappen
Keine Ankündigung bisher.
Support-Thread zum OpenWeatherMap Plugin
Einklappen
X
-
Ich bekomme irgendwie recht viele API Fehler.. soweit ich das gesehen habe, müsste man Zahlungsdaten hinterlegen, um onecall Abfragen zu nutzen. Kommt für mich nicht in Frage, insofern fällt es mir auch schwer, das Problem zu fixen.
Aus meiner Sicht sollte die Eval-Sache aus dem Struct raus und direkt ins Plugin mit einem zusätzlichen Part für current/wind_gust/beaufort
Ich hab mal einen PR dazu erstellt, müsste aber bitte jemand testen.Zuletzt geändert von Onkelandy; 13.12.2024, 14:27.
Kommentar
-
Ich versuche gerade, mich da etwas einzuarbeiten... ohne V3.0-Account bekomme ich in den structs gar keine Daten, im Web-Interface kann ich mit "alle downloaden" aber durchaus Daten über die V2.5-API bekommen.
Verstehe ich das richtig, dass die Structs alle auf den Onecall-API aufbauen? Also müsste man die structs anpassen, wenn man keine V3.0 nutzen möchte?
Und wenn ich nur die owm_raw_files haben möchte, wird gar nicht gelesen, weil die von keinem Item gefragt sind...??Zuletzt geändert von Morg; 24.06.2025, 11:15.
Kommentar
-
Ich hatte mir mal visualcrossing angesehen aber mich dann später für open-meteo entschieden. Ich brauche nur die zukünftigen Temperaturen der nächsten 48 Stunden und das reicht so aus. Allerdings habe ich kein Plugin im Einsatz sondern parse schlicht ein wenig das Ergebnis der API in einer Logik.
Kommentar
-
Morg ,
kannst Du das Plugin so konfigurierbar machen, dass es das Onecall-API v3 und alternativ das kostenlose API v2.5 unterstützt? Letzteres benötigt halt 2 Aufrufe für current und forecast (plus ggfls. weitere je nach benötigten Daten). Wenn man in den Plugin-Versionen weit genug zurück geht, müsste sogar noch der Code auffindbar sein, der vor der Einführung des Onecall-API v2.5 gültig war.
Für diejenigen, die v3 nutzen und aus Kostengründen die Anzahl der API-Aufrufe begrenzen wollen, wäre es m.E. sinnvoll, die Wetter-Widgets in smartVISU so zu erweitern, dass sie vollständig aus items versorgt werden können und die Visu dann keine eigenen Aufrufe mehr macht. Bei weather.current geht das ja schon, nur findet der API-Aufruf trotzdem noch statt. Dazu wäre eine standardisierte item-Benennung hilfreich, über die wir uns noch verständigen müssten.
Gruß
Wolfram
Kommentar
-
Muss ich mal schauen. Ich hab immer noch das database-Plugin am Wickel (wobei ich da momentan ehrlicherweise nicht wirklich weiter komme...) und denke noch auf lib.orb rum.
Das Aufwändigste an der Flexibilisierung des Plugins ist, die passenden json-Pfade zu Wetterdatenpunkten zu finden und je nach Abfrage zu setzen. Dann könnte das Plugin standardisierte Wetteritems anbieten.
Alternativ wäre wirklich nur der Aufruf (und die data_source-Parameter) anzupassen, und jeder muss weiter mit den Pfad-Suchmustern arbeiten. Das braucht dann (s.o.) entsprechend aufwändige structs und ist aus meiner Sicht daher auch nicht schön...
Ich habe jetzt openmeteo ausprobiert und fülle (und erstelle) den Itembaum einmal am Tag mit einer Logik, dann passen die Benennungen der Vorhersageitems (.daily.d0, .daily.d1, .daily.d2... für heute, morgen, übermorgen; genauso .hourly.h001, .hourly.h002, .hourly.h003...) und man könnte mit simpler Arithmetik das passende Item finden (ich brauche eigentlich nur d0, also die Vorhersage für den aktuellen Tag).
Ist vielleicht etwas ... overpoweredaber es tut seinen Job, und wenn ich die Abrufparameter ändere, bau ich mir schnell und einfach den passenden Itembaum (Vorhersage für 150+ Stunden * jeweils 12 Items + 12 Einheiten...)
Code:#!/usr/bin/env python3 # # This file contains a logic for use with SmartHomeNG # # Name of the logic: openmeteo.py # # # get weather data and forecast from openmeteo and # - create matching item file and/or # - fill items with values # import json import requests # Startpunkte für Items (level = Einrückung * 4) base_item = 'd.wetter' base_level = 2 def walk(node, name, parent, level, method): """ dict rekursiv durchlaufen """ for key in sorted(node.keys()): method(node[key], key, parent + ('.' if parent else '') + str(name), level) if isinstance(node[key], dict): walk(node[key], key, parent + ('.' if parent else '') + str(name), level + 1, method) def print_item(node, name, parent, level): """ Item für yaml ausgeben """ def pitem(text, level): print(f'{" " * level}{text}') if type(node) is dict: print(f'{" " * level}{name}:') else: off = 0 if name.endswith('.unit'): name = 'unit' off = 1 if type(node) in (int, float): typ = "num" elif type(node) is str: typ = 'str' else: typ = 'foo' pitem(f'{name}:', level + off) pitem(f'type: {typ}', level + 1 + off) def set_item(node, name, parent, level): """ Item-Wert setzen """ if type(node) not in (str, int, float): return item = sh.return_item(f'{parent}.{name}') if item is not None: try: item(node) except Exception: pass lon = sh.env.location.lon() lat = sh.env.location.lat() base_url = "https://api.open-meteo.com/v1/forecast" # Bernd: urlparam = f"{url}?latitude={lat}&longitude={lon}¤t=temperature_2m&timezone=auto" url = f"{base_url}?latitude={lat}&longitude={lon}&daily=temperature_2m_max,temperature_2m_min,apparent_temperature_max,apparent_temperature_min,sunrise,sunset,daylight_duration,sunshine_duration,precipitation_sum,rain_sum,showers_sum&hourly=temperature_2m,relative_humidity_2m,dew_point_2m,apparent_temperature,precipitation_probability,precipitation,rain,showers,surface_pressure,visibility,evapotranspiration,et0_fao_evapotranspiration,wind_speed_10m,wind_direction_10m,uv_index,direct_radiation¤t=temperature_2m,relative_humidity_2m,apparent_temperature,precipitation,rain,showers,snowfall,cloud_cover,surface_pressure&timezone=auto" # mit timezone=auto wird eine lokale Zeit passend zu lat/lon wiedergegeben session = requests.session() response = session.get(url) num_bytes = len(response.content) if num_bytes < 50: raise LeaveLogic() json_obj = response.json() # logger.warning(f"{json_obj=}") data = {} # Abschnitte, die geparst werden for interval in ['current', 'daily', 'hourly']: j = json_obj[interval] data[interval] = {} pad = '000' # aktuellen Abschnitt parsen if isinstance(j['time'], list): pl = len(str(len(j['time']))) for idx in range(len(j['time'])): pi = pad + str(idx) data[interval][interval[0] + pi[-pl:]] = {k: v[idx] for k, v in j.items()} else: data[interval] = j.copy() # Einheiten für aktuellen Abschnitt parsen ju = json_obj[interval + '_units'] attrs = list(ju.keys()) if 'time' not in data[interval]: e_len = len(data[interval]) pl = len(str(e_len)) for attr in attrs: for idx in range(e_len): pi = pad + str(idx) data[interval][interval[0] + pi[-pl:]][attr + '.unit'] = ju.get(attr, '') else: for attr in attrs: data[interval][attr + '.unit'] = ju.get(attr, '') # Item-Definition erzeugen (auf Konsole ausgeben) # walk(data, base_item, '', base_level, print_item) # Item-Werte befüllen walk(data, base_item, '', base_level, set_item)
Zuletzt geändert von Morg; 26.06.2025, 23:01.
Kommentar
Kommentar