SONOS_Remote_v1.0.1

Hi Hoggle,
das klappt, danke.

Vom OW-VD bekomme ich aber nur Werte wie heute früh “fog” und heute abend “rain”.
Diese hast Du in Deinem Script ja nicht “übersetzt”. Daher vermute ich, Du erhältst ausführlichere Infos, oder?

PS: Kannst Du mir einen LUA-Editor empfehlen? (für Mac)

Hi, schön zu hören.

grundsätzlich kannst Du bei den ifelse jedes weitere Wording “übersetzen”:

elseif weather == "few clouds" then 
      weather_de = "mit ein paar Wolken."

Da brauchst Du nur beliebige elseif-Zeilen ergänzen.

Der Wert kommt letztlich aus dem VD über
local weather=ajson.weather[1].description
in Zeile 15. Ich kann Dir aber nicht mehr sagen, ob das das Original war oder eine Anpassung… :slight_smile:

VG Hoggle

Ja, das hab ich mir schon gedacht :slight_smile:
Wunderte mich nur, dass meine Wetter-Meldungen viel kürzer sind als Deine (ab Zeile 57).
Hab den Fehler gefunden: ich hatte die Zeile 53 auskommentiert und die (ich vermute) originale Zeile 52 noch aktiv.
Habe ich gerade geändert, bekomme aber nun:

[DEBUG] 21:13:10: 10,1
[DEBUG] 21:13:10: nil
[DEBUG] 21:13:10: nil
[DEBUG] 21:13:10: line 95: attempt to concatenate local ‘weather_de’ (a nil value)

PS: Kannst Du mir einen LUA-Editor empfehlen? (für Mac)

Wo wird denn die globale Variable “weather” erzeugt?

Wie in den Kommentaren:

ZeroBraneStudio

Im Update-Button des VDs habe ich:

selfId = fibaro:getSelfId()
local id = fibaro:get(fibaro:getSelfId(), "IPAddress")

HC3 = Net.FHttp("api.openweathermap.org") 
danem, statusm = HC3:GET("/data/2.5/weather?q="..id.."&units=metric&APPID=xxxxxxxxxxxx")
danef, statusf = HC3:GET("/data/2.5/forecast?q="..id.."&units=metric&APPID=xxxxxxxxxxxx")

local ajson=json.decode(danem) 
local tempmin=ajson.main.temp_min
local tempmax=ajson.main.temp_max
local pressure=ajson.main.pressure
local humidity=ajson.main.humidity
local city=ajson.name
local wind=ajson.wind.speed
local weather=ajson.weather[1].description

local tm=ajson.dt

local ajsonf=json.decode(danef) 
local n
local t

for i = 1,5 do
  t = ajsonf.list[i].dt
  if t > tm then
  	n = i
    break
  end
end

local ftempmin=ajsonf.list[n].main.temp_min
local ftempmax=ajsonf.list[n].main.temp_max
local fpressure=ajsonf.list[n].main.pressure
local fhumidity=ajsonf.list[n].main.humidity
local fwind=ajsonf.list[n].wind.speed

if ftempmin > tempmin then
  fibaro:call(selfId,"setProperty","ui.Label1.value", string.format("%3.1f°C(↑%3.1f)", tempmin, ftempmin))
elseif ftempmin < tempmin then
  fibaro:call(selfId,"setProperty","ui.Label1.value", string.format("%3.1f°C(↓%3.1f)", tempmin, ftempmin))
else
  fibaro:call(selfId,"setProperty","ui.Label1.value", string.format("%3.1f°C(-)", tempmin))
end

if ftempmax > tempmax then
  fibaro:call(selfId,"setProperty","ui.Label2.value", string.format("%3.1f°C(↑%3.1f)", tempmax, ftempmax))
elseif ftempmax < tempmax then
  fibaro:call(selfId,"setProperty","ui.Label2.value", string.format("%3.1f°C(↓%3.1f)", tempmax, ftempmax))
else
  fibaro:call(selfId,"setProperty","ui.Label2.value", string.format("%3.1f°C(-)", tempmax))
end

if fpressure > pressure then
  fibaro:call(selfId,"setProperty","ui.Label3.value",string.format("%dhPa(↑%d)", pressure, fpressure))
