Logic Machine Forum
Airthings API - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Gateway (https://forum.logicmachine.net/forumdisplay.php?fid=10)
+--- Thread: Airthings API (/showthread.php?tid=5486)



Airthings API - Fahd - 26.06.2024

Hey everyone, 

I'm want to read temperature and humidity data from the Airthings API through LM5, but I'm new to working with APIs . Could someone please help me get started?

https://developer.airthings.com/api-docs
https://developer.airthings.com/docs/api/getting-started#api-documentation

Thanks in advance!


RE: Airthings API - admin - 26.06.2024

Similar integration: https://forum.logicmachine.net/showthread.php?tid=4824&pid=31274#pid31274


RE: Airthings API - Fahd - 03.07.2024

(26.06.2024, 11:05)admin Wrote: Similar integration: https://forum.logicmachine.net/showthread.php?tid=4824&pid=31274#pid31274

In case someone needs it, below is a scheduled script that runs every 5 minutes to retrieve temp data from some sensors and write them into LM5 groups. (I'm pretty sure that it could be improved)

Code:
local https = require('ssl.https')
local json = require('json')
local ltn12 = require('ltn12')
-- Airthings API endpoints and credentials
local tokenEndpoint = 'https://accounts-api.airthings.com/v1/token'
local clientId = 'xx'
local clientSecret = 'xx'
-- local deviceSerialNumber = '3130000665'  -- Specific device serial number
local devices = {
    { serialNumber = 'xx', location = '7east' },
    { serialNumber = 'xx', location = '7west' },
    { serialNumber = 'xx', location = '7mid' }
}
local accessToken
-- Custom logging function
-- Function to get access token
function getAccessToken()
    local requestBody = 'grant_type=client_credentials'
        .. '&client_id=' .. clientId
        .. '&client_secret=' .. clientSecret
        .. '&scope=read:device'
    local response_body = {}
    local _, code, headers, status = https.request{
        url = tokenEndpoint,
        method = 'POST',
        headers = {
            ['Content-Type'] = 'application/x-www-form-urlencoded',
            ['Content-Length'] = #requestBody
        },
        source = ltn12.source.string(requestBody),
        sink = ltn12.sink.table(response_body)
    }
    local response = table.concat(response_body)
--    log("DEBUG", "Response body: " .. response)
--    log("DEBUG", "HTTP status code: " .. tostring(code))
--    log("DEBUG", "HTTP status: " .. tostring(status))
   
    if code == 200 then
        local jsonResponse = json.decode(response)
        accessToken = jsonResponse.access_token
        log("INFO", 'Access token received: ' .. accessToken)
    else
        log("ERROR", 'Error fetching access token: ' .. tostring(code) .. ' ' .. tostring(status))
    end
end
-- Function to get data from a specific device
function getDeviceData(serialNumber)
    local deviceDataEndpoint = 'https://ext-api.airthings.com/v1/devices/' .. serialNumber .. '/latest-samples'
    local response_body = {}
    local _, code, headers, status = https.request{
        url = deviceDataEndpoint,
        method = 'GET',
        headers = {
            ['Authorization'] = 'Bearer ' .. accessToken
        },
        sink = ltn12.sink.table(response_body)
    }
    local response = table.concat(response_body)
--   log("DEBUG", "Device data response body: " .. response)
--   log("DEBUG", "HTTP status code: " .. tostring(code))
  --  log("DEBUG", "HTTP status: " .. tostring(status))
   
    if code == 200 then
        local jsonResponse = json.decode(response)
        return jsonResponse
    else
--       log("ERROR", 'Error fetching device data: ' .. tostring(code) .. ' ' .. tostring(status))
        return nil
    end
end
-- Main script
getAccessToken()
-- if accessToken then
--    local data = getDeviceData(deviceSerialNumber)
--    if data then
--        log("INFO", "Data for device " .. deviceSerialNumber .. ": " .. json.encode(data))
--    end
-- end
-- Main script
getAccessToken()
if accessToken then
    i = 1   -- Initialize index
    for _, device in ipairs(devices) do
   
        i = i + 1    -- Increment index for group address
        local data = getDeviceData(device.serialNumber)
        if data then
            local temperature = tostring(data.data.temp)
            log("INFO", "Temperature " .. device.location .. " == " .. temperature)
        -- Inside your loop for devices
       grp.checkwrite("32/1/" .. i, temperature)  -- Write temperature to group address
     
       -- log(i)
        end
    end
end