Updated version of Netatmo script with HTTPS (http is not allowed by netatmo anymore)
Task
How to get my Netatmo weather station readings into my KNX network using LogicMachine?
Things to prepare in advance
V2
v1
Use the function in your programs
Either in Event-based, Scheduled or Resident script run the function by command refresh_netatmo().
example : a scheduled script that run every minute with the content :
Matthieu
	
	
	
Task
How to get my Netatmo weather station readings into my KNX network using LogicMachine?
Things to prepare in advance
- Buy Netatmo weather station
 - Create a private app at http://dev.netatmo.com
 
- Add the following function in Common Functions or User Library
 - Fill in the script with client_id, client_secret, username and password
 - Rename object names with your own objects
 - Rename module names to match configuration in Netatmo
 
V2
Code:
require 'ltn12'
require 'socket.http'
json = require("json")
https = require 'ssl.https'
function refresh_netatmo()
  local netatmo_debug = true
  local client_id = "xxx"
  local client_secret = "xxx"
  local username = "xxx"
  local password = "xxx"
  local scope = "read_station"
  -- optional device_id
  local device_id = "xxx"
  local request_token_url = "https://api.netatmo.net/oauth2/token"
  local request_device_list = "https://api.netatmo.net/api/devicelist"
  local response_body = { }
  local export_data = {}
  if (netatmo_debug) then
    alert("netatmo start")
  end
  
  local request_body = "grant_type=password&client_id=" .. client_id .."&client_secret=" .. client_secret .. "&username=" .. username .. "&password=" .. password .. "&scope=" .. scope
  local body, code, hdrs, stat = https.request
  {
    url = request_token_url;
    method = "POST";
    headers =
    {
      ["Content-Type"] = "application/x-www-form-urlencoded";
      ["Content-Length"] = #request_body;
    };
    source = ltn12.source.string(request_body);
    sink = ltn12.sink.table(response_body);
  }
  if (code ~= 200) then
    alert("netatmo auth error : "..tostring(code)..","..tostring(body))
    return
  end
  local response_decode = json.decode(table.concat(response_body))
  local access_token = response_decode.access_token
  if (netatmo_debug) then
    alert("netatmo token %s",access_token)
  end
  -- request for all devices
  local request_body = "access_token=" .. access_token .. "&app_type=app_station"
  -- request to limit to only one device :
  -- local request_body = "access_token=" .. access_token .. "&app_type=app_station&device_id=" .. device_id
  
  local response_body = { }
  local body, code, hdrs, stat = https.request
  {
    url = request_device_list;
    method = "POST";
    headers =
    {
      ["Content-Type"] = "application/x-www-form-urlencoded";
      ["Content-Length"] = #request_body;
    };
    source = ltn12.source.string(request_body);
    sink = ltn12.sink.table(response_body);
  }
  if (code ~= 200) then
    alert("netatmo devicelist error : "..tostring(code)..","..tostring(body))
    return
  end
  local response_decode = json.decode(table.concat(response_body))
  -- Main module
  if (netatmo_debug) then
    alert("netatmo main module")
  end
  grp.write("netatmo temperature interieure",response_decode.body.devices[1].dashboard_data.Temperature,dt.float16)
  grp.write("netatmo humidite interieure",response_decode.body.devices[1].dashboard_data.Humidity,dt.scale)
  grp.write("netatmo pression",response_decode.body.devices[1].dashboard_data.Pressure,dt.uint16)
  grp.write("netatmo CO2",response_decode.body.devices[1].dashboard_data.CO2,dt.float16)
  grp.write("netatmo sonometre",response_decode.body.devices[1].dashboard_data.Noise,dt.uint8)
  grp.write("netatmo temperature interieure minimum",response_decode.body.devices[1].dashboard_data.min_temp,dt.float16)
  grp.write("netatmo temperature interieure maximum",response_decode.body.devices[1].dashboard_data.max_temp,dt.float16)
  grp.write("netatmo pression absolue",response_decode.body.devices[1].dashboard_data.AbsolutePressure,dt.uint16)
  grp.write("netatmo salon temperature",response_decode.body.devices[1].dashboard_data.Temperature,dt.float16)
  grp.write("netatmo salon humidite",response_decode.body.devices[1].dashboard_data.Humidity,dt.scale)
  grp.write("netatmo salon CO2",response_decode.body.devices[1].dashboard_data.CO2,dt.uint16)
 
  -- search for additional modules by name
  
  for index, value in ipairs(response_decode.body.modules) do
    if (netatmo_debug) then
      alert("netatmo module " .. tostring(index) .. ":" .. tostring(value.module_name))
    end
    if (value.module_name == "Pluviomètre") then
      if (netatmo_debug) then
        alert("netatmo module match pluviometre")
      end
      grp.write("netatmo pluviometre",value.dashboard_data.Rain,dt.float16)
      grp.write("netatmo pluviometre 1h",value.dashboard_data.sum_rain_1,dt.float16)
      grp.write("netatmo pluviometre 24h",value.dashboard_data.sum_rain_24,dt.float16)
    elseif (value.module_name == "Extérieur") then
      if (netatmo_debug) then
        alert("netatmo module match exterieur")
      end
      grp.write("netatmo temperature exterieure",value.dashboard_data.Temperature,dt.float16)
      grp.write("netatmo humidite exterieure",value.dashboard_data.Humidity,dt.float16)
      grp.write("netatmo temperature exterieure minimum",value.dashboard_data.min_temp,dt.float16)
      grp.write("netatmo temperature exterieure maximum",value.dashboard_data.max_temp,dt.float16)
    elseif (value.module_name == "Chambre") then
      if (netatmo_debug) then
        alert("netatmo module match Chambre")
      end
      grp.write("netatmo chambre temperature",value.dashboard_data.Temperature,dt.float16)
      grp.write("netatmo chambre CO2",value.dashboard_data.CO2,dt.float16)
      grp.write("netatmo chambre humidite",value.dashboard_data.Humidity,dt.scale)
    
    elseif (value.module_name == "Bureau") then
      if (netatmo_debug) then
        alert("netatmo module match Bureau")
      end
      grp.write("netatmo bureau temperature",value.dashboard_data.Temperature,dt.float16)
      grp.write("netatmo bureau CO2",value.dashboard_data.CO2,dt.float16)
      grp.write("netatmo bureau humidite",value.dashboard_data.Humidity,dt.scale)
          
    elseif (value.module_name == "Studio") then
      if (netatmo_debug) then
        alert("netatmo module match Studio")
      end
      grp.write("netatmo studio temperature",value.dashboard_data.Temperature,dt.float16)
      grp.write("netatmo studio CO2",value.dashboard_data.CO2,dt.float16)
      grp.write("netatmo studio humidite",value.dashboard_data.Humidity,dt.scale)
     
    end
  
  end
 
  if (netatmo_debug) then
    alert("netatmo end")
  end
  
  