elseif fpressure < pressure then
  fibaro:call(selfId,"setProperty","ui.Label3.value",string.format("%dhPa(↓%d)", pressure, fpressure))
else
  fibaro:call(selfId,"setProperty","ui.Label3.value",string.format("%dhPa(-)", pressure))
end

if fhumidity > humidity then
  fibaro:call(selfId,"setProperty","ui.Label4.value",string.format("%d%s(↑%d)", humidity, "%", fhumidity))
elseif fhumidity < humidity then
  fibaro:call(selfId,"setProperty","ui.Label4.value",string.format("%d%s(↓%d)", humidity, "%", fhumidity))
else
  fibaro:call(selfId,"setProperty","ui.Label4.value",string.format("%d%s(-)", humidity, "%"))
end

if fwind > wind then
  fibaro:call(selfId,"setProperty","ui.Label5.value",string.format("%4.1fm/s(↑%4.1f)", wind, fwind))
elseif fwind < wind then
  fibaro:call(selfId,"setProperty","ui.Label5.value",string.format("%4.1fm/s(↓%4.1f)", wind, fwind))
else
  fibaro:call(selfId,"setProperty","ui.Label5.value",string.format("%4.1fm/s(-)", wind))
end
  
  fibaro:call(selfId,"setProperty","ui.Label6.value",city)
  
  fibaro:call(selfId,"setProperty","ui.Label91.value",weather)
	fibaro:setGlobal("OW_Weather", weather)
--------
function setDevicePropertyValue(id, label, value)
  fibaro:call(id, "setProperty", "ui."..label..".value", value)
end

--Date = os.date("%Y-%m-%d %H:%M:%S", os.time())
Date = os.date("%d-%m-%Y %H:%M:%S", os.time())
setDevicePropertyValue(selfId, "DateUpdate",Date)

fibaro:debug("Durchgelaufen")

Hier sind Zeile 15 und 80 relevant

??? Der sieht bei mir so aus:

-- Skript übersetzt und Fehlerkorrekturen eingebaut by boomx #siio
-- Dank an die Autoren Jakub & Damian von der polnischen Commuity @ forum.fibaro.com
  
-- DATEN ANPASSEN  
  local city="mein Ort"
  local country="de" -- en, se, ....
  local api_key="hier ist mein API-key" -- you can get your own API_KEY on this website: https://home.openweathermap.org/users/sign_up
  local lang = "de" -- en, se, ...
  
-- NETATMO-INTEGRATION (Aussensensor) - Temperatur und Luftfeuchtigkeit

  local netatmo = false
  local netatmo_id = 78 -- ID des Thermometers
  
-- VARIABLE für Wind (netatmo oder Z-Weather)

  local wind_var = false
  local var_name = 'wind_zweahter'
  
-- AB HIER NICHTS MEHR ÄNDERN

  local thisdevice = fibaro:getSelfId() 
  local cHM = os.date("%H:%M")
  local sunRise = fibaro:getValue(1, "sunriseHour")
  local sunSet = fibaro:getValue(1, "sunsetHour")
  local noc = (cHM > sunSet or cHM < sunRise)
  local weather_array = {[200] = 47, [201] = 45, [202] = 45, [210] = 38, [211] = 4, [212] = 3, [221] = 4, [230] = 9, [231] = 9, [232] = 9, [300] = 9, [301] = 9, [302] = 9, [310] = 11, [311] = 10, [312] = 6, [321] = 9, [500] = 40, [501] = 40, [502] = 12, [503] = 12, [504] = 12, [511] = 10, [520] = 12, [521] = 12, [522] = 12, [600] = 14, [601] = 16, [602] = 13, [611] = 5, [621] = 19, [701] = 21, [711] = 22, [721] = 20, [731] = 19, [741] = 21, [804] = 26, [900] = 0, [901] = 1, [902] = 2, [903] = 25, [904] = 36, [905] = 24, [906] = 17, [950] = 3200, [952] = 12, [953] = 12, [954] = 12, [955] = 12, [956] = 12, [957] = 24, [958] = 24, [959] = 2, [960] = 4, [961] = 4, [962] = 2, [800] = 32, [801] = 30, [802] = 30, [803] = 28, [951] = 34} 
  if noc then weather_array = {[800] = 31, [801]= 29, [802] = 29, [803] = 27, [951] = 33} end 
  local city = string.gsub(city," ","+")

