-- Copyright (c) 2025 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--          http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.
local mdb = require 'mc.mdb'
local class = require 'mc.class'
local app_base = require 'mc.client_app_base'
local mdb_service = require 'mc.mdb.mdb_service'
local subscribe_signal = require 'mc.mdb.subscribe_signal'
local org_freedesktop_dbus = require 'sd_bus.org_freedesktop_dbus'

local match_rule = org_freedesktop_dbus.MatchRule
local get_non_virtual_interface_objects = mdb_service.get_non_virtual_interface_objects
local foreach_non_virtual_interface_objects = mdb_service.foreach_non_virtual_interface_objects

local Accessor = require 'thermal_mgmt.json_types.Accessor'
local Scanner = require 'thermal_mgmt.json_types.Scanner'
local FruCtrl = require 'thermal_mgmt.json_types.FruCtrl'
local Unit = require 'thermal_mgmt.json_types.Unit'
local BlockIO = require 'thermal_mgmt.json_types.BlockIO'
local Board = require 'thermal_mgmt.json_types.Board'
local Connector = require 'thermal_mgmt.json_types.Connector'
local NodeLocation = require 'thermal_mgmt.json_types.NodeLocation'
local PowerSupplies = require 'thermal_mgmt.json_types.PowerSupplies'
local Fan = require 'thermal_mgmt.json_types.Fan'
local Fans = require 'thermal_mgmt.json_types.Fans'
local SystemsPumps = require 'thermal_mgmt.json_types.SystemsPumps'
local Drive = require 'thermal_mgmt.json_types.Drive'
local PCIeCard = require 'thermal_mgmt.json_types.PCIeCard'
local SOC = require 'thermal_mgmt.json_types.SOC'
local FanGroup = require 'thermal_mgmt.json_types.FanGroup'
local Status = require 'thermal_mgmt.json_types.Status'
local Pump = require 'thermal_mgmt.json_types.Pump'
local PumpGroup = require 'thermal_mgmt.json_types.PumpGroup'
local ThresholdSensorDisplay = require 'thermal_mgmt.json_types.ThresholdSensorDisplay'
local ThresholdSensor = require 'thermal_mgmt.json_types.ThresholdSensor'
local Chassis = require 'thermal_mgmt.json_types.Chassis'

---@class thermal_mgmt_client: BasicClient
local thermal_mgmt_client = class(app_base.Client)

function thermal_mgmt_client:GetAccessorObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Accessor', true)
end

function thermal_mgmt_client:ForeachAccessorObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Accessor', cb, true)
end

function thermal_mgmt_client:GetScannerObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Scanner', true)
end

function thermal_mgmt_client:ForeachScannerObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Scanner', cb, true)
end

function thermal_mgmt_client:GetFruCtrlObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.FruCtrl', true)
end

function thermal_mgmt_client:ForeachFruCtrlObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.FruCtrl', cb, true)
end

function thermal_mgmt_client:GetUnitObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Board.Unit', true)
end

function thermal_mgmt_client:ForeachUnitObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Board.Unit', cb, true)
end

function thermal_mgmt_client:GetBlockIOObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Chip.BlockIO', true)
end

function thermal_mgmt_client:ForeachBlockIOObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Chip.BlockIO', cb, true)
end

function thermal_mgmt_client:GetBoardObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Board', true)
end

function thermal_mgmt_client:ForeachBoardObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Board', cb, true)
end

function thermal_mgmt_client:GetConnectorObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Connector', true)
end

function thermal_mgmt_client:ForeachConnectorObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Connector', cb, true)
end

function thermal_mgmt_client:GetNodeLocationObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.NodeLocation', true)
end

function thermal_mgmt_client:ForeachNodeLocationObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.NodeLocation', cb, true)
end

function thermal_mgmt_client:GetPowerSuppliesObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Chassis.PowerSubsystem.PowerSupplies', true)
end

function thermal_mgmt_client:ForeachPowerSuppliesObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Chassis.PowerSubsystem.PowerSupplies', cb,
        true)
end

function thermal_mgmt_client:GetFanObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Fan', true)
end

function thermal_mgmt_client:ForeachFanObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Fan', cb, true)
end

function thermal_mgmt_client:GetFansObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Fans', true)
end

function thermal_mgmt_client:ForeachFansObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Fans', cb, true)
end

function thermal_mgmt_client:GetSystemsPumpsObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Pumps', true)
end

