local syslog=require("syslog") local math=require("math") local cjson=require("cjson") -------------------------[全局参数定义]------------------------- BATT_TEMP_COUNT = 4 BATT_VOL_COUNT = 14 IFU_DAT_FILE = "/app/ifu_bak.json" -- DEVICE_OFFLINE_TIME = 20*60 DEVICE_OFFLINE_TIME = 99999999 ifu_obj={} pcs_obj={} bms_obj={} syslog.openlog("EMU", syslog.LOG_PERROR + syslog.LOG_ODELAY, "LOG_USER") PROJECT_10KW="10KW" PROJECT_3_6KW="3.6KW" PROJECT=PROJECT_10KW local function write_cache_to_file(path,ojb) local file=io.open(path, 'w+') file:seek('set') file:write(cjson.encode(ojb)) file:flush() file:close() end local function read_cache_from_file(path) local file=io.open(path, 'a+') local ojb={} file:seek('set') ojb = file:read() file:close() if(ojb == nil) then return nil end return cjson.decode(ojb) end local function parser_input(obj) if not obj or type(obj) ~= "string" then syslog.syslog("LOG_WARNING","Invalid message of virtual device") return nil,nil end local obj = cjson.decode(obj) -- --获取输入变量-- local pcs,bms=nil,nil if not obj["datas"] then syslog.syslog("LOG_WARNING","Invalid structure of virtual device,message need [datas] in object") return pcs,bms end for i,v in pairs(obj["datas"]) do if v.tags and v.tags.dev_type and v.tags.dev_type == "PCS" then if pcs == nil then pcs = {} end pcs = v.tags pcs.dev_type = nil pcs.SN = v.sn pcs.time = v.time elseif v.tags and v.tags.dev_type and v.tags.dev_type == "BMS" then if bms == nil then bms = {} end bms = v.tags bms.dev_type = nil bms.sn = v.sn bms.time = v.time end end syslog.syslog("LOG_WARNING","PCS:" .. cjson.encode(pcs or {})) syslog.syslog("LOG_WARNING","BMS:" .. cjson.encode(bms or {})) return pcs,bms end -- | BMS/PCS | variable name | (弃用) | (弃用) | emu coefficient | ifu variable name | local symbol_remap_3_6KW={ {"BMS", "Model_SN", 1, "BMS_ID", nil, "BMS_ID"}, {"BMS", "Version", 1, "BMS_SOFT_VER", nil, "BMS_SOFT_VER"}, {"BMS", "SOC", 1, "SOC", 1, "StateOfCharge"}, {"BMS", "SOH", 1, "SOH", 1, "StateOfHealth"}, {"BMS", "FullCapacity", 1, "TCap", 1000, "TotalCapacity"}, {"BMS", "ReMainCapacity", 1, "RemCap", 1000, "RemainingCapacity"}, {"BMS", "VoltageOfPack", 1, "Vbat", 1, "BatteryVoltage"}, {"BMS", "Current", 1, "Ibat", 1, "BatteryCurrent"}, -- {"PCS", "BatteryPower", 1, nil, 1, "BatteryWattage"}, --先不自己计算 -- {"PCS", "BatteryPower", 1, nil, 1, "PowerAtCharge"}, --先不自己计算 -- {"PCS", "E_BatteryCharge", 1, nil, 1000, "AccumulatedLifetimeCharge"}, --先不自己计算 -- {"PCS", "E_BatteryDischarge", 1, nil, 1000, "AccumulatedLifetimeDischarge"}, --先不自己计算 -- {"PCS", "E_BatCharge_Today", 1, nil, 1, "DailyCharge"}, --先不自己计算 -- {"PCS", "E_BatDischarge_Today", 1, nil, 1, "DailyDischarge"}, --先不自己计算 -- {"PCS", "BMSPackTemp", 1, nil, 1, "BatteryTemp"}, {"PCS", "workMode", 1, nil, 1, "InverterMode"}, {"PCS", "Temperature", 1, nil, 1, "InverterTemp"}, {"PCS", "device_sn", 1, "PCS_ID", nil, "PCS_ID"}, {"PCS", "firmware", 1, "PCS_Software_version",nil, "PCS_Software_version"}, {"PCS", "VGrid", 1, "VGrid", 1, "GridVoltage"}, {"PCS", "IGrid", 1, "IGrid", 1, "GridCurrent"}, {"PCS", "PGrid", 1, nil, 1, "GridWattage"}, {"PCS", "FGrid", 1, nil, 1, "GridFrequency"}, {"PCS", "Vpv1", 1, nil, 1, "Ppv1Voltage"}, {"PCS", "Ipv1", 1, nil, 1, "Ppv1Current"}, {"PCS", "Ppv1", 1, nil, 1, "Ppv1Wattage"}, {"PCS", "Vpv2", 1, nil, 1, "Ppv2Voltage"}, {"PCS", "Ipv2", 1, nil, 1, "Ppv2Current"}, {"PCS", "Ppv2", 1, nil, 1, "Ppv2Wattage"}, {"PCS", "E_PV_Total", 1, "TPvA", 1000, "TotalAccumulatedSolar"}, {"PCS", "E_Total_Sell", 1, "E_total_Sell", 1000, "TotalAccumulativePowerToGrId"}, {"PCS", "E_Total_Buy", 1, "E_total_Buy", 1000, "TotalAccumulativePowerFromGrid"} } local symbol_remap_10KW={ {"BMS", "Model_SN???", nil, nil, nil, "BMS_ID"}, {"BMS", "Version???", nil, nil, nil, "BMS_SoftVer"}, {"BMS", "SystemSoc", 1, "SOC", 1, "StateOfCharge"}, {"BMS", "SystemSoh", 1, "SOH", 1, "StateOfHealth"}, -- {"BMS", "FullCapacity", 1, "TCap", 1000, "TotalCapacity"}, {"BMS", "SystemEnableDiscargeEnergy",1, "RemCap", 1000, "RemainingCapacity"}, {"BMS", "SystemTotalVoltage", nil, nil, 1, "BatteryVoltage"}, {"BMS", "SystemTotalCurrent", nil, nil, 1, "BatteryCurrent"}, {"BMS", "Systemaveragetemperature", nil, nil, 1, "BatteryTemp"}, {"BMS", "RackVoltageDifference", nil, nil, 1, "Vol_Diff_bat"}, {"BMS", "SystemMaxCellVoltage", nil, nil, 1, "Vol_Higher_bat"}, {"BMS", "SystemMaxVolCellRackID", nil, nil, 1, "Vol_Higher_Bat_Rack"}, {"BMS", "SystemMaxVolCellSlaveID", nil, nil, 1, "Vol_Higher_Bat_Group"}, {"BMS", "SystemMaxVolCellID", nil, nil, 1, "Vol_Higher_Bat_No"}, {"BMS", "SystemMinCellVoltage", nil, nil, 1, "Vol_Lower_bat"}, {"BMS", "SystemMaxTempCellRackID", nil, nil, 1, "Vol_Lower_Bat_Rack"}, {"BMS", "SystemMaxTempCellSlaveID", nil, nil, 1, "Vol_Lower_Bat_Group"}, {"BMS", "SystemMaxTempCellID", nil, nil, 1, "Vol_Lower_Bat_No"}, {"BMS", "SystemMaxCellTemperature", nil, nil, 1, "Temp_Max_bat"}, {"BMS", "SystemMinCellTemperature", nil, nil, 1, "Temp_Min_bat"}, -- {"PCS", "BMSPackTemp", 1, nil, 1, "BatteryTemp"}, {"PCS", "workMode", 1, nil, 1, "InverterMode"}, {"PCS", "Inverter_Temp", 1, nil, 1, "InverterTemp"}, {"PCS", "device_sn", nil, nil, nil, "PCS_ID"}, {"PCS", "firmware", nil, nil, nil, "PCS_SoftVer"}, {"PCS", "VGrid_R", nil, nil, 1, "GridVoltage_R"}, {"PCS", "VGrid_S", nil, nil, 1, "GridVoltage_S"}, {"PCS", "VGrid_T", nil, nil, 1, "GridVoltage_T"}, {"PCS", "IGrid_R", nil, nil, 1, "GridCurrent_R"}, {"PCS", "IGrid_S", nil, nil, 1, "GridCurrent_S"}, {"PCS", "IGrid_T", nil, nil, 1, "GridCurrent_T"}, {"PCS", "PGrid_R", nil, nil, 1, "GridWattage_R"}, {"PCS", "PGrid_S", nil, nil, 1, "GridWattage_S"}, {"PCS", "PGrid_T", nil, nil, 1, "GridWattage_T"}, {"PCS", "FGrid_R", nil, nil, 1, "GridFrequency_R"}, {"PCS", "FGrid_S", nil, nil, 1, "GridFrequency_S"}, {"PCS", "FGrid_T", nil, nil, 1, "GridFrequency_T"}, {"PCS", "Vpv1", nil, nil, 1, "Ppv1Voltage"}, {"PCS", "Ipv1", nil, nil, 1, "Ppv1Current"}, {"PCS", "Ppv1", nil, nil, 1, "Ppv1Wattage"}, {"PCS", "Vpv2", nil, nil, 1, "Ppv2Voltage"}, {"PCS", "Ipv2", nil, nil, 1, "Ppv2Current"}, {"PCS", "Ppv2", nil, nil, 1, "Ppv2Wattage"}, {"PCS", "Vpv3", nil, nil, 1, "Ppv3Voltage"}, {"PCS", "Ipv3", nil, nil, 1, "Ppv3Current"}, {"PCS", "Ppv3", nil, nil, 1, "Ppv3Wattage"}, {"PCS", "Vpv4", nil, nil, 1, "Ppv4Voltage"}, {"PCS", "Ipv4", nil, nil, 1, "Ppv4Current"}, {"PCS", "Ppv4", nil, nil, 1, "Ppv4Wattage"}, {"PCS", "E_PV_Total", nil, nil, 1000, "TotalAccumulatedSolar"}, {"PCS", "E_Total", nil, nil, 1000, "TotalAccumulativePowerToGrId"}, {"PCS", "E_Total_Buy", nil, nil, 1000, "TotalAccumulativePowerFromGrid"} } local function ifu_calculate(pcs_obj,bms_obj) local cache = read_cache_from_file(IFU_DAT_FILE) if not cache then cache={} cache.ifu={} cache.lastReMainCapacity = 0 cache.date = os.date("*t", os.time()) syslog.syslog("LOG_WARNING","table init") write_cache_to_file(IFU_DAT_FILE,cache) end if not last_cal then last_cal = os.time() end local bms_valid = bms_obj and bms_obj.time and os.difftime(os.time(),bms_obj.time) < DEVICE_OFFLINE_TIME local pcs_valid = pcs_obj and pcs_obj.time and os.difftime(os.time(),pcs_obj.time) < DEVICE_OFFLINE_TIME if not bms_valid then syslog.syslog("LOG_WARNING","Invalid source data," .. string.format("bms sample time %d",bms_obj and bms_obj.time or 0)) end if not pcs_valid then syslog.syslog("LOG_WARNING","Invalid source data," .. string.format("pcs sample time %d",pcs_obj and pcs_obj.time or 0)) end ifu_obj = cache.ifu if PROJECT==PROJECT_10KW then for i,v in pairs(symbol_remap_10KW) do if bms_valid and v and v[1] == "BMS" then if bms_obj[v[2]] and v[6] then print("bms",v[2],bms_obj[v[2]]) if type(bms_obj[v[2]]) == "number" and v[5] then ifu_obj[v[6]] = bms_obj[v[2]] * v[5] else ifu_obj[v[6]] = pcs_obj[v[2]] end else print("bms data not usable",v[2],bms_obj[v[2]]) end elseif pcs_valid and v and v[1] == "PCS" then if pcs_obj[v[2]] and v[6] then print("pcs",v[2],pcs_obj[v[2]]) if type(pcs_obj[v[2]]) == "number" and v[5] then ifu_obj[v[6]] = pcs_obj[v[2]] * v[5] else ifu_obj[v[6]] = pcs_obj[v[2]] end else print("pcs data not usable",v[2],pcs_obj[v[2]]) end end end -- symbol_remap = symbol_remap_10KW if bms_valid and bms_obj.SystemEnableDiscargeEnergy then local interval = os.difftime(os.time(),last_cal) syslog.syslog("LOG_WARNING","calculate interval "..interval or 0) local portion_of_hour = interval/3600 last_cal = os.time() --如果第一次那么不计入统计 if cache.lastReMainCapacity == 0 then cache.lastReMainCapacity = bms_obj.SystemEnableDiscargeEnergy end --每天定时清空daily统计 local date = os.date("*t", os.time()); if date["day"] ~= cache.date["day"] and date["hour"] == 0 then -- 8 地方时区 ifu_obj.DailyCharge = 0 ifu_obj.DailyDischarge = 0 end if bms_obj.Model_SN and ifu_obj.BMS_ID and bms_obj.Model_SN ~= ifu_obj.BMS_ID then -- 查看BMS ID是否变更过 ifu_obj.AccumulatedLifetimeCharge = 0 ifu_obj.AccumulatedLifetimeDischarge = 0 end local diff = bms_obj.SystemEnableDiscargeEnergy - cache.lastReMainCapacity if diff > 0 then ifu_obj.AccumulatedLifetimeCharge = ifu_obj.AccumulatedLifetimeCharge or 0 + diff * portion_of_hour ifu_obj.DailyCharge = ifu_obj.DailyCharge or 0 + diff * portion_of_hour elseif diff < 0 then ifu_obj.AccumulatedLifetimeDischarge = ifu_obj.AccumulatedLifetimeDischarge or 0 - diff * portion_of_hour ifu_obj.DailyDischarge = ifu_obj.DailyDischarge or 0 - diff * portion_of_hour else ifu_obj.AccumulatedLifetimeCharge = ifu_obj.AccumulatedLifetimeCharge or 0 ifu_obj.DailyCharge = ifu_obj.DailyCharge or 0 ifu_obj.AccumulatedLifetimeDischarge = ifu_obj.AccumulatedLifetimeDischarge or 0 ifu_obj.DailyDischarge = ifu_obj.DailyDischarge or 0 end cache.lastReMainCapacity = bms_obj.SystemEnableDiscargeEnergy end if ifu_obj.Vol_Diff_bat and type(ifu_obj.Vol_Diff_bat) == "number" then ifu_obj.AlarmVolDiffOver = 0 if ifu_obj.Vol_Diff_bat > 100 then ifu_obj.AlarmVolDiffOver = 1 elseif ifu_obj.Vol_Diff_bat > 200 then ifu_obj.AlarmVolDiffOver = 2 elseif ifu_obj.Vol_Diff_bat > 200 then ifu_obj.AlarmVolDiffOver = 3 end end elseif PROJECT==PROJECT_3_6KW then for i,v in pairs(symbol_remap_3_6KW) do if bms_valid and v and v[1] == "BMS" then if bms_obj[v[2]] and v[6] then print("bms",v[2],bms_obj[v[2]]) if type(bms_obj[v[2]]) == "number" and v[5] then ifu_obj[v[6]] = bms_obj[v[2]] * v[5] else ifu_obj[v[6]] = pcs_obj[v[2]] end else print("bms data not usable",v[2],bms_obj[v[2]]) end elseif pcs_valid and v and v[1] == "PCS" then if pcs_obj[v[2]] and v[6] then print("pcs",v[2],pcs_obj[v[2]]) if type(pcs_obj[v[2]]) == "number" and v[5] then ifu_obj[v[6]] = pcs_obj[v[2]] * v[5] else ifu_obj[v[6]] = pcs_obj[v[2]] end else print("pcs data not usable",v[2],pcs_obj[v[2]]) end end end if bms_valid and bms_obj.ReMainCapacity then --如果第一次那么不计入统计 if cache.lastReMainCapacity == 0 then cache.lastReMainCapacity = bms_obj.ReMainCapacity end --每天定时清空daily统计 local date = os.date("*t", os.time()); if date["day"] ~= cache.date["day"] and date["hour"] == 0 then -- 8 地方时区 ifu_obj.DailyCharge = 0 ifu_obj.DailyDischarge = 0 end if bms_valid and bms_obj.Model_SN and ifu_obj.BMS_ID and bms_obj.Model_SN ~= ifu_obj.BMS_ID then -- 查看BMS ID是否变更过 ifu_obj.AccumulatedLifetimeCharge = 0 ifu_obj.AccumulatedLifetimeDischarge = 0 end local diff = bms_obj.ReMainCapacity - cache.lastReMainCapacity if diff > 0 then ifu_obj.AccumulatedLifetimeCharge = ifu_obj.AccumulatedLifetimeCharge + diff ifu_obj.DailyCharge = ifu_obj.DailyCharge + diff elseif diff < 0 then ifu_obj.AccumulatedLifetimeDischarge = ifu_obj.AccumulatedLifetimeDischarge - diff ifu_obj.DailyDischarge = ifu_obj.DailyDischarge - diff end cache.lastReMainCapacity = bms_obj.ReMainCapacity end --计算平均温度,最大最小电压 local temp_sum,temp_count,tab = 0,0,{} for i=1, BATT_TEMP_COUNT do local temp = bms_valid and bms_obj["Temperature_" .. i] if not temp then break end temp_sum = temp_sum + temp temp_count = i table.insert(tab,temp) end if temp_count > 0 then ifu_obj.BatteryTemp = temp_sum/BATT_TEMP_COUNT else ifu_obj.BatteryTemp = 0 end if #tab == BATT_TEMP_COUNT then table.sort(tab) ifu_obj.Temp_Max_bat = tab[#tab] ifu_obj.Temp_Min_bat = tab[1] end if bms_valid and bms_obj.VoltageOfPack and bms_obj.Current then ifu_obj.BatteryWattage = bms_obj.VoltageOfPack * bms_obj.Current end --计算电池温度,最高电压,最低电压,压差 local tab = {} for i=1, BATT_VOL_COUNT do local vol = bms_valid and bms_obj["Voltage_Unit_" .. i] if not vol then break end -- tab[string.format( "%d",i)] = vol table.insert(tab,vol) end if #tab == BATT_VOL_COUNT then table.sort(tab) ifu_obj.Vol_Higher_bat = tab[#tab] ifu_obj.Vol_Lower_bat = tab[1] if ifu_obj.Vol_Higher_bat and ifu_obj.Vol_Lower_bat then ifu_obj.Vol_Diff_bat = ifu_obj.Vol_Higher_bat - ifu_obj.Vol_Lower_bat if ifu_obj.Vol_Diff_bat and type(ifu_obj.Vol_Diff_bat) == "number" then ifu_obj.AlarmVolDiffOver = 0 if ifu_obj.Vol_Diff_bat > 100 then ifu_obj.AlarmVolDiffOver = 1 elseif ifu_obj.Vol_Diff_bat > 200 then ifu_obj.AlarmVolDiffOver = 2 elseif ifu_obj.Vol_Diff_bat > 200 then ifu_obj.AlarmVolDiffOver = 3 end end end end -- 找出电池ID for i=1, BATT_VOL_COUNT do local vol = bms_valid and bms_obj["Voltage_Unit_" .. i] if vol and ifu_obj.Vol_Higher_bat and ifu_obj.Vol_Higher_bat == vol then ifu_obj.Vol_Higher_Bat_No = i end if vol and ifu_obj.Vol_Lower_bat and ifu_obj.Vol_Lower_bat == vol then ifu_obj.Vol_Lower_Bat_No = i end end else syslog.syslog("LOG_WARNING","unknow project ") return -1 end cache.ifu = ifu_obj -- write_cache_to_file("/tmp/ifu_"..os.date("%X"),ifu_obj) -- write_cache_to_file("/tmp/pcs_"..os.date("%X"),pcs_obj) -- write_cache_to_file("/tmp/bms_"..os.date("%X"),bms_obj) syslog.syslog("LOG_WARNING","IFU:" .. cjson.encode(ifu_obj)) write_cache_to_file(IFU_DAT_FILE,cache) end function protocol_decode(input_str, len) --出参格式化-- local err_code = -1 local pcs_obj, bms_obj = parser_input(input_str) -- ifu_calculate(pcs_obj,bms_obj) local ret,msg = pcall(ifu_calculate,pcs_obj,bms_obj) if ret then local payload=cjson.encode(ifu_obj) return 0,payload,#payload else syslog.syslog("LOG_WARNING","IFU canlculate failed," .. msg) end return -1 end local json_str = '{\ "datas":[\ {\ "sn":"2",\ "time":1593581386,\ "state":211,\ "quality":240,\ "identifier":"post",\ "tags":{\ "SystemTotalVoltage": 749,\ "SystemTotalCurrent": -240,\ "SystemSoc": 7.5,\ "SystemSoh": 100,\ "SystemInsulation": 2000,\ "SystemEnableChargeEnergy": 5,\ "SystemEnableDiscargeEnergy": 15,\ "SystemMaxChargeCurrent": 60,\ "SystemMaxDischargeCurrent": 60,\ "RackCurrentDifference": 0,\ "RackVoltageDifference": 0,\ "SystemMaxVolCellRackID": 1,\ "SystemMaxVolCellSlaveID": 15,\ "SystemMaxVolCellID": 16,\ "SystemMaxCellVoltage": 3240,\ "SystemMinVolCellRackID": 1,\ "SystemMinVolCellSlaveID": 1,\ "SystemMinVolCellID": 1,\ "SystemMinCellVoltage": 3001,\ "Systemaveragevoltage": 3120,\ "SystemMaxTempCellRackID": 1,\ "SystemMaxTempCellSlaveID": 7,\ "SystemMaxTempCellID": 4,\ "SystemMaxCellTemperature": 29.9,\ "SystemMinTempCellRackID": 1,\ "SystemMinTempCellSlaveID": 1,\ "SystemMinTempCellID": 1,\ "SystemMinCellTemperature": 20,\ "Systemaveragetemperature": 24.5,\ "dev_type":"BMS"\ }\ },\ {\ "sn":"1",\ "time":1593581262,\ "state":0,\ "quality":0,\ "identifier":"post",\ "tags":{\ "DSPVer": "04029-03-S10",\ "ARMVer": "02041-11-S00",\ "device_sn": "9010KETL207W0001",\ "dev_type": "PCS",\ "Vpv1": 0,\ "Ipv1": 0,\ "Ppv1": 0,\ "Vpv2": 0,\ "Ipv2": 0,\ "Ppv2": 0,\ "Vpv3": 0,\ "Ipv3": 0,\ "Ppv3": 0,\ "Vpv4": 0,\ "Ipv4": 0,\ "Ppv4": 0,\ "PVMode": 3428843520,\ "VGrid_R": 4.9,\ "IGrid_R": 0,\ "FGrid_R": 0.65,\ "PGrid_R": 16,\ "VGrid_S": 152.4,\ "IGrid_S": 26,\ "FGrid_S": 5.12,\ "PGrid_S": -1179.4,\ "VGrid_T": 2766.7,\ "IGrid_T": 0,\ "FGrid_T": 0.66,\ "PGrid_T": 2977.5,\ "GridMode": 26214,\ "Total_Power": 28261,\ "ACActivePower": 17237,\ "ACReactivePower": 25970,\ "ACApparentPower": 2318,\ "Back_Up_Vload_R": 52,\ "Back_Up_Iload_R": 0,\ "Back_Up_Fload_R": 1.05,\ "LoadMode_R": 26214,\ "Back_Up_Pload_R": 25966,\ "Back_Up_Vload_S": 2544.5,\ "Back_Up_Iload_S": 0,\ "Back_Up_Fload_S": 302.73,\ "LoadMode_S": 0,\ "Back_Up_Pload_S": 0,\ "Back_Up_Vload_T": 0.1,\ "Back_Up_Iload_T": 0,\ "Back_Up_Fload_T": 1.72,\ "LoadMode_T": 46034,\ "Back_Up_Pload_T": 0,\ "PLoad_R": -1630,\ "PLoad_S": 0,\ "Pload_T": 29551,\ "BackupLoad_Pow": 14389,\ "TotalLoadPower": 12895,\ "UpsLoadPercent": 12601,\ "Inverter_Temp": 1439.1,\ "Module_Temp": 6.4,\ "Radiator_Temp": 5583.3,\ "FunctionBitValue": 561,\ "BUSVoltage": 0,\ "NBUSVoltage": 4.9,\ "Vbattery1": 0,\ "Ibattery1": 1.6,\ "BatteryPower": 4,\ "BattaryMode": 256,\ "InverterWarning": 30405,\ "SafetyCountry": 13241,\ "workMode": 15633,\ "OperationMode": 0,\ "ErrorMessage": 5071209,\ "E_PV_Total": 184991447.6,\ "PV_E_Day": 183600824.4,\ "E_Total": 183332901.3,\ "h_Total": 1819541603,\ "E_Day": 2746.5,\ "E_Total_Buy": 1140850737,\ "E_Day_Buy": 0,\ "E_Total_Load": 321126.4,\ "E_Load_Day": 0.1,\ "E_BatteryCharge": 17.2,\ "E_BatCharge_Today": 4603.4,\ "E_BatteryDischarge": 198036684.8,\ "E_BatDischarge_Today": 23.6\ }\ }\ ]\ }' -- protocol_decode(json_str, 0) syslog.closelog()