-- connect to OpenWeatherMap:
  fibaro:debug('Verbindung zur API wird aufgebaut...')
  OWM = Net.FHttp("api.openweathermap.org") 
  data, status = OWM:GET("/data/2.5/weather?q="..city..","..country.."&units=metric&lang="..lang.."&APPID="..api_key) 
  if tonumber(status) < 300 and status ~= nil then 
    --fibaro:debug(data)
    ajson=json.decode(data)
    -- Stadt:
    city_=ajson.name..", "..ajson.sys.country
    fibaro:debug('Wetterdaten für ' ..city_.. ' abgefragt.')
    --Wetter
    pogo=ajson.weather[1].description
    fibaro:debug('Wetter: ' ..pogo)
    pogoId=tonumber(ajson.weather[1].id)
    weather_ = weather_array[pogoId]
    if weather_ == nil then weather_ = 3200 end;
    fibaro:debug('ConditionCode: ' ..weather_)
    --Temperatur
    if (netatmo == false) then
      fibaro:debug('Keine netatmo-Integration')
      tempmin=math.floor(ajson.main.temp_min)
      tempmin = tonumber(tempmin .. ".00")
    else
      fibaro:debug('netatmo-Integration aktiv')
      tempmin = tonumber(fibaro:getValue(netatmo_id, "value"))
    end
    fibaro:debug('Temperatur: ' ..tempmin.. ' °')
    --Luftfeuchtigkeit
    if (netatmo == false) then
      fibaro:debug('Keine netatmo-Integration')
      hum=ajson.main.humidity 
      hum = tonumber(hum .. ".00") 
    else
      fibaro:debug('netatmo-Integration aktiv')
      hum = tonumber(fibaro:getValue(netatmo_id + 1, "value"))
    end
    fibaro:debug('Luftfeuchtigkeit: ' ..hum.. ' %')
    --Luftdruck
    pressure=math.floor(ajson.main.pressure)
    fibaro:debug('Luftdruck: ' ..pressure.. ' hPa')
    --Windstärke
    if (netatmo == false) then
      fibaro:debug('Keine Variable für Wind gesetzt')
      wind_speed=math.floor(ajson.wind.speed * 3.6)
      wind_speed = tonumber(wind_speed .. ".00")
      fibaro:debug('Windstärke: ' ..wind_speed.. ' km/h')
    else
      fibaro:debug('Variable für Wind gesetzt')
      wind_speed = fibaro:getGlobal('wind_zweather')
      fibaro:debug('Windstärke: ' ..wind_speed.. ' km/h')
    end
    --Windrichtung
    wind_deg=math.floor(ajson.wind.deg)
    wind_deg_num = math.floor(wind_deg / 45)
    wind_deg_tab = {"N", "NE", "E", "SE", "S", "SW", "W", "NW"}
    wind_direction = wind_deg_tab[wind_deg_num]
    if (wind_direction == nil) then wind_direction = '-' end
    fibaro:debug('Windrichtung: ' ..wind_direction)
        
-- Write data to label of VD:
    fibaro:call(thisdevice, "setProperty", "ui.Label1.value", tempmin.." °C"); 
    fibaro:call(thisdevice, "setProperty", "ui.Label2.value", hum.." %"); 
    fibaro:call(thisdevice, "setProperty", "ui.Label3.value", wind_speed.." km/h, "..wind_direction); 
    fibaro:call(thisdevice, "setProperty", "ui.Label4.value", pressure.." hPa"); 
    fibaro:call(thisdevice, "setProperty", "ui.Label5.value", city_); 