function thermal_mgmt_client:ForeachSystemsPumpsObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Pumps', cb, true)
end

function thermal_mgmt_client:GetDriveObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Storage.Drive', true)
end

function thermal_mgmt_client:ForeachDriveObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Storage.Drive', cb, true)
end

function thermal_mgmt_client:GetPCIeCardObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.PCIeDevices.PCIeCard', true)
end

function thermal_mgmt_client:ForeachPCIeCardObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.PCIeDevices.PCIeCard', cb, true)
end

function thermal_mgmt_client:GetSOCObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.SOC', true)
end

function thermal_mgmt_client:ForeachSOCObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Managers.SOC', cb, true)
end

function thermal_mgmt_client:GetFanGroupObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Chassis.FanGroup', true)
end

function thermal_mgmt_client:ForeachFanGroupObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Chassis.FanGroup', cb, true)
end

function thermal_mgmt_client:GetStatusObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Manufacture.Status', true)
end

function thermal_mgmt_client:ForeachStatusObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Manufacture.Status', cb, true)
end

function thermal_mgmt_client:GetPumpObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Pump', true)
end

function thermal_mgmt_client:ForeachPumpObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.Pump', cb, true)
end

function thermal_mgmt_client:GetPumpGroupObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Chassis.PumpGroup', true)
end

function thermal_mgmt_client:ForeachPumpGroupObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Chassis.PumpGroup', cb, true)
end

function thermal_mgmt_client:GetThresholdSensorDisplayObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.ThresholdSensorDisplay', true)
end

function thermal_mgmt_client:ForeachThresholdSensorDisplayObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.ThresholdSensorDisplay', cb, true)
end

function thermal_mgmt_client:GetThresholdSensorObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.ThresholdSensor', true)
end

function thermal_mgmt_client:ForeachThresholdSensorObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Systems.ThresholdSensor', cb, true)
end

function thermal_mgmt_client:OnAccessorInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Accessor')
end

function thermal_mgmt_client:OnAccessorInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Accessor')
end

function thermal_mgmt_client:OnScannerInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Scanner')
end

function thermal_mgmt_client:OnScannerInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Scanner')
end

function thermal_mgmt_client:OnFruCtrlPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.FruCtrl', {'PowerState'})
end

function thermal_mgmt_client:OnFruCtrlInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.FruCtrl')
end

function thermal_mgmt_client:OnFruCtrlInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.FruCtrl')
end

function thermal_mgmt_client:OnUnitPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Board.Unit', {'CurrentUpgradeStatus'})
end

function thermal_mgmt_client:OnUnitInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Board.Unit')
end

function thermal_mgmt_client:OnUnitInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Board.Unit')
end

function thermal_mgmt_client:OnBlockIOInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Chip.BlockIO')
end

function thermal_mgmt_client:OnBlockIOInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Chip.BlockIO')
end

function thermal_mgmt_client:OnBoardPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Board', {'Name'})
end

function thermal_mgmt_client:OnBoardInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Board')
end

function thermal_mgmt_client:OnBoardInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Board')
end

function thermal_mgmt_client:OnConnectorInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Connector')
end

function thermal_mgmt_client:OnConnectorInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Connector')
end

function thermal_mgmt_client:OnNodeLocationInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.NodeLocation')
end

function thermal_mgmt_client:OnNodeLocationInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.NodeLocation')
end

function thermal_mgmt_client:OnPowerSuppliesInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Chassis.PowerSubsystem.PowerSupplies')
end

function thermal_mgmt_client:OnPowerSuppliesInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Chassis.PowerSubsystem.PowerSupplies')
end

function thermal_mgmt_client:OnFanPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Fan', {
            'FanId', 'Slot', 'FrontPresence', 'RearPresence', 'FrontStatus', 'RearStatus', 'Model'
        })
end

function thermal_mgmt_client:OnFanInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Fan')
end

function thermal_mgmt_client:OnFanInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Fan')
end

function thermal_mgmt_client:OnFansInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Fans')
end

function thermal_mgmt_client:OnFansInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Fans')
end

function thermal_mgmt_client:OnSystemsPumpsInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Pumps')
end

function thermal_mgmt_client:OnSystemsPumpsInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Pumps')
end

function thermal_mgmt_client:OnDriveInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Storage.Drive')
end