endv1
Code:
require 'ltn12'
require 'socket.http'
json = require("json")
https = require 'ssl.https'
function refresh_netatmo()
  local netatmo_debug = false
  local client_id = ""
  local client_secret = ""
  local username = ""
  local password = ""
  local scope = "read_station"
  -- optional
  --local device_id = ""
  local request_token_url = "https://api.netatmo.net/oauth2/token"
  local request_device_list = "https://api.netatmo.net/api/devicelist"
  local response_body = { }
  if (netatmo_debug) then
    alert("netatmo start")
  end
  
  local request_body = "grant_type=password&client_id=" .. client_id .."&client_secret=" .. client_secret .. "&username=" .. username .. "&password=" .. password .. "&scope=" .. scope
  local body, code, hdrs, stat = https.request
  {
    url = request_token_url;
    method = "POST";
    headers =
    {
      ["Content-Type"] = "application/x-www-form-urlencoded";
      ["Content-Length"] = #request_body;
    };
    source = ltn12.source.string(request_body);
    sink = ltn12.sink.table(response_body);
  }
  if (code ~= 200) then
    alert("netatmo auth error")
     error("netatmo auth error : "..tostring(code)..","..tostring(body))
    return
  end
  local response_decode = json.decode(table.concat(response_body))
  local access_token = response_decode.access_token
  if (netatmo_debug) then
    alert("netatmo token %s",access_token)
  end
  
  local request_body = "access_token=" .. access_token .. "&app_type=app_station"
  -- to limit to only one device :
--  local request_body = "access_token=" .. access_token .. "&app_type=app_station&device_id=" .. device_id
  
  local response_body = { }
  local body, code, hdrs, stat = https.request
  {
    url = request_device_list;
    method = "POST";
    headers =
    {
      ["Content-Type"] = "application/x-www-form-urlencoded";
      ["Content-Length"] = #request_body;
    };
    source = ltn12.source.string(request_body);
    sink = ltn12.sink.table(response_body);
  }
  if (code ~= 200) then
    error("netatmo devicelist error")
    return
  end
  local response_decode = json.decode(table.concat(response_body))
  -- Module int
  if (netatmo_debug) then
    alert("netatmo device 1")
  end
  grp.write("Netatmo Température intérieure",response_decode.body.devices[1].dashboard_data.Temperature,dt.float16)
  grp.write("Netatmo Humidité intérieure",response_decode.body.devices[1].dashboard_data.Humidity,dt.scale)
  grp.write("Netatmo Pression",response_decode.body.devices[1].dashboard_data.Pressure,dt.uint16)
  grp.write("Netatmo CO2",response_decode.body.devices[1].dashboard_data.CO2,dt.uint16)
  grp.write("Netatmo Sonomètre",response_decode.body.devices[1].dashboard_data.Noise,dt.uint8)
  grp.write("Netatmo Température intérieure minimum",response_decode.body.devices[1].dashboard_data.min_temp,dt.float16)
  grp.write("Netatmo Température intérieure maximum",response_decode.body.devices[1].dashboard_data.max_temp,dt.float16)
  grp.write("Netatmo Pression absolue",response_decode.body.devices[1].dashboard_data.AbsolutePressure,dt.uint16)
  
  -- Module ext
  if (netatmo_debug) then
    alert("netatmo module 1")
  end
  grp.write("Netatmo Température extérieure",response_decode.body.modules[1].dashboard_data.Temperature,dt.float16)
  grp.write("Netatmo Humidité extérieure",response_decode.body.modules[1].dashboard_data.Humidity,dt.float16)
  grp.write("Netatmo Température extérieure minimum",response_decode.body.modules[1].dashboard_data.min_temp,dt.float16)
  grp.write("Netatmo Température extérieure maximum",response_decode.body.modules[1].dashboard_data.max_temp,dt.float16)
  
  -- Module Pluvio
  if (netatmo_debug) then
    alert("netatmo module 2")
  end  
  
  grp.write("Netatmo Pluviomètre",response_decode.body.modules[2].dashboard_data.Rain,dt.float16)
  grp.write("Netatmo Pluviomètre 1h",response_decode.body.modules[2].dashboard_data.sum_rain_1,dt.float16)
  grp.write("Netatmo Pluviomètre 24h",response_decode.body.modules[2].dashboard_data.sum_rain_24,dt.float16)
  
  if (netatmo_debug) then
    alert("netatmo end")
  end
  
endUse the function in your programs
Either in Event-based, Scheduled or Resident script run the function by command refresh_netatmo().
example : a scheduled script that run every minute with the content :
Code:
refresh_netatmo()Matthieu