-- Show in UI HC2 (browser)
    VD = Net.FHttp("127.0.0.1", 11111); 
    r,s,e = VD:PUT("/api/devices", '{ "id": 3, "properties": {"Temperature": ' .. tempmin .. ', "Humidity": ' .. hum .. ', "ConditionCode": ' .. weather_ .. ', "Wind": ' .. wind_speed .. '}}'); 
    if tonumber(e) == 0 then 
      fibaro:debug("Wetterdaten in der API aktualisiert."); 
    else 
      fibaro:debug("Aktualisierung der Wetterdaten fehlerhaft!!!"); 
    end 
  else 
    fibaro:debug("Fehler beim Aufruf der OpenWeatherMap-API. Status: #"..status); 
  end

Das VD stammt von hier:
https://www.siio.de/heizenenergiesparen/wetteranzeige-im-homecenter-2-mit-eigenen-werten-fuellen/

Okay, die varianten sind eben vielfältig…

Geh mal hier hin:
https://www.siio.de/fibaro-downloads-virtuelle-module-szenen/
und suche nach “open”

Okay, spuckt bei mir leider keine Werte aus. Also das GUI des VD bleibt leer.
Auf den ersten Blick fällt mir auf, dass Du in Zeile 5+6 noch eine “APPID” hinten dran stehen hast. Die Zeile endet bei mir mit …=metric")
Muss die OW-API-ID dort hin?

