local sys = require "sys" local devices = require "main.devices" local cjson = require "cjson" local bit = require "bit" local event = require "main.event" require "main.global" local configuration = require "storage.configuration" local sensor_monitor = {} local nodes = devices.get_nodes() local sensorUpdate = false local isDiMannual = false local sensors = { ADIO = { -- PLC模块 tags = { DI = "", DO = nil, fan1 = nil, fan2 = nil }, di_status = 0 }, TempHumi = { -- 温湿度模块 tags = {}, }, Immersion = { -- 水浸(不用--切换为DI) tags = {}, }, Smoke = { -- 烟感(不用--切换为DI) tags = {}, }, PowerMeter = { -- 电表 tags = {}, }, PowerSwitch = { -- 智能空开(不用) tags = {}, switch_type = 0xff, exsist = 0xff, }, SmartLock = { tags = {}, }, MultiSwitch = { -- 多路开关控制器 tags = { MSDI = {}, MSDO = {} }, }, SafeElectricity = { tags = {}, -- 安全用电模块 warn1 = {}, warn2 = {} } } local old_status = {} local report_tags = { Ua = { type = REPORT_VOLTAGE, sensor = "PowerMeter" }, Ub = { type = REPORT_VOLTAGE, sensor = "PowerMeter" }, Uc = { type = REPORT_VOLTAGE, sensor = "PowerMeter" }, Ia = { type = REPORT_CURRENT, sensor = "PowerMeter" }, Ib = { type = REPORT_CURRENT, sensor = "PowerMeter" }, Ic = { type = REPORT_CURRENT, sensor = "PowerMeter" }, DO = { type = REPORT_TEXT, sensor = "ADIO" }, DI = { type = REPORT_TEXT, sensor = "ADIO" }, MSDI = { type = REPORT_MUTI, sensor = "MultiSwitch" }, MSDO = { type = REPORT_MUTI, sensor = "MultiSwitch" }, --ASWSwitchState = { type = REPORT_TEXT, sensor = "PowerSwitch" }, --CIa = { type = REPORT_CURRENT, sensor = "PowerSwitch" }, --CIb = { type = REPORT_CURRENT, sensor = "PowerSwitch" }, --CIc = { type = REPORT_CURRENT, sensor = "PowerSwitch" } } local mannual = false local sensor_resolve = { ADIO = function(service, data) local services = { get_di_status = function(data) --log_print.info(service, cjson.encode(data)) sensors.ADIO.tags.DI = "" -- 每次读取DI前,清空 sensors.ADIO.di_status = data.tags.di_status isDiMannual = bit.band(sensors.ADIO.di_status, bit.lshift(1, 15 - 1)) == 0 -- DI15手自动 if isDiMannual ~= mannual then if isDiMannual == true then RUN_MODE = 2 log_print.info("Switch to manual mode") else log_print.info("Switch to automatic mode") RUN_MODE = 1 end mannual = isDiMannual end for i = 1, 20, 1 do sensors.ADIO.tags.DI = sensors.ADIO.tags.DI .. (bit.band(sensors.ADIO.di_status, bit.lshift(1, i - 1)) == 0 and 0 or 1) end log_print.debug("contactor DI", sensors.ADIO.tags.DI) end, get_do_status = function(data) sensors.ADIO.tags.DO = data.tags.do_status sys.publish(GET_DO_ACK) local pri_DO = "" for i = 1, 8, 1 do pri_DO = pri_DO .. (bit.band(sensors.ADIO.tags.DO, bit.lshift(1, i - 1)) == 0 and 0 or 1) end log_print.debug("contactor DO", pri_DO) end, set_do_status = function(data) sys.publish(SET_DO_ACK) --sys.publish(SET_DO_ACK) log_print.info("set do ack received") end, get_fan_speed= function(data) sensors.ADIO.tags.fan1 = data.tags.fan1 sensors.ADIO.tags.fan2 = data.tags.fan2 sys.publish(GET_SPEED_ACK) --sys.publish(SET_DO_ACK) log_print.info("get fan speed ack received") end, set_fan_tmp= function(data) sys.publish(SET_TMP_ACK) --sys.publish(SET_DO_ACK) log_print.info("set fan tmp received") end } if services[service] then services[service](data) end sensors.ADIO.lastActive = os.time() end, TempHumi = function(service, data) local services = { get_temp_humidity = function(data) sensors.TempHumi.tags.Temp = data.tags.temperature sensors.TempHumi.tags.Hum = data.tags.humidity log_print.debug("temperature", sensors.TempHumi.tags.Temp, "humidity", sensors.TempHumi.tags.Hum) end } if services[service] then services[service](data) end sensors.TempHumi.lastActive = os.time() end, Immersion = function(service, data) local services = { get_water_immersion = function(data) sensors.Immersion.tags.WaterImmersion = data.tags.water_immersion log_print.debug("immersion", sensors.Immersion.tags.WaterImmersion) end } if services[service] then services[service](data) end sensors.Immersion.lastActive = os.time() end, Smoke = function(service, data) local services = { get_smoke_status = function(data) sensors.Smoke.tags.SmokeStatus = data.tags.smoke_status log_print.debug("smoke", sensors.Smoke.tags.SmokeStatus) end } if services[service] then services[service](data) end sensors.Smoke.lastActive = os.time() end, SmartLock = function(service, data) local sn = string.split(data.sn, "_")[2] local chn = devices.getChn(sn) if chn == nil or chn == -1 then log_print.error(sn .. " can not find the corresponding chn!!!") return end if sensors.SmartLock.tags.CLock == nil then sensors.SmartLock.tags.CLock = {} end local services = { status = function(data) sensors.SmartLock.tags.CLock[chn] = data.tags.status log_print.debug(string.format("SmartLock %d status %s", chn, data.tags.status)) end } if services[service] then services[service](data) end sensors.Smoke.lastActive = os.time() end, PowerMeter = function(servive, data) local params = { totalReverseElectricEnergy = function() --[[ if sensors.PowerMeter.tags.ReverseEnergy == nil then sensors.PowerMeter.tags.ReverseEnergy = {} end sensors.PowerMeter.tags.ReverseEnergy[chn] = data.tags.totalReverseElectricEnergy * POWER_METER_MUL log_print.debug(chn .. " reverse energy " .. sensors.PowerMeter.tags.ReverseEnergy[chn]) ]] sensors.PowerMeter.tags.ReverseEnergy = data.tags.totalReverseElectricEnergy * POWER_METER_MUL log_print.debug(" PowerMeter ReverseEnergy " .. sensors.PowerMeter.tags.ReverseEnergy) end, TotalPowerConsumption = function() --[[ if sensors.PowerMeter.tags.Energy == nil then sensors.PowerMeter.tags.Energy = {} end sensors.PowerMeter.tags.Energy[chn] = data.tags.TotalPowerConsumption * POWER_METER_MUL log_print.debug(chn .. " total energy " .. sensors.PowerMeter.tags.Energy[chn]) ]] sensors.PowerMeter.tags.Energy = data.tags.TotalPowerConsumption * POWER_METER_MUL log_print.debug(" PowerMeter Energy " .. sensors.PowerMeter.tags.Energy) end, totalForwardElectricEnergy = function() --[[ if sensors.PowerMeter.tags.PositiveEnergy == nil then sensors.PowerMeter.tags.PositiveEnergy = {} end sensors.PowerMeter.tags.PositiveEnergy[chn] = data.tags.totalForwardElectricEnergy * POWER_METER_MUL log_print.debug(chn .. " positive energy " .. sensors.PowerMeter.tags.PositiveEnergy[chn]) ]] sensors.PowerMeter.tags.PositiveEnergy = data.tags.totalForwardElectricEnergy * POWER_METER_MUL log_print.debug(" PowerMeter PositiveEnergy " .. sensors.PowerMeter.tags.PositiveEnergy) end, APhaseVoltage = function() -- if sensors.PowerMeter.tags.Ua == nil then -- sensors.PowerMeter.tags.Ua = {} -- end -- if chn == 1 then sensors.PowerMeter.tags.Ua = data.tags.APhaseVoltage end sensors.PowerMeter.tags.Ua = data.tags.APhaseVoltage log_print.debug(" PowerMeter Ua " .. sensors.PowerMeter.tags.Ua) end, BPhaseVoltage = function() -- if chn ~= 1 then -- return -- end -- if sensors.PowerMeter.tags.Ub == nil then -- sensors.PowerMeter.tags.Ub = {} -- end -- if chn == 1 then sensors.PowerMeter.tags.Ub = data.tags.BPhaseVoltage end sensors.PowerMeter.tags.Ub = data.tags.BPhaseVoltage log_print.debug(" PowerMeter Ub " .. sensors.PowerMeter.tags.Ub) end, CPhaseVoltage = function() -- if chn ~= 1 then -- return -- end -- if sensors.PowerMeter.tags.Uc == nil then -- sensors.PowerMeter.tags.Uc = {} -- end -- if chn == 1 then sensors.PowerMeter.tags.Uc = data.tags.CPhaseVoltage end sensors.PowerMeter.tags.Uc = data.tags.CPhaseVoltage log_print.debug(" PowerMeter Uc " .. sensors.PowerMeter.tags.Uc) end, APhaseCurrent = function() -- if chn ~= 1 then -- return -- end -- if sensors.PowerMeter.tags.Ia == nil then -- sensors.PowerMeter.tags.Ia = {} -- end -- if chn == 1 then sensors.PowerMeter.tags.Ia = data.tags.APhaseCurrent * 1000 * POWER_METER_MUL end sensors.PowerMeter.tags.Ia = data.tags.APhaseCurrent * 1000 * POWER_METER_MUL log_print.debug(" PowerMeter Ia " .. sensors.PowerMeter.tags.Ia) end, BPhaseCurrent = function() -- if chn ~= 1 then -- return -- end -- if sensors.PowerMeter.tags.Ib == nil then -- sensors.PowerMeter.tags.Ib = {} -- end -- if chn == 1 then sensors.PowerMeter.tags.Ib = data.tags.BPhaseCurrent * 1000 * POWER_METER_MUL end sensors.PowerMeter.tags.Ib = data.tags.BPhaseCurrent * 1000 * POWER_METER_MUL log_print.debug(" PowerMeter Ib " .. sensors.PowerMeter.tags.Ib) end, CPhaseCurrent = function() -- if chn ~= 1 then -- return -- end -- if sensors.PowerMeter.tags.Ic == nil then -- sensors.PowerMeter.tags.Ic = {} -- end -- if chn == 1 then sensors.PowerMeter.tags.Ic = data.tags.CPhaseCurrent * 1000 * POWER_METER_MUL end sensors.PowerMeter.tags.Ic = data.tags.CPhaseCurrent * 1000 * POWER_METER_MUL log_print.debug(" PowerMeter Ic " .. sensors.PowerMeter.tags.Ic) end } for k, v in pairs(data.tags) do -- print(k, v) if params[k] then params[k]() end end sensors.PowerMeter.lastActive = os.time() end, PowerSwitch = function(service, data) local services = { line_current = function() for k, v in pairs(data.tags) do local chn = tonumber(string.sub(k, -1)) sensors.PowerSwitch.tags.CIa = sensors.PowerSwitch.tags.CIa or {} if bit.band(sensors.PowerSwitch.switch_type, bit.lshift(1, chn - 1)) == 0 and bit.band(sensors.PowerSwitch.exsist, bit.lshift(1, chn - 1)) ~= 0 then sensors.PowerSwitch.tags.CIa[chn] = v * 1000 end end end, phase_a_current = function() for k, v in pairs(data.tags) do local chn = tonumber(string.sub(k, -1)) sensors.PowerSwitch.tags.CIa = sensors.PowerSwitch.tags.CIa or {} if bit.band(sensors.PowerSwitch.switch_type, bit.lshift(1, chn - 1)) ~= 0 and bit.band(sensors.PowerSwitch.exsist, bit.lshift(1, chn - 1)) ~= 0 then sensors.PowerSwitch.tags.CIa[chn] = v * 1000 end end end, phase_b_current = function() for k, v in pairs(data.tags) do local chn = tonumber(string.sub(k, -1)) sensors.PowerSwitch.tags.CIb = sensors.PowerSwitch.tags.CIb or {} if bit.band(sensors.PowerSwitch.exsist, bit.lshift(1, chn - 1)) ~= 0 then sensors.PowerSwitch.tags.CIb[chn] = v * 1000 end end end, phase_c_current = function() for k, v in pairs(data.tags) do local chn = tonumber(string.sub(k, -1)) sensors.PowerSwitch.tags.CIc = sensors.PowerSwitch.tags.CIc or {} if bit.band(sensors.PowerSwitch.exsist, bit.lshift(1, chn - 1)) ~= 0 then sensors.PowerSwitch.tags.CIc[chn] = v * 1000 end end end, temperature = function() for k, v in pairs(data.tags) do local chn = tonumber(string.sub(k, -1)) sensors.PowerSwitch.tags.ASWTemp = sensors.PowerSwitch.tags.ASWTemp or {} if bit.band(sensors.PowerSwitch.exsist, bit.lshift(1, chn - 1)) ~= 0 then sensors.PowerSwitch.tags.ASWTemp[chn] = v end end end, switch_status = function() sensors.PowerSwitch.tags.ASWSwitchState = "" local switch_status = data.tags.switch_status for i = 1, 8, 1 do sensors.PowerSwitch.tags.ASWSwitchState = sensors.PowerSwitch.tags.ASWSwitchState .. (bit.band(switch_status, bit.lshift(1, i - 1)) == 0 and 0 or 1) end end, exsist_switch = function() sensors.PowerSwitch.exsist = data.tags.exsist end, switch_control = function() sys.publish(SET_AWS_ACK) end, batch_control = function() sys.publish(SET_AWS_ACK) end, switch_type = function() sensors.PowerSwitch.switch_type = data.tags.switch_type end } if services[service] then services[service](data) end sensors.PowerSwitch.lastActive = os.time() end, MultiSwitch = function(service, data) local sn = string.split(data.sn, "_")[2] local chn = devices.getChn(sn) if chn == nil or chn == -1 then log_print.error(sn .. " can not find the corresponding chn!!!") return end local services = { do_feedback = function(data) sensors.MultiSwitch.tags.MSDI[chn] = data.tags.do_feed local pri_DI = "" for i = 1, 6, 1 do pri_DI = pri_DI .. (bit.band(sensors.MultiSwitch.tags.MSDI[chn], bit.lshift(1, i - 1)) == 0 and 0 or 1) end log_print.debug(string.format("multipath %d MSDI %s", chn, pri_DI)) sys.publish(MULTI_DO_FEEDBACK_ACK) -- log_print.info(string.format("multipath %d %s", chn, "do_feedback_ack received")) end, do_ctrl = function(data) sys.publish(MULTI_SET_DO_ACK) log_print.info(string.format("multipath %d %s", chn, "set do ack received")) end, do_current = function(data) sensors.MultiSwitch.tags.MSDO[chn] = data.tags.do_current local pri_DO = "" for i = 1, 6, 1 do pri_DO = pri_DO .. (bit.band(sensors.MultiSwitch.tags.MSDO[chn], bit.lshift(1, i - 1)) == 0 and 0 or 1) end log_print.debug(string.format("multipath %d MSDO %s", chn, pri_DO)) sys.publish(MULTI_DO_CURRENT_ACK) --log_print.info(string.format("multipath %d %s", chn, "do_current_ack received")) end, sync_rtc = function(data) sys.publish(MULTI_SYNC_RTC_ACK) log_print.info(string.format("multipath %d %s", chn, "sync rtc ack received")) end, order = function(data) sys.publish(MULTI_SEND_ORDER_ACK) --sys.publish(SET_DO_ACK) log_print.info(string.format("multipath %d %s", chn, "send order ack received")) end, set_sch_K1 = function(data) sys.publish(MULTI_SET_SCH_ACK) log_print.info(string.format("multipath %d %s", chn, "set sch K1 ack received")) end, set_sch_K1_K2 = function(data) sys.publish(MULTI_SET_SCH_ACK) log_print.info(string.format("multipath %d %s", chn, "set sch K1~K2 ack received")) end, set_sch_K1_K3 = function(data) sys.publish(MULTI_SET_SCH_ACK) log_print.info(string.format("multipath %d %s", chn, "set sch K1~K3 ack received")) end, set_sch_K1_K4 = function(data) sys.publish(MULTI_SET_SCH_ACK) log_print.info(string.format("multipath %d %s", chn, "set sch K1~K4 ack received")) end } if services[service] then services[service](data) end sensors.MultiSwitch.lastActive = os.time() end, SafeElectricity = function(service, data) local sn = string.split(data.sn, "_")[2] local chn = devices.getChn(sn) if chn == nil or chn == -1 then log_print.error(sn .. " can not find the corresponding chn!!!") return end local params = { A_phase_vol = function() if sensors.SafeElectricity.tags.CUa == nil then sensors.SafeElectricity.tags.CUa = {} end sensors.SafeElectricity.tags.CUa[chn] = data.tags.A_phase_vol log_print.debug(" safeelectricity " .. chn .. " CUa " .. sensors.SafeElectricity.tags.CUa[chn]) end, B_phase_vol = function() if sensors.SafeElectricity.tags.CUb == nil then sensors.SafeElectricity.tags.CUb = {} end sensors.SafeElectricity.tags.CUb[chn] = data.tags.B_phase_vol log_print.debug(" safeelectricity " .. chn .. " CUb " .. sensors.SafeElectricity.tags.CUb[chn]) end, C_phase_vol = function() if sensors.SafeElectricity.tags.CUc == nil then sensors.SafeElectricity.tags.CUc = {} end sensors.SafeElectricity.tags.CUc[chn] = data.tags.C_phase_vol log_print.debug(" safeelectricity " .. chn .. " CUc " .. sensors.SafeElectricity.tags.CUc[chn]) end, A_phase_cur = function() if sensors.SafeElectricity.tags.CIa == nil then sensors.SafeElectricity.tags.CIa = {} end sensors.SafeElectricity.tags.CIa[chn] = data.tags.A_phase_cur log_print.debug(" safeelectricity " .. chn .. " CIa " .. sensors.SafeElectricity.tags.CIa[chn]) end, B_phase_cur = function() if sensors.SafeElectricity.tags.CIb == nil then sensors.SafeElectricity.tags.CIb = {} end sensors.SafeElectricity.tags.CIb[chn] = data.tags.B_phase_cur log_print.debug(" safeelectricity " .. chn .. " CIb " .. sensors.SafeElectricity.tags.CIb[chn]) end, C_phase_cur = function() if sensors.SafeElectricity.tags.CIc == nil then sensors.SafeElectricity.tags.CIc = {} end sensors.SafeElectricity.tags.CIc[chn] = data.tags.C_phase_cur log_print.debug(" safeelectricity " .. chn .. " CIc " .. sensors.SafeElectricity.tags.CIc[chn]) end, N_phase_cur = function() if sensors.SafeElectricity.tags.CIn == nil then sensors.SafeElectricity.tags.CIn = {} end sensors.SafeElectricity.tags.CIn[chn] = data.tags.N_phase_cur log_print.debug(" safeelectricity " .. chn .. " CIn " .. sensors.SafeElectricity.tags.CIn[chn]) end, A_phase_temp = function() if sensors.SafeElectricity.tags.CTa == nil then sensors.SafeElectricity.tags.CTa = {} end sensors.SafeElectricity.tags.CTa[chn] = data.tags.A_phase_temp log_print.debug(" safeelectricity " .. chn .. " CTa " .. sensors.SafeElectricity.tags.CTa[chn]) end, B_phase_temp = function() if sensors.SafeElectricity.tags.CTb == nil then sensors.SafeElectricity.tags.CTb = {} end sensors.SafeElectricity.tags.CTb[chn] = data.tags.B_phase_temp log_print.debug(" safeelectricity " .. chn .. " CTb " .. sensors.SafeElectricity.tags.CTb[chn]) end, C_phase_temp = function() if sensors.SafeElectricity.tags.CTc == nil then sensors.SafeElectricity.tags.CTc = {} end sensors.SafeElectricity.tags.CTc[chn] = data.tags.C_phase_temp log_print.debug(" safeelectricity " .. chn .. " CTc " .. sensors.SafeElectricity.tags.CTc[chn]) end, N_phase_temp = function() if sensors.SafeElectricity.tags.CTn == nil then sensors.SafeElectricity.tags.CTn = {} end sensors.SafeElectricity.tags.CTn[chn] = data.tags.N_phase_temp log_print.debug(" safeelectricity " .. chn .. " CTn " .. sensors.SafeElectricity.tags.CTn[chn]) end, combined_elec = function() if sensors.SafeElectricity.tags.CEnergy == nil then sensors.SafeElectricity.tags.CEnergy = {} end sensors.SafeElectricity.tags.CEnergy[chn] = data.tags.combined_elec log_print.debug(" safeelectricity " .. chn .. " CEnergy " .. sensors.SafeElectricity.tags.CEnergy[chn]) end, leakage_curr = function() if sensors.SafeElectricity.tags.CResidual == nil then sensors.SafeElectricity.tags.CResidual = {} end sensors.SafeElectricity.tags.CResidual[chn] = data.tags.leakage_curr log_print.debug(" safeelectricity " .. chn .. " CResidual " .. sensors.SafeElectricity.tags.CResidual[chn]) end, warn1 = function() sensors.SafeElectricity.warn1[chn] = data.tags.warn1 log_print.debug(" safeelectricity " .. chn .. " warn1 " .. sensors.SafeElectricity.warn1[chn]) end, warn2 = function() sensors.SafeElectricity.warn2[chn] = data.tags.warn2 log_print.debug(" safeelectricity " .. chn .. " warn2 " .. sensors.SafeElectricity.warn2[chn]) end } for k, v in pairs(data.tags) do -- print(k, v) if params[k] then params[k]() end end sensors.PowerMeter.lastActive = os.time() end } local function getTime(offset) return os.date("*t", os.time() + 0 + (offset or 0)) end local function length(t) local res = 0 for k, v in pairs(t) do res = res + 1 end return res end function sensor_monitor.process(topic, payload) -- xpcall(function () -- local service = string.split(topic, "/")[8] local obj = cjson.decode(payload) local sn = string.split(obj.sn, "_")[2] local service = obj.identifier local node = nodes[sn] local device_type = node.template.name obj.tags = cjson.decode(obj.tag_node) WarnStatus.lastCommunication[sn].lastActive = os.time() -- 更新下挂设备通信时间 sensorUpdate = true if sensor_resolve[device_type] then sensor_resolve[device_type](service, obj) end sensorUpdate = false -- end,function (err) -- log_print.info(err) -- end) end function sensor_monitor.get_status() return sensors end function sensor_monitor.isDiMannual() return isDiMannual end function sensor_monitor.get_sensorUpdate() return sensorUpdate end function sensor_monitor.updateDO(value) sensors.ADIO.tags.DO = value end function sensor_monitor.loadNodes() nodes = devices.get_nodes() -- log_print.info(cjson.encode(nodes)) -- 下挂设备离线标志 for k, v in pairs(nodes) do if WarnStatus.lastCommunication[v.sn] == nil then -- log_print.info(v.sn) WarnStatus.lastCommunication[v.sn] = {} WarnStatus.lastCommunication[v.sn].lastActive = os.time() WarnStatus.lastCommunication[v.sn].disconnected = false WarnStatus.lastCommunication[v.sn].type = v.type elseif not WarnStatus.lastCommunication[v.sn].disconnected then WarnStatus.lastCommunication[v.sn].lastActive = os.time() end end -- 通用告警标志 if WarnStatus.commonWarn == nil then WarnStatus.commonWarn = {} local common = {"TemperatureWarn", "HumidityWarn", "FrontDoorOpen", "BackDoorOpen", "Immersion", "Surge", "Smoke", "BreakerTripped", "Extinguishern1", "Extinguishern2", "PowerDown"} for k, v in pairs(common) do WarnStatus.commonWarn[v] = false end end -- 电表告警标志 if WarnStatus.meterWarn == nil then WarnStatus.meterWarn = {} local meter = {"OverVoltageA", "OverVoltageB", "OverVoltageC", "UnderVoltageA", "UnderVoltageB", "UnderVoltageC", "OverCurrentA", "OverCurrentB", "OverCurrentC", "UnderCurrentA", "UnderCurrentB", "UnderCurrentC", "PhaseWarnA", "PhaseWarnB", "PhaseWarnC"} for k, v in pairs(meter) do WarnStatus.meterWarn[v] = false end end -- 安全用电模块告警标志 local parm = {"PsOverVoltage", "PsOverCurrent", "PsOverTemperature", "PsResidualCurrent", "PsOverPower"} if WarnStatus.safeelecWarn == nil then WarnStatus.safeelecWarn = {} for i = 1, SAFE_CONT, 1 do local str = "SafeElectricity" .. i WarnStatus.safeelecWarn[str] = {} for k, v in pairs(parm) do WarnStatus.safeelecWarn[str][v] = false end end elseif length(WarnStatus.safeelecWarn) < SAFE_CONT then -- 若添加设备,则WarnStatus对应自动添加 local start = length(WarnStatus.safeelecWarn) for i = start + 1, SAFE_CONT, 1 do local str = "SafeElectricity" .. i WarnStatus.safeelecWarn[str] = {} for k, v in pairs(parm) do WarnStatus.safeelecWarn[str][v] = false end end end -- 多路开关控制器告警标志 if WarnStatus.multiWarn == nil then WarnStatus.multiWarn = {} WarnStatus.multiWarn.TurnOnWarn = {} WarnStatus.multiWarn.TurnOffWarn = {} for i = 1, MULTI_CONT, 1 do local str = "MultiSwitch" .. i WarnStatus.multiWarn.TurnOnWarn[str] = {} for j = 1, 6, 1 do WarnStatus.multiWarn.TurnOnWarn[str][j] = false end end for i = 1, MULTI_CONT, 1 do local str = "MultiSwitch" .. i WarnStatus.multiWarn.TurnOffWarn[str] = {} for j = 1, 6, 1 do WarnStatus.multiWarn.TurnOffWarn[str][j] = false end end end -- 接触器告警标志 if WarnStatus.contactorWarn == nil then WarnStatus.contactorWarn = {} WarnStatus.contactorWarn.TurnOnWarn = {} WarnStatus.contactorWarn.TurnOffWarn = {} for i = 1, 8, 1 do WarnStatus.contactorWarn.TurnOnWarn[i] = false end for j = 1, 8, 1 do WarnStatus.contactorWarn.TurnOffWarn[j] = false end end configuration.set("WarnStatus", WarnStatus) end function sensor_monitor.init() --[[ sensors.PowerMeter.tags.Energy = {} sensors.PowerMeter.tags.PositiveEnergy = {} sensors.PowerMeter.tags.ReverseEnergy = {} sensors.PowerSwitch.tags.CIa = {} sensors.PowerSwitch.tags.CIb = {} sensors.PowerSwitch.tags.CIc = {} sensors.PowerSwitch.tags.ASWTemp = {} for i = 1, POWER_METER_COUNT, 1 do sensors.PowerMeter.tags.Energy[i] = cjson.null sensors.PowerMeter.tags.PositiveEnergy[i] = cjson.null sensors.PowerMeter.tags.ReverseEnergy[i] = cjson.null end for i = 1, SMART_SWITCH_COUNT, 1 do sensors.PowerSwitch.tags.CIa[i] = cjson.null sensors.PowerSwitch.tags.CIb[i] = cjson.null sensors.PowerSwitch.tags.CIc[i] = cjson.null sensors.PowerSwitch.tags.ASWTemp[i] = cjson.null end ]] sensor_monitor.loadNodes() -- 摄像头连接检测 sys.taskInit(function() local nodes = devices.get_nodes() local cameras = {} for _, v in pairs(nodes) do if v.template.name == "SDBCamera" then cameras[#cameras + 1] = v end end local function ping_exec(ip, timeout) local file local success = false os.execute("rm -f /tmp/pingresult") os.execute("ping -c 1 -w 1 -q -n " .. ip .. " > /tmp/pingresult &") for i = 1, timeout, 500 do -- 最长延时1秒 =>判断2次 sys.wait(500) -- log_print.info("waiting...", i, timeout) file = io.open("/tmp/pingresult", "r") if file then local data = file:read("*a") if data ~= "" and string.find(data, "ping statistics") and (string.find(data, "100% packet loss") == nil or string.find(data, "Invalid argument") == nil) then success = true break end end end if file then file:close() end return success end while true do for _, v in pairs(cameras) do local result = ping_exec(v.ip_addr, 1000) log_print.info("ping camera ==> ", "SN: ", v.sn, "IP: ", v.ip_addr, "RESULT: ", result) if result then WarnStatus.lastCommunication[v.sn].lastActive = os.time() end end sys.wait(10 * 1000) end end) -- 告警上报 sys.taskInit(function() -- event.wait("", 65000) sys.wait(65 * 1000) -- local tosensor = { -- ADIO = "ADIO", -- TempHumi = "TempHumi", -- Immersion = "Immersion", -- Smoke = "Smoke", -- PowerMeter = "PowerMeter", -- SmartSwitch = "PowerSwitch" -- } while true do local warnings = {} -- 变化告警信息 local warnings_all = {} -- 所有告警信息 local count = 0 local wanringNames = { ADIO = {mark = "Disconnect_IO", ebeb = 1, des = "PLC模块"}, TempHumi = {mark = "Disconnect_TH", ebeb = 2, des = "温湿度传感器"}, PowerMeter = {mark = "Disconnect_EMeter", ebeb = 3, des = "电表"}, SDBCamera = {mark = "Disconnect_CAM", ebeb = 4, des = "相机"}, SmartLock = {mark = "Disconnect_Lock", ebeb = 5, des = "门锁"}, SafeElectricity = {mark = "Disconnect_PS", ebeb = 6, des = "安全用电模块"}, MultiSwitch = {mark = "Disconnect_MS", ebeb = 7, des = "多路开关控制器"}, --Immersion = "Disconnect_Water", --Smoke = "Disconnect_Smoke", --ARCM300JnTn = "Disconnect_ARCM300", --PowerSwitch = "Disconnect_ASW" } log_print.info("Checking the sensor disconnection alarm...") for k, v in pairs(WarnStatus.lastCommunication) do -- 传感器断线告警 -- log_print.info(" now device sn: ", k, " disconnected ", v.disconnected, " time diff ", os.time(), " ", v.lastActive) if (v.disconnected and os.time() - v.lastActive < SdbConfig.DeviceTimeout) or -- 恢复 (not v.disconnected and os.time() - v.lastActive > SdbConfig.DeviceTimeout) then -- 离线 v.disconnected = not v.disconnected local node = nodes[k] local chn = devices.getChn(k) --log_print.info(" device sn: ", k, " ch: ", chn) if chn and chn >= 1 then -- 多路 if wanringNames[node.template.name] then if bit.band(bit.rshift(WarnConfig.OfflineMask, wanringNames[node.template.name].ebeb - 1), 0x01) == 1 then -- 是否使能离线告警 warnings[wanringNames[node.template.name].mark .. (chn or "")] = v.disconnected and 1 or 0 if v.disconnected then log_print.info(" 设备离线 Sensor warnings :", wanringNames[node.template.name].des, chn, v.disconnected and 1 or 0) else log_print.info(" 设备恢复 Sensor warnings :", node.template.name, chn, v.disconnected and 1 or 0) end count = count + 1 end end elseif chn and chn == -1 then -- 单路 if bit.band(bit.rshift(WarnConfig.OfflineMask, wanringNames[node.template.name].ebeb - 1), 0x01) == 1 then warnings[wanringNames[node.template.name].mark] = v.disconnected and 1 or 0 if v.disconnected then log_print.info(" 设备离线 Sensor warnings ", wanringNames[node.template.name].des, v.disconnected and 1 or 0) else log_print.info(" 设备恢复 Sensor warnings ", wanringNames[node.template.name].des, v.disconnected and 1 or 0) end count = count + 1 end else -- 虚拟控制器 + nil end end if 1 then local node = nodes[k] local chn = devices.getChn(k) --log_print.info(" device sn: ", k, " ch: ", chn) if chn and chn >= 1 then -- 多路 if wanringNames[node.template.name] then if bit.band(bit.rshift(WarnConfig.OfflineMask, wanringNames[node.template.name].ebeb - 1), 0x01) == 1 then -- 是否使能离线告警 warnings_all[wanringNames[node.template.name].mark .. (chn or "")] = v.disconnected and 1 or 0 if v.disconnected then -- log_print.info(" 设备离线 Sensor warnings :", wanringNames[node.template.name].des, chn, v.disconnected and 1 or 0) else -- log_print.info(" 设备恢复 Sensor warnings :", node.template.name, chn, v.disconnected and 1 or 0) end end end elseif chn and chn == -1 then -- 单路 if bit.band(bit.rshift(WarnConfig.OfflineMask, wanringNames[node.template.name].ebeb - 1), 0x01) == 1 then warnings_all[wanringNames[node.template.name].mark] = v.disconnected and 1 or 0 if v.disconnected then -- log_print.info(" 设备离线 Sensor warnings ", wanringNames[node.template.name].des, v.disconnected and 1 or 0) else -- log_print.info(" 设备恢复 Sensor warnings ", wanringNames[node.template.name].des, v.disconnected and 1 or 0) end end else -- 虚拟控制器 + nil end end end local TempHumi_table = { {mark = "Temp", des = "温度", wmark = "Temperature"}, {mark = "Hum", des = "湿度", wmark = "Humidity"} } log_print.info("Checking Temperature and Humidity Alarms...") if length(sensors.TempHumi.tags) > 0 then -- 温湿度告警 for k, v in pairs(TempHumi_table) do if sensors.TempHumi.tags[v.mark] then --log_print.info(" now : ", k, " value ", v, " _H ", WarnConfig[k]) if WarnStatus.commonWarn[v.mark] and sensors.TempHumi.tags[v.mark] < WarnConfig[v.wmark] then WarnStatus.commonWarn[v.mark] = false warnings[v.mark] = 0 log_print.info(" 温湿度 TempHumi warnings : ", v.des, warnings[v.mark]) count = count + 1 elseif not WarnStatus.commonWarn[v.mark] and sensors.TempHumi.tags[v.mark] >= WarnConfig[v.wmark] then WarnStatus.commonWarn[v.mark] = true warnings[v.mark] = 1 log_print.info(" 温湿度 TempHumi warnings : ", v.des, warnings[v.mark]) count = count + 1 end if 1 then warnings_all[v.mark] = WarnStatus.commonWarn[v.mark] and 1 or 0 end end end end local mark_table = { {mark = "FrontDoorOpen", bitmap = 9, ebeb = 1, des = "前门"}, {mark = "BackDoorOpen", bitmap = 10, ebeb = 1, des = "后门"}, {mark = "Immersion", bitmap = 11, ebeb = 2, des = "水浸"}, {mark = "Surge", bitmap = 12, ebeb = 3, des = "浪涌保护器"}, {mark = "Smoke", bitmap = 13, ebeb = 4, des = "烟感"}, {mark = "BreakerTripped", bitmap = 14, ebeb = 5, des = "断路器"}, {mark = "Extinguishern1", bitmap = 16, ebeb = 6, des = "自动灭火器1"}, {mark = "Extinguishern2", bitmap = 17, ebeb = 6, des = "自动灭火器2"}, {mark = "PowerDown", bitmap = 20, ebeb = 7, des = "断电告警"} } log_print.info("Checking general DI alarms...") for k, v in pairs(mark_table) do -- 前后门开告警 水浸告警 浪涌告警 烟感告警 输入断路器告警 自动灭火器12告警 断电告警 if WarnStatus.commonWarn[v.mark] and bit.band(sensors.ADIO.di_status, bit.lshift(1, v.bitmap - 1)) == 0 then WarnStatus.commonWarn[v.mark] = false if bit.band(bit.rshift(WarnConfig.DIWarnMask, v.ebeb - 1), 0x01) == 1 then -- 是否使能DI告警 warnings[v.mark] = 0 log_print.info(" 通用DI general DI warnings :", v.des, 0) count = count + 1 end elseif not WarnStatus.commonWarn[v.mark] and bit.band(sensors.ADIO.di_status, bit.lshift(1, v.bitmap - 1)) ~= 0 then WarnStatus.commonWarn[v.mark] = true if bit.band(bit.rshift(WarnConfig.DIWarnMask, v.ebeb - 1), 0x01) == 1 then warnings[v.mark] = 1 log_print.info(" 通用DI general DI warnings :", v.des, 1) count = count + 1 end end if 1 then warnings_all[v.mark] = WarnStatus.commonWarn[v.mark] and 1 or 0 end end local phase_table = { {item = "Ua", mark = "PhaseWarnA", des = "A相缺相"}, {item = "Ub", mark = "PhaseWarnB", des = "B相缺相"}, {item = "Uc", mark = "PhaseWarnC", des = "C相缺相"} } local meter_table = { {item = "Ua", overmark = "OverVoltageA", undermark = "UnderVoltageA", _H = WarnConfig.OverVoltage, _L = WarnConfig.UnderVoltage, overdes = "A相过压", underdes = "A相欠压"}, {item = "Ub", overmark = "OverVoltageB", undermark = "UnderVoltageB", _H = WarnConfig.OverVoltage, _L = WarnConfig.UnderVoltage, overdes = "B相过压", underdes = "B相欠压" }, {item = "Uc", overmark = "OverVoltageC", undermark = "UnderVoltageC", _H = WarnConfig.OverVoltage, _L = WarnConfig.UnderVoltage, overdes = "C相过压", underdes = "C相欠压" }, {item = "Ia", overmark = "OverCurrentA", undermark = "UnderCurrentA", _H = WarnConfig.OverCurrent, _L = WarnConfig.UnderCurrent, overdes = "A相过流", underdes = "A相欠流" }, {item = "Ib", overmark = "OverCurrentB", undermark = "UnderCurrentB", _H = WarnConfig.OverCurrent, _L = WarnConfig.UnderCurrent, overdes = "B相过流", underdes = "B相欠流" }, {item = "Ic", overmark = "OverCurrentC", undermark = "UnderCurrentC", _H = WarnConfig.OverCurrent, _L = WarnConfig.UnderCurrent, overdes = "C相过流", underdes = "C相欠流" } } log_print.info("Checking meter alarms...") if length(sensors.PowerMeter.tags) > 0 then for k, v in pairs(phase_table) do -- 缺相告警 if sensors.PowerMeter.tags[v.item] then if WarnStatus.meterWarn[v.mark] and sensors.PowerMeter.tags[v.item] >= 10 then WarnStatus.meterWarn[v.mark] = false warnings[v.mark] = 0 log_print.info(" 电表 Meter phase warnings ", v.des, 0) count = count + 1 elseif not WarnStatus.meterWarn[v.mark] and sensors.PowerMeter.tags[v.item] < 10 then WarnStatus.meterWarn[v.mark] = true warnings[v.mark] = 1 log_print.info(" 电表 Meter phase warnings ", v.des, 1) count = count + 1 end end if 1 then warnings_all[v.mark] = WarnStatus.meterWarn[v.mark] and 1 or 0 end end for k, v in pairs(meter_table) do if sensors.PowerMeter.tags[v.item] then -- 欠压流告警 if WarnStatus.meterWarn[v.undermark] and sensors.PowerMeter.tags[v.item] >= v._L then WarnStatus.meterWarn[v.undermark] = false warnings[v.undermark] = 0 log_print.info(" 电表 Meter under warnings ", v.underdes, 0) count = count + 1 elseif not WarnStatus.meterWarn[v.undermark] and sensors.PowerMeter.tags[v.item] < v._L then WarnStatus.meterWarn[v.undermark] = true warnings[v.undermark] = 1 log_print.info(" 电表 Meter under warnings ", v.underdes, 1) count = count + 1 end if 1 then warnings_all[v.undermark] = WarnStatus.meterWarn[v.undermark] and 1 or 0 end -- 过压流告警 if WarnStatus.meterWarn[v.overmark] and sensors.PowerMeter.tags[v.item] <= v._H then WarnStatus.meterWarn[v.overmark] = false warnings[v.overmark] = 0 log_print.info(" 电表 Meter over warnings ", v.overdes, 0) count = count + 1 elseif not WarnStatus.meterWarn[v.overmark] and sensors.PowerMeter.tags[v.item] > v._H then WarnStatus.meterWarn[v.overmark] = true warnings[v.overmark] = 1 log_print.info(" 电表 Meter over warnings ", v.overdes, 1) count = count + 1 end if 1 then warnings_all[v.overmark] = WarnStatus.meterWarn[v.overmark] and 1 or 0 end end end end local safe_table = { {mark = "OverVoltage", ebeb = {2, 4, 6}, des = "过压"}, {mark = "OverCurrent", ebeb = {8, 9, 10}, des = "过流"}, {mark = "OverTemp", ebeb = {1, 2, 3, 4}, des = "过温"}, {mark = "Residual", ebeb = {1}, des = "漏电流"}, {mark = "OverPower", ebeb = {12, 13, 14}, des = "过功率"}, } local Voltage, Current, Temp, Residual, Power log_print.info("Checking alarms on the safety power module...") for i = 1, SAFE_CONT, 1 do if sensors.SafeElectricity.warn1[i] ~= nil and sensors.SafeElectricity.warn2[i] ~= nil then log_print.info("check safety power module online", i) local str = "SafeElectricity" .. i for k, v in pairs(safe_table) do if v.mark == "OverVoltage" then -- 过压告警 local A_phase = bit.band(sensors.SafeElectricity.warn1[i], bit.lshift(1, v.ebeb[1] - 1)) == 0 and 0 or 1 local B_phase = bit.band(sensors.SafeElectricity.warn1[i], bit.lshift(1, v.ebeb[2] - 1)) == 0 and 0 or 1 local C_phase = bit.band(sensors.SafeElectricity.warn1[i], bit.lshift(1, v.ebeb[3] - 1)) == 0 and 0 or 1 log_print.info(str, "OverVoltage A:", A_phase, "OverVoltage B:", B_phase, "OverVoltage C:", C_phase) if A_phase == 1 or B_phase == 1 or C_phase == 1 then Voltage = 1 elseif A_phase == 0 and B_phase == 0 and C_phase == 0 then Voltage = 0 end if WarnStatus.safeelecWarn[str].PsOverVoltage and Voltage == 0 then WarnStatus.safeelecWarn[str].PsOverVoltage = false warnings["PsOverVoltage" .. i] = 0 log_print.info(" SafeElectricity overvol warnings ", v.des, i, 0) count = count + 1 elseif not WarnStatus.safeelecWarn[str].PsOverVoltage and Voltage == 1 then WarnStatus.safeelecWarn[str].PsOverVoltage = true warnings["PsOverVoltage" .. i] = 1 log_print.info(" SafeElectricity overvol warnings ", v.des, i, 1) count = count + 1 end if 1 then warnings_all["PsOverVoltage" .. i] = WarnStatus.safeelecWarn[str].PsOverVoltage and 1 or 0 end end if v.mark == "OverCurrent" then -- 过流告警 local A_phase = bit.band(sensors.SafeElectricity.warn1[i], bit.lshift(1, v.ebeb[1] - 1)) == 0 and 0 or 1 local B_phase = bit.band(sensors.SafeElectricity.warn1[i], bit.lshift(1, v.ebeb[2] - 1)) == 0 and 0 or 1 local C_phase = bit.band(sensors.SafeElectricity.warn1[i], bit.lshift(1, v.ebeb[3] - 1)) == 0 and 0 or 1 log_print.info(str, "OverCurrent A:", A_phase, "OverCurrent B:", B_phase, "OverCurrent C:", C_phase) if A_phase == 1 or B_phase == 1 or C_phase == 1 then Current = 1 elseif A_phase == 0 and B_phase == 0 and C_phase == 0 then Current = 0 end if WarnStatus.safeelecWarn[str].PsOverCurrent and Current == 0 then WarnStatus.safeelecWarn[str].PsOverCurrent = false warnings["PsOverCurrent" .. i] = 0 log_print.info(" SafeElectricity overcur warnings ", v.des, i, 0) count = count + 1 elseif not WarnStatus.safeelecWarn[str].PsOverCurrent and Current == 1 then WarnStatus.safeelecWarn[str].PsOverCurrent = true warnings["PsOverCurrent" .. i] = 1 log_print.info(" SafeElectricity overcr warnings ", v.des, i, 1) count = count + 1 end if 1 then warnings_all["PsOverCurrent" .. i] = WarnStatus.safeelecWarn[str].PsOverCurrent and 1 or 0 end end if v.mark == "OverTemp" then -- 过温告警 local A_phase = bit.band(sensors.SafeElectricity.warn2[i], bit.lshift(1, v.ebeb[1] - 1)) == 0 and 0 or 1 local B_phase = bit.band(sensors.SafeElectricity.warn2[i], bit.lshift(1, v.ebeb[2] - 1)) == 0 and 0 or 1 local C_phase = bit.band(sensors.SafeElectricity.warn2[i], bit.lshift(1, v.ebeb[3] - 1)) == 0 and 0 or 1 local N_phase = bit.band(sensors.SafeElectricity.warn2[i], bit.lshift(1, v.ebeb[4] - 1)) == 0 and 0 or 1 log_print.info(str, "OverTemp A:", A_phase, "OverTemp B:", B_phase, "OverTemp C:", C_phase, "OverTemp N:", N_phase) if A_phase == 1 or B_phase == 1 or C_phase == 1 or N_phase == 1 then Temp = 1 elseif A_phase == 0 and B_phase == 0 and C_phase == 0 and N_phase == 0 then Temp = 0 end if WarnStatus.safeelecWarn[str].PsOverTemperature and Temp == 0 then WarnStatus.safeelecWarn[str].PsOverTemperature = false warnings["PsOverTemperature" .. i] = 0 log_print.info(" SafeElectricity overtmp warnings ", v.des, i, 0) count = count + 1 elseif not WarnStatus.safeelecWarn[str].PsOverTemperature and Temp == 1 then WarnStatus.safeelecWarn[str].PsOverTemperature = true warnings["PsOverTemperature" .. i] = 1 log_print.info(" SafeElectricity overtmp warnings ", v.des, i, 1) count = count + 1 end if 1 then warnings_all["PsOverTemperature" .. i] = WarnStatus.safeelecWarn[str].PsOverTemperature and 1 or 0 end end if v.mark == "Residual" then -- 漏电告警 local resi = bit.band(sensors.SafeElectricity.warn1[i], bit.lshift(1, v.ebeb[1] - 1)) == 0 and 0 or 1 log_print.info(str, "Residual:", resi) if resi == 1 then Residual = 1 else Residual = 0 end if WarnStatus.safeelecWarn[str].PsResidualCurrent and Residual == 0 then WarnStatus.safeelecWarn[str].PsResidualCurrent = false warnings["PsResidualCurrent" .. i] = 0 log_print.info(" SafeElectricity sesidualCur warnings ", v.des, i, 0) count = count + 1 elseif not WarnStatus.safeelecWarn[str].PsResidualCurrent and Residual == 1 then WarnStatus.safeelecWarn[str].PsResidualCurrent = true warnings["PsResidualCurrent" .. i] = 1 log_print.info(" SafeElectricity sesidualCur warnings ", v.des, i, 1) count = count + 1 end if 1 then warnings_all["PsResidualCurrent" .. i] = WarnStatus.safeelecWarn[str].PsResidualCurrent and 1 or 0 end end if v.mark == "OverPower" then -- 过功率告警 local A_phase = bit.band(sensors.SafeElectricity.warn1[i], bit.lshift(1, v.ebeb[1] - 1)) == 0 and 0 or 1 local B_phase = bit.band(sensors.SafeElectricity.warn1[i], bit.lshift(1, v.ebeb[2] - 1)) == 0 and 0 or 1 local C_phase = bit.band(sensors.SafeElectricity.warn1[i], bit.lshift(1, v.ebeb[3] - 1)) == 0 and 0 or 1 log_print.info(str, "OverPower A:", A_phase, "OverPower B:", B_phase, "OverPower C:", C_phase) if A_phase == 1 or B_phase == 1 or C_phase == 1 then Power = 1 elseif A_phase == 0 and B_phase == 0 and C_phase == 0 then Power = 0 end if WarnStatus.safeelecWarn[str].PsOverPower and Power == 0 then WarnStatus.safeelecWarn[str].PsOverPower = false warnings["PsOverPower" .. i] = 0 log_print.info(" SafeElectricity overpower warnings ", v.des, i, 0) count = count + 1 elseif not WarnStatus.safeelecWarn[str].PsOverPower and Power == 1 then WarnStatus.safeelecWarn[str].PsOverPower = true warnings["PsOverPower" .. i] = 1 log_print.info(" SafeElectricity overpower warnings ", v.des, i, 1) count = count + 1 end if 1 then warnings_all["PsOverPower" .. i] = WarnStatus.safeelecWarn[str].PsOverPower and 1 or 0 end end end else log_print.info("check safety power module offline", i) end end if LIGHT_TYPE == 1 then log_print.info("Checking alarms on the MultiSwitch...") local time = getTime() local offsetNow = time.hour * 60 + time.min log_print.info("offsetNow :", offsetNow) for i = 1, MULTI_CONT, 1 do -- 1.根据当前时间获取多路开关控制器的策略 (协议限制:单个多路开关器每个通道开关灯时间必须一致) local sch = {} local ctrl = "CTRL" .. i if Multi_Strategy[1][ctrl].k_cont then log_print.info("Now MultiSwitch :", i, "K CONT : ", Multi_Strategy[1][ctrl].k_cont) if Multi_Strategy[1][ctrl].K1.time and #Multi_Strategy[1][ctrl].K1.value ~= 0 then log_print.info("K1 time :", Multi_Strategy[1][ctrl].K1.time) log_print.info("K1 :", Multi_Strategy[1][ctrl].K1.value[1] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K1.value[2] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K1.value[3] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K1.value[4] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K1.value[5] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K1.value[6] == 0 and 0 or 1) end if Multi_Strategy[1][ctrl].K2.time and #Multi_Strategy[1][ctrl].K2.value ~= 0 then log_print.info("K2 time :", Multi_Strategy[1][ctrl].K2.time) log_print.info("K2 :", Multi_Strategy[1][ctrl].K2.value[1] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K2.value[2] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K2.value[3] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K2.value[4] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K2.value[5] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K2.value[6] == 0 and 0 or 1) end if Multi_Strategy[1][ctrl].K3.time and #Multi_Strategy[1][ctrl].K3.value ~= 0 then log_print.info("K3 time :", Multi_Strategy[1][ctrl].K3.time) log_print.info("K3 :", Multi_Strategy[1][ctrl].K3.value[1] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K3.value[2] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K3.value[3] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K3.value[4] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K3.value[5] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K3.value[6] == 0 and 0 or 1) end if Multi_Strategy[1][ctrl].K4.time and #Multi_Strategy[1][ctrl].K4.value ~= 0 then log_print.info("K4 time :", Multi_Strategy[1][ctrl].K4.time) log_print.info("K4 :", Multi_Strategy[1][ctrl].K4.value[1] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K4.value[2] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K4.value[3] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K4.value[4] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K4.value[5] == 0 and 0 or 1, Multi_Strategy[1][ctrl].K4.value[6] == 0 and 0 or 1) end for j = 1, Multi_Strategy[1][ctrl].k_cont, 1 do -- 获取当前时间所处策略的 K1~K2~K3~K4~ 时间段的策略 local _L = "K" .. j local h = j + 1 local _H = "K" .. h if offsetNow >= Multi_Strategy[1][ctrl][_L].time and (j == Multi_Strategy[1][ctrl].k_cont or offsetNow < Multi_Strategy[1][ctrl][_H].time) then log_print.info("Now K accord with :", _L, _H) sch = Multi_Strategy[1][ctrl][_L].value break end end end log_print.info("MultiSwitch :", i, "PLAN:", sch[1] == 0 and 0 or 1, sch[2] == 0 and 0 or 1, sch[3] == 0 and 0 or 1, sch[4] == 0 and 0 or 1, sch[5] == 0 and 0 or 1, sch[6] == 0 and 0 or 1) -- 2.开关灯异常检测 local multi_sn = "MultiSwitch" .. i local value = sensors.MultiSwitch.tags.MSDI[i] if value then for n = 1, 6, 1 do local plan = sch[n] == 0 and 0 or 1 local real = bit.band(bit.rshift(value, n - 1), 0x01) == 1 and 1 or 0 local channel = (i-1)*6 + n if real ~= plan then if plan == 1 and not WarnStatus.multiWarn.TurnOnWarn[multi_sn][n] then WarnStatus.multiWarn.TurnOnWarn[multi_sn][n] = true warnings["TurnOnWarn" .. channel] = 1 log_print.info(" MultiSwitch TurnOnWarn warnings ", "TurnOnWarn", channel, 1) count = count + 1 elseif plan == 0 and not WarnStatus.multiWarn.TurnOffWarn[multi_sn][n] then WarnStatus.multiWarn.TurnOffWarn[multi_sn][n] = true warnings["TurnOffWarn" .. channel] = 1 log_print.info(" MultiSwitch TurnOffWarn warnings ", "TurnOffWarn", channel, 1) count = count + 1 end else if plan == 1 and WarnStatus.multiWarn.TurnOnWarn[multi_sn][n] then WarnStatus.multiWarn.TurnOnWarn[multi_sn][n] = false warnings["TurnOnWarn" .. channel] = 0 log_print.info(" MultiSwitch TurnOnWarn warnings ", "TurnOnWarn", channel, 0) -- 开灯告警恢复 count = count + 1 elseif plan == 0 and WarnStatus.multiWarn.TurnOffWarn[multi_sn][n] then WarnStatus.multiWarn.TurnOffWarn[multi_sn][n] = false warnings["TurnOffWarn" .. channel] = 0 log_print.info(" MultiSwitch TurnOffWarn warnings ", "TurnOffWarn", channel, 0) -- 关灯告警恢复 count = count + 1 end end if 1 then warnings_all["TurnOnWarn" .. channel] = WarnStatus.multiWarn.TurnOnWarn[multi_sn][n] and 1 or 0 warnings_all["TurnOffWarn" .. channel] = WarnStatus.multiWarn.TurnOffWarn[multi_sn][n] and 1 or 0 end end end end else log_print.info("Checking alarms on the Contactor...") local time = getTime() local offsetNow = time.hour * 60 + time.min log_print.info("offsetNow :", offsetNow) -- 1.根据当前时间获取接触器的策略(协议限制:接触器每个通道开关灯时间可不一致) local sch = {} for i = 1, TOTAL_CH, 1 do local ka = "KA" .. string.format("%d", i) log_print.info("Now Channel :", ka, "g : ", Conta_Strategy[1][ka].g.time, "k : ", Conta_Strategy[1][ka].k.time) if Conta_Strategy[1][ka].g.time < Conta_Strategy[1][ka].k.time then -- 正常逻辑: 关灯时间一定小于开灯时间,白天关灯,晚上开灯 if offsetNow >= Conta_Strategy[1][ka].k.time then sch[i] = 1 elseif offsetNow >= Conta_Strategy[1][ka].g.time then sch[i] = 0 end else if offsetNow >= Conta_Strategy[1][ka].g.time then sch[i] = 0 elseif offsetNow >= Conta_Strategy[1][ka].k.time then sch[i] = 1 end end end log_print.info("Contactor :", "PLAN:", sch[1] == 0 and 0 or 1, sch[2] == 0 and 0 or 1, sch[3] == 0 and 0 or 1, sch[4] == 0 and 0 or 1, sch[5] == 0 and 0 or 1, sch[6] == 0 and 0 or 1, sch[7] == 0 and 0 or 1, sch[8] == 0 and 0 or 1) -- 2.开关灯异常检测 local value = sensors.ADIO.di_status if value then for i = 1, TOTAL_CH, 1 do local plan = sch[i] == 0 and 0 or 1 local real = bit.band(bit.rshift(value, i - 1), 0x01) == 1 and 1 or 0 local channel = i if real ~= plan then if plan == 1 and not WarnStatus.contactorWarn.TurnOnWarn[i] then WarnStatus.contactorWarn.TurnOnWarn[i] = true warnings["TurnOnWarn" .. channel] = 1 log_print.info(" Contactor TurnOnWarn warnings ", "TurnOnWarn", channel, 1) count = count + 1 elseif plan == 0 and not WarnStatus.contactorWarn.TurnOffWarn[i] then WarnStatus.contactorWarn.TurnOffWarn[i] = true warnings["TurnOffWarn" .. channel] = 1 log_print.info(" Contactor TurnOffWarn warnings ", "TurnOffWarn", channel, 1) count = count + 1 end else if plan == 1 and WarnStatus.contactorWarn.TurnOnWarn[i] then WarnStatus.contactorWarn.TurnOnWarn[i] = false warnings["TurnOnWarn" .. channel] = 0 log_print.info(" Contactor TurnOnWarn warnings ", "TurnOnWarn", channel, 0) -- 开灯告警恢复 count = count + 1 elseif plan == 0 and WarnStatus.contactorWarn.TurnOffWarn[i] then WarnStatus.contactorWarn.TurnOffWarn[i] = false warnings["TurnOffWarn" .. channel] = 0 log_print.info(" Contactor TurnOffWarn warnings ", "TurnOffWarn", channel, 0) -- 关灯告警恢复 count = count + 1 end end if 1 then warnings_all["TurnOnWarn" .. channel] = WarnStatus.contactorWarn.TurnOnWarn[i] and 1 or 0 warnings_all["TurnOffWarn" .. channel] = WarnStatus.contactorWarn.TurnOffWarn[i] and 1 or 0 end end end end --[[ if sensors.PowerSwitch.tags.ASWTemp then --智能空开温度告警 for k, v in ipairs(sensors.PowerSwitch.tags.ASWTemp) do if type(v) == "number" then if WarnStatus.awsTempWarn[k] and v < WarnConfig.Thr_ASWTemp_R then WarnStatus.awsTempWarn[k] = false warnings["ASW_TempWarn" .. k] = 0 count = count + 1 elseif not WarnStatus.awsTempWarn[k] and v >= WarnConfig.Thr_ASWTemp_H then WarnStatus.awsTempWarn[k] = true warnings["ASW_TempWarn" .. k] = 1 count = count + 1 end end end end if sensors.PowerSwitch.exsist then --智能空开分路告警 for i = 1, SMART_SWITCH_COUNT, 1 do if WarnStatus.awsChWarn[i] and bit.band(sensors.PowerSwitch.exsist, bit.lshift(1, i - 1)) ~= 0 then WarnStatus.awsChWarn[i] = false warnings["Disconnect_ASW" .. i] = 0 count = count + 1 elseif not WarnStatus.awsChWarn[i] and bit.band(sensors.PowerSwitch.exsist, bit.lshift(1, i - 1)) == 0 then for k1, v1 in pairs(sensors.PowerSwitch.tags) do log_print.info("warnings", k1, v1) if type(v1) == "table" then sensors.PowerSwitch.tags[k1][i] = cjson.null end end WarnStatus.awsChWarn[i] = true warnings["Disconnect_ASW" .. i] = 1 count = count + 1 end end end ]] if WarnStatus.warnings_all == nil then WarnStatus.warnings_all = {} end for k, v in pairs(warnings_all) do WarnStatus.warnings_all[k] = v == 1 and 1 or 0 end if count ~= 0 then for k, v in pairs(warnings) do WarnStatus.warnings[k] = v == 1 and 1 or 0 end protocol.report_warning(warnings) configuration.set("WarnStatus", WarnStatus) end sys.wait(5 * 1000) end end) -- 电压、总电流、用电安全数据根据上报阈值配置进行变化上报,DO、DI、MSDO、MSDI 任意一个变化引起上报,其它值不执行变化上报 sys.taskInit(function() -- event.wait("", 65000) sys.wait(65 * 1000) while true do local tags = {} count = 0 for k, v in pairs(report_tags) do --状态变化上报 local status = sensors[v.sensor].tags[k] if status then if not old_status[k] then if type(status) == "table" then old_status[k] = cjson.decode(cjson.encode(status)) --生成新对象 else old_status[k] = status end -- tags[k] = status -- count = count + 1 else local compare = {} compare[REPORT_VOLTAGE] = function(old, new) if not (SdbConfig.Rpt_min_U >= 5 and SdbConfig.Rpt_min_U <= 220) then return false end if type(new) == "table" then for i = 1, #new, 1 do if type(old[i]) ~= type(new[i]) or (type(old[i]) == "number" and type(new[i]) == "number" and math.abs(old[i] - new[i]) > SdbConfig.Rpt_min_U) then log_print.info("the voltage fluctuation exceeds the threshold") return true end end else --log_print.info("report", old, new, type(old), type(new)) if type(old) ~= type(new) or (type(old) == "number" and type(new) == "number" and math.abs(old - new) > SdbConfig.Rpt_min_U) then log_print.info("the voltage fluctuation exceeds the threshold") return true end end end compare[REPORT_CURRENT] = function(old, new) if not (SdbConfig.Rpt_min_I >= 10 and SdbConfig.Rpt_min_I <= 5000) then return false end if type(new) == "table" then for i = 1, #new, 1 do --log_print.info("report", old[i], new[i]) if type(old[i]) ~= type(new[i]) or (type(old[i]) == "number" and type(new[i]) == "number" and math.abs(old[i] - new[i]) > SdbConfig.Rpt_min_I) then log_print.info("the current fluctuation exceeds the threshold") return true end end else if type(old) ~= type(new) or (type(old) == "number" and type(new) == "number" and math.abs(old - new) > SdbConfig.Rpt_min_I) then log_print.info("the current fluctuation exceeds the threshold") return true end end end compare[REPORT_TEXT] = function(old, new) -- log_print.info("report", old, new) if old ~= new then log_print.info("DI/DO change") return true end end compare[REPORT_MUTI] = function(old, new) if type(new) == "table" then for i = 1, MULTI_CONT, 1 do -- log_print.info("report", old[i], new[i]) if (old[i] and new[i]) and (type(old[i]) == "number" and type(new[i]) == "number") and old[i] ~= new[i] then log_print.info("MSDI/MSDO change") return true end end end end if compare[v.type](old_status[k], status) then if type(status) == "table" then old_status[k] = cjson.decode(cjson.encode(status)) --生成新对象 else old_status[k] = status end tags[k] = status -- 注意:只有变化的数据才会上报 count = count + 1 end end end end if count ~= 0 then protocol.report(tags) end sys.wait(15 * 1000) end end) end function sensor_monitor.update_status() for k, v in pairs(report_tags) do local status = sensors[v.sensor].tags[k] if type(status) == "table" then old_status[k] = cjson.decode(cjson.encode(status)) -- 生成新对象 else old_status[k] = status end end end local doorOpen = {false, false} -- 前后门状态,前门 后门 function sensor_monitor.camera_linkage() local enable = CameraConfig.enable if enable == 1 then for k, v in pairs(CameraConfig.Config) do local door = bit.band(sensors.ADIO.di_status, bit.lshift(1, v.di - 1)) ~= 0 if door ~= doorOpen[k] then if door == true then log_print.info("The door opens and then snap a photo ", k) -- 1 前门;2后门 protocol.take_photo(k) end doorOpen[k] = door end end end end return sensor_monitor