Page 1 of 1

Access multiple json.item objects

Posted: Wednesday 20 November 2024 16:05
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

Re: Access multiple json.item objects

Posted: Wednesday 20 November 2024 16:59
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

Re: Access multiple json.item objects

Posted: Thursday 20 February 2025 9:20
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
}