Korrekt vermutet :slight_smile:
Werte sind nun drin, aber die TTS-Szene kennt die Variable “weather_de” immernoch nicht :,-(

[DEBUG] 23:32:17: line 95: attempt to concatenate local ‘weather_de’ (a nil value)

Hoggle, hast Du ne Idee?

Am Handy werden mir die Zeilennummern nicht dargestellt. Ist das der Debug ?
Wie ist der debug für weather?

Das ist die TTS-Szene

…ist von Dir – dies steht oben in Zeile 21-23
– Funktion zur Ermittlung des Datums.
– Version 1.0
– Copyright © 2015 Nicolas Dörig

Und der Debug ist:
[DEBUG] 06:50:46: 8,4
[DEBUG] 06:50:46: nil
[DEBUG] 06:50:46: nil
[DEBUG] 06:50:46: line 95: attempt to concatenate local ‘weather_de’ (a nil value)

Zeile 95 ist:
message = "Es ist "… germanDate('l') …" und draussen sind "…tempcurr…" Grad."…weather_de…".";

mach da testweise mal raus:
message = "Es ist "… germanDate('l') …" und draussen sind "…tempcurr…" Grad.";

dann bekomme ich:

[DEBUG] 11:13:28: 10,1
[DEBUG] 11:13:28: nil
[DEBUG] 11:13:28: nil

die beiden “nil” sind ja glaub ich Ausgaben von:
Zeile 56: fibaro:debug(weather)
und
Zeile 85: fibaro:debug(weather_de)

okay, dann ersetze das mal wie folgt, damit das eindeutig ist:

fibaro:debug("Weather: "..weather)
 fibaro:debug("Weather_de: "..weather_de) 

Jetzt komm ich im Debug nur noch bis Zeile 55 (ehem. 56)
[DEBUG] 11:33:09: 10,1
[DEBUG] 11:33:09: line 55: attempt to concatenate local ‘weather’ (a nil value)

Das Script sieht mittlerweile so aus:

--[[
%% properties

%% globals
--]]

 
-- 193 is the Virtual Device ID
-- 28 is the Process button ID
 
local sid, bid = 193, 28
local temp = tostring(fibaro:getValue(178, "value"))

--local temp=tostring(fibaro:getGlobalValue("OWM_Temp"));
--fibaro:debug(temp);
tempcurr=string.gsub(temp, "%.", ",", 1);
fibaro:debug(tempcurr);

-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
-- Funktion zur Ermittlung des Datums.
-- Version 1.0
-- Copyright (c) 2015 Nicolas Dörig
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------

function germanDate( _type ) -- l=longDate("Montag, 12.September"), s=shortDate("Mo, 12.Sep 2011"), N=numericLong("12.09.2011"), n=numericShort("12.09.11")
	local longWochentag  = {'Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'}
	local shortWochentag = {'So','Mo','Di','Mi','Do','Fr','Sa'}
	local longMon        = {'Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'}
	local shortMon       = {'Jan','Feb','Mrz','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'}
	local indexTag       = os.date( "%w" ) +1
	local indexMon       = math.abs( os.date( "%m" ) )
	if _type == 's' then
		return os.date( shortWochentag[indexTag]..", %d."..shortMon[indexMon].." %Y" )
	elseif _type == 'l' then
		return os.date( longWochentag[indexTag]..", %d."..longMon[indexMon] )
	elseif _type == 'N' then
		return os.date( "%d.%m.%Y" )
	elseif _type == 'n' then
		return os.date( "%d.%m.%y" )
	end
end
--print ( 'Kurzdatum mit Wochentag\t' .. germanDate('s') )
--print ( 'Langdatum mit Wochentag\t' .. germanDate('l') )
--print ( 'Datum numerisch lang\t' .. germanDate('N') )
--print ( 'Datum numerisch kurz\t' .. germanDate('n') )

-------------------------------------------------------------------------------------------

--playTTS("de", "Guten Morgen. Es ist ".. germanDate('l') .." und draussen sind es " .. getWeather( 't' ) .." Grad " .. getWeather( 'c' ) ..". Ich starte das Radio fuer dich.", 13000, 15);

-- local weather = fibaro:getValue(3, "WeatherConditionConverted")
local weather = fibaro:getGlobal("OW_Weather")
fibaro:debug("Weather: "..weather)

local weather_de

  if weather == "overcast clouds" or weather == "cloudy" then 
      weather_de = "und es ist bewoelkt."
	elseif weather == "few clouds" then 
      weather_de = "mit ein paar Wolken."
	elseif weather == "scattered clouds" then 
      weather_de = "bei aufgelockerter Bewölkung."
	elseif weather == "broken clouds" then 
      weather_de = "bei durchbrochener Bewölkung."
	elseif weather == "light rain" then 
      weather_de = "es regnet leicht, vergiss den Schirm nicht!"
	elseif weather == "moderate rain" then 
      weather_de = "es regnet, vergiss den Schirm nicht!"
  	elseif weather == "heavy intensity rain" then 
      weather_de = "es regnet stark, vergiss den Schirm nicht!"
    elseif weather == "clear sky" then 
      weather_de = "und der Himmel ist klar."
    elseif weather == "snow" then 
      weather_de = ". Es schenit."
    elseif weather == "sleet" then 
      weather_de = ". Schneeregen."
    elseif weather == "drizzle" then 
      weather_de = ". Nieselregen."
    else
      --weather_de = "."
  	  weather_de = weather
    end

fibaro:debug("Weather_de: "..weather_de)
---------------------------------------------------------------------------
-- Create TTS params object
 
-- message = "Die aktuelle Temperatur draußen beträgt "..tempcurr.."°Celsius.",  
 
local params = {

--TTS Message

message = "Guten Morgen ... ... Es ist ".. germanDate('l') .." ... ... Draussen sind es "..tempcurr.." Grad ... "..weather_de.."...";
--message = "Es ist ".. germanDate('l') .." und draussen sind "..tempcurr.."°Celsius.".. getWeather( 'c' ) ..". Ich starte das Radio fuer dich.";

duration = 'auto';  -- Duration: "auto", xx seconds
language = "de-DE"; -- Language: see http://www.voicerss.org/api/documentation.aspx to get your language code
volume = 17;         -- Volume
}
 
local _f = fibaro
local _x ={root="x_sonos_object",load=function(b)local c=_f:getGlobalValue(b.root)if string.len(c)>0 then local d=json.decode(c)if d and type(d)=="table"then return d else _f:debug("Unable to process data, check variable")end else _f:debug("No data found!")end end,set=function(b,e,d)local f=b:load()if f[e]then for g,h in pairs(d)do f[e][g]=h end else f[e]=d end;_f:setGlobal(b.root,json.encode(f))end,get=function(b,e)local f=b:load()if f and type(f)=="table"then for g,h in pairs(f)do if tostring(g)==tostring(e or"")then return h end end end;return nil end}
-- Make a request to the remote to process params object instantly
_x:set(tostring(sid), { tts = params })
_f:call(sid, "pressButton", bid)

-- _f:call(sid, "setSlider", "7", volume); -- Lautstärke festlegen
-- _f:call(sid, "pressButton", "1"); -- Radio starten
-- _f:debug("1: Starte Radio");