![]() |
|
Scripting: Request via API and JSON format file processing - Printable Version +- LogicMachine Forum (https://forum.logicmachine.net) +-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1) +--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8) +--- Thread: Scripting: Request via API and JSON format file processing (/showthread.php?tid=5192) |
Scripting: Request via API and JSON format file processing - nisagnel - 06.01.2024 Hello, I am reaching out to you because I would like to create a Lua script on my Wyser for KNX (Schneider) to make a request to capture the outdoor temperature from my weather station via the Ecowitt website. Ecowitt provides an API for making such requests. I tried to set it up directly on the machine, but I couldn't make it work. As a result, I ran a script on my PC running Linux because it's easier to use the standard output. To make it work, I had to install additional packages: lua-socket, lua-socket, lua-socket. Below is the script that works on my PC (except the KNX part at the bottom) but does not work on the LogicMachine. Now, I am facing a portability issue to this KNX supervisor. Could someone help me? I believe I am not very far from achieving my goal. Thank you in advance. NiSAGNEL Code: --I left in comments what was useful to me for development on my PC
json = require('json')
ltn12 = require('ltn12')
https = require('ssl.https')
-- Extraire les variables de l'URL
local applicationKey = 'MyApplication-Key'
local apiKey = 'MyAPI-Key'
local MacAdd = 'Mon Adresse MAC'
local TempUnit = '1' -- Temperature Unit 1 = °C
local Research = 'outdoor.temperature'
-- URL complète avec les paramètres
local url = 'https://api.ecowitt.net/api/v3/device/real_time?application_key=' .. applicationKey .. '&api_key=' .. apiKey .. '&mac=' .. MacAdd .. '&temp_unitid=' .. TempUnit .. '&call_back=' .. Research
-- Tableau pour stocker la réponse HTTP
local resp = {}
-- Effectuer la requête HTTPS
local res, code, headers, status = https.request{
url = url,
method = 'GET',
sink = ltn12.sink.table(resp),
}
-- Variable pour les erreurs de requetes
local LocalCountError = '1'
-- Afficher le code de statut et la réponse brute pour le débogage
-- print("Code de statut:", code)
-- print("Réponse brute:", table.concat(resp))
-- Vérifier le code de statut de la réponse
if code == 200 then
-- Concaténer la réponse HTTP
resp = table.concat(resp)
-- Décoder la réponse JSON
local data = json.decode(resp)
-- Afficher la réponse JSON brute pour le débogage
-- print("Raw JSON response:", resp)
-- Vérifier si la réponse est un objet JSON valide
if data then
-- Vérifier si le champ 'msg' est 'success'
if data.msg == "success" then
-- Extraire la valeur de la température
local tempExt = tonumber(data.data.outdoor.temperature.value)
if tempExt then
-- print(Research .. " : " .. tempExt .. " ℃")
LocalCountError = '0'
else
-- print("Impossible d'extraire la température.")
LocalCountError = LocalCountError + 1
end
else
-- print("Erreur dans la réponse JSON : " .. data.msg)
LocalCountError = LocalCountError + 10
end
else
-- print("Réponse JSON invalide.")
LocalCountError = LocalCountError + 100
end
else
print("La requête HTTPS a échoué. Code de statut : " .. code)
LocalCountError = LocalCountError + 1000
end
-- Error Management
-- Read Error on KNX address
local Error = tonumber(grp.read('32/3/254')) or 999
if LocalCountError ~= 0 then
Error = Error + 1
if Error > 5 then
tempExt = '99'
end
else
Error = 0
end
-- Send to KNX Address Error
grp.write('32/3/254', Error)
-- Send to KNX Address Valeur de Température
grp.write('32/3/1', tempExt)RE: Scripting: Request via API and JSON format file processing - nisagnel - 06.01.2024 Hello, I found a way to make my script verbose to better understand what is happening by redirecting messages to the logs. After the HTTPS request, I inserted the following line of code: Code: log("Status code:", code)Code: * arg: 1
* string: Status code:
* arg: 2
* string: wantreadThank you, NiSAGNEL RE: Scripting: Request via API and JSON format file processing - nisagnel - 07.01.2024 Hello, I had misunderstood... regarding my issue. Upon checking, I realized that my firewall was not allowing traffic from WISER for KNX to the Ecowitt site. I am updating the code; someone might find it useful or improve it. This code allows querying the Ecowitt site through APIs with the purpose of acquiring the value from a temperature sensor. NiSAGNEL Code: json = require('json')
ltn12 = require('ltn12')
https = require('ssl.https')
--Déclaration Variable erreur
local LocalCountError = tonumber(0)
LocalCountError = 0
-- Read Error on KNX address
local Error = tonumber(grp.read('32/3/254')) or 2
-- Extraire les variables de l'URL
local applicationKey = 'MyApplication-Key'
local apiKey = 'MyAPI-Key'
local MacAdd = 'My MAC Adresse'
local TempUnit = '1' -- Temperature Unit 1 = °C
local Research = 'outdoor.temperature'
-- URL complète avec les paramètres
local url = 'https://api.ecowitt.net/api/v3/device/real_time?application_key=' .. applicationKey .. '&api_key=' .. apiKey .. '&mac=' .. MacAdd .. '&temp_unitid=' .. TempUnit .. '&call_back=' .. Research
-- Tableau pour stocker la réponse HTTP
local resp = {}
-- Effectuer la requête HTTPS
local res, code, headers, status = https.request{
url = url,
method = 'GET',
sink = ltn12.sink.table(resp),
}
-- Vérifier le code de statut de la réponse
if code == 200 then
-- Concaténer la réponse HTTP
resp = table.concat(resp)
-- Décoder la réponse JSON
local data = json.decode(resp)
-- Vérifier si la réponse est un objet JSON valide
if data then
-- Vérifier si le champ 'msg' est 'success'
if data.msg == "success" then
-- Extraire la valeur de la température
-- local tempExt = tonumber(data.data.outdoor.temperature.value)
local tempExt = string.format("%.2f", data.data.outdoor.temperature.value)
if tempExt then -- OK
-- print(Research .. " : " .. tempExt .. " ℃")
grp.write('32/3/1', tempExt)
LocalCountError = 0
else
-- print("Impossible d'extraire la température.")
LocalCountError = LocalCountError + 1
end
else
-- print("Erreur dans la réponse JSON : " .. data.msg)
LocalCountError = LocalCountError + 10
end
else
-- print("Réponse JSON invalide.")
LocalCountError = LocalCountError + 100
end
else
print("La requête HTTPS a échoué. Code de statut : " .. code)
LocalCountError = LocalCountError + 1000
end
-- Error Management
-- In case of error
if LocalCountError > 0 then
Error = Error + 1
if Error > 5 then
tempExt = '99'
end
else
Error = 0
end
-- Send to KNX Address Error
grp.write('32/3/254', Error)NiSAGNEL RE: Scripting: Request via API and JSON format file processing - admin - 08.01.2024 You should use grp.getvalue() instead of grp.read(). grp.read() only sends a read telegram, it does not return the actual value. |