function thermal_mgmt_client:OnDriveInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Storage.Drive')
end

function thermal_mgmt_client:OnPCIeCardPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.PCIeDevices.PCIeCard', {'Name'})
end

function thermal_mgmt_client:OnPCIeCardInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.PCIeDevices.PCIeCard')
end

function thermal_mgmt_client:OnPCIeCardInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.PCIeDevices.PCIeCard')
end

function thermal_mgmt_client:OnSOCInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.SOC')
end

function thermal_mgmt_client:OnSOCInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Managers.SOC')
end

function thermal_mgmt_client:OnFanGroupPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Chassis.FanGroup', {'ExpectedSpeedPercent'})
end

function thermal_mgmt_client:OnFanGroupInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Chassis.FanGroup')
end

function thermal_mgmt_client:OnFanGroupInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Chassis.FanGroup')
end

function thermal_mgmt_client:OnStatusPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Manufacture.Status', {'Mode'})
end

function thermal_mgmt_client:OnStatusInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Manufacture.Status')
end

function thermal_mgmt_client:OnStatusInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Manufacture.Status')
end

function thermal_mgmt_client:OnPumpPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Pump', {'Presence', 'Status'})
end

function thermal_mgmt_client:OnPumpInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Pump')
end

function thermal_mgmt_client:OnPumpInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.Pump')
end

function thermal_mgmt_client:OnPumpGroupPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Chassis.PumpGroup', {'ExpectedSpeedPercent'})
end

function thermal_mgmt_client:OnPumpGroupInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Chassis.PumpGroup')
end

function thermal_mgmt_client:OnPumpGroupInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Chassis.PumpGroup')
end

function thermal_mgmt_client:OnThresholdSensorDisplayPropertiesChanged(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_properties_changed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.ThresholdSensorDisplay', {'Health', 'ReadingDisplay'})
end

function thermal_mgmt_client:OnThresholdSensorDisplayInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.ThresholdSensorDisplay')
end

function thermal_mgmt_client:OnThresholdSensorDisplayInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.ThresholdSensorDisplay')
end

function thermal_mgmt_client:OnThresholdSensorInterfacesAdded(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.ThresholdSensor')
end

function thermal_mgmt_client:OnThresholdSensorInterfacesRemoved(cb)
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), '/bmc', cb,
        'bmc.kepler.Systems.ThresholdSensor')
end

function thermal_mgmt_client:GetChassisChassisObject(path_params)
    return mdb.try_get_object(self:get_bus(), path_params and ('/bmc/kepler/Chassis/' .. path_params['ChassisId']) or
        '/bmc/kepler/Chassis/:ChassisId', 'bmc.kepler.Chassis')
end

function thermal_mgmt_client:GetChassisObjects()
    return get_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Chassis', true,
        {'/bmc/kepler/Chassis/:ChassisId'})
end

function thermal_mgmt_client:ForeachChassisObjects(cb)
    return foreach_non_virtual_interface_objects(self:get_bus(), 'bmc.kepler.Chassis', cb, true,
        {'/bmc/kepler/Chassis/:ChassisId'})
end

function thermal_mgmt_client:OnChassisInterfacesAdded(cb, path_params)
    local path_namespace = path_params and ('/bmc/kepler/Chassis/' .. path_params['ChassisId']) or
                               '/bmc/kepler/Chassis/:ChassisId'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_added(self:get_bus(), path_namespace, cb,
        'bmc.kepler.Chassis')
end

function thermal_mgmt_client:OnChassisInterfacesRemoved(cb, path_params)
    local path_namespace = path_params and ('/bmc/kepler/Chassis/' .. path_params['ChassisId']) or
                               '/bmc/kepler/Chassis/:ChassisId'
    self.signal_slots[#self.signal_slots + 1] = subscribe_signal.on_interfaces_removed(self:get_bus(), path_namespace,
        cb, 'bmc.kepler.Chassis')
end

function thermal_mgmt_client:SubscribeFruCtrlBeforePowerOnSignal(cb)
    local sig = match_rule.signal('BeforePowerOnSignal', 'bmc.kepler.Systems.FruCtrl')
    self.signal_slots[#self.signal_slots + 1] = self:get_bus():match(sig, function(msg)
        cb(msg:read())
    end)
end

function thermal_mgmt_client:ctor()
    self.signal_slots = {}
end

---@type thermal_mgmt_client
return thermal_mgmt_client.new('thermal_mgmt')
