Access multiple json.item objects

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
infoed
Posts: 7
Joined: Monday 21 October 2024 14:33
Target OS: NAS (Synology & others)
Domoticz version:
Contact:

Access multiple json.item objects

Post by infoed »

Hi,
I 'm looking for a way to process multiple HTTP resonses of different openurl results.

E.g :
Open 2 different graph API calls for 2 different devices (idx 1 and idx2)

url1 = dz.settings['Domoticz url'] .. '/json.htm?type=command&param=graph&sensor=counter&range=year&idx=' .. id1
dz.openURL({ url = url1, callback = scriptVar1 })
url2 = dz.settings['Domoticz url'] .. '/json.htm?type=command&param=graph&sensor=counter&range=month&idx=' .. id2
dz.openURL({ url = url2, callback = scriptVar2 })

When I have only one url call, I process the results like this:

-- main
if item.isHTTPResponse and item.isJSON then
updateTextSensor(processResult(item.json))
elseif item.isTimer then
callYearGraph(idx1)
else
dz.log(' Error while retrieving elektra data. Result is ' .. item.statusText ..' ; Response is: ' .. item.data)
end

I know that the result of ONE openurl call is in item.json.

Can somebody give me an example of processing TWO url calls using TWO item.json tables with the different callback methods?

Thanks in advance, InfoEd
User avatar
waltervl
Posts: 5851
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: Access multiple json.item objects

Post by waltervl »

You have to check the trigger eg

Code: Select all

if item.isHTTPResponse and item.isJSON then
  if item.trigger ==  'scriptVar1' then
  -- do your scrptvar 1 thing
  elseif item.trigger ==  'scriptVar2' then
  -- do your scrptvar 2 thing
  end
 updateTextSensor(processResult(item.json))
elseif item.isTimer then
   callYearGraph(idx1)
else
  dz.log(' Error while retrieving elektra data. Result is ' .. item.statusText ..' ; Response is: ' .. item.data)
end
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
User avatar
Ragdag
Posts: 152
Joined: Friday 30 March 2018 13:56
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Access multiple json.item objects

Post by Ragdag »

Here is an actual script I use to read my Dell iDRAC data of 2 different end points

Code: Select all

--[[
Description:
This script polls an iDRAC interface for thermal and HDD status, updates Domoticz devices accordingly,
and logs relevant data. Uses HTTP requests to retrieve JSON data and ensures device existence before updates.
--]]

-----------------------------------------------------------
-- Constants and configuration
-----------------------------------------------------------
local scriptName = 'iDRAC_Monitor'
local config = {
    baseUrl = 'https://192.168.2.202',
    auth = 'Basic xxxxxxxx',
    deviceIds = { inletTemp = 395, exhaustTemp = 396, cpu1Temp = 397, fan1Speed = 3008, hddPowerState = 4105, hddPowerStateText = 4104 },
    endpoints = {
        thermal = '/redfish/v1/Chassis/System.Embedded.1/Thermal',
        hddStatus = '/redfish/v1/Systems/System.Embedded.1/Storage/RAID.Integrated.1-1/Drives/Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1'
    }
}

local deviceCache = {}
local logging = { marker = scriptName }

-----------------------------------------------------------
-- Utility functions
-----------------------------------------------------------
local function getDevice(domoticz, id)
    if not deviceCache[id] then deviceCache[id] = domoticz.devices(id) end
    return deviceCache[id]
end

local function updateDevice(domoticz, id, value, action, errorMsg)
    local device = getDevice(domoticz, id)
    if not device or value == nil or value == -999 then
        domoticz.log(errorMsg, domoticz.LOG_ERROR)
        return
    end
    if action == 'updateText' then device.updateText(value)
    elseif action == 'updateTemperature' then device.updateTemperature(value)
    elseif action == 'updateCustomSensor' then device.updateCustomSensor(value)
    elseif action == 'switchOn' then device.switchOn()
    elseif action == 'switchOff' then device.switchOff()
    end
end

local function makeRequest(domoticz, endpoint, callback)
    domoticz.openURL({ url = config.baseUrl .. endpoint, method = 'GET', headers = { ['Authorization'] = config.auth }, callback = callback })
end

-----------------------------------------------------------
-- Data processing
-----------------------------------------------------------
local function processThermalData(domoticz, data)
    local updates = {
        [config.deviceIds.inletTemp] = -999, [config.deviceIds.exhaustTemp] = -999, [config.deviceIds.cpu1Temp] = -999, [config.deviceIds.fan1Speed] = -999
    }
    for _, t in ipairs(data.Temperatures or {}) do
        if t.Name:find('Inlet Temp') then updates[config.deviceIds.inletTemp] = t.ReadingCelsius
        elseif t.Name:find('Exhaust Temp') then updates[config.deviceIds.exhaustTemp] = t.ReadingCelsius
        elseif t.Name:find('CPU1 Temp') then updates[config.deviceIds.cpu1Temp] = t.ReadingCelsius
        end
    end
    for _, f in ipairs(data.Fans or {}) do
        if f.Name:find('Fan1') then updates[config.deviceIds.fan1Speed] = f.Reading end
    end
    for id, value in pairs(updates) do
        updateDevice(domoticz, id, value, id == config.deviceIds.fan1Speed and 'updateCustomSensor' or 'updateTemperature', 'Error reading thermal data')
    end
end

local function processHDDData(domoticz, data)
    local status = data.Oem and data.Oem.Dell and data.Oem.Dell.DellPhysicalDisk.PowerStatus
    if status then
        updateDevice(domoticz, config.deviceIds.hddPowerState, status == 'Spun-Up', status == 'Spun-Up' and 'switchOn' or 'switchOff', 'Error setting HDD state')
        updateDevice(domoticz, config.deviceIds.hddPowerStateText, status, 'updateText', 'Error setting HDD state text')
    else
        domoticz.log('Invalid HDD data format', domoticz.LOG_ERROR)
    end
end

-----------------------------------------------------------
-- Main script
-----------------------------------------------------------
return {
    on = {
        timer = { 'every 5 minutes' },
        httpResponses = { scriptName .. '_thermal', scriptName .. '_hdd' }
    },
    logging = logging,
    execute = function(domoticz, item)
        if item.isTimer then
            makeRequest(domoticz, config.endpoints.thermal, scriptName .. '_thermal')
            makeRequest(domoticz, config.endpoints.hddStatus, scriptName .. '_hdd')
        elseif item.isJSON then
            local data = item.json
            if data then
                if item.callback == scriptName .. '_thermal' then processThermalData(domoticz, data)
                elseif item.callback == scriptName .. '_hdd' then processHDDData(domoticz, data)
                end
            end
        else
            domoticz.log('Invalid response received', domoticz.LOG_ERROR)
        end
    end
}
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest