--============================= Z-Range test v1.0 =============================== lgF="";gF="";yF="";ygF="";cF="";bF="";snHC=api.get("/settings/info/")["serialNumber"] wF="";rF="";irF="";eF="";jDlist={["numDev"]=0,["phDev"]=0,["idColor1"]=lgF,["roomName1"]=api.get("/settings/info/")["hcName"],["pName1"]=snHC}jP={}jMesh={} order={irF,"","","","","",lgF};sn=0;dateRange={min=os.time(),max=0,range} nStat={["ok"]=lgF.."ok"..eF,["error"]=irF.."error"..eF,["in progress"]=cF.."in progress"..eF,["pending"]=yF.."pending"..eF};endStr={"
","","",""} tHeader={" # ","Parent ID:Description","Last Route","iRoute","iSee","Status","Time Stamp"};dNum={0,0,0};dMaxLen=0;iSeeTotal=0;iSeeMax=0;iSeeMax1=0;iSeeHC=0;meshFactor=.5 zBuf={}zBuf[1]="" function getRoom(roomId) return roomId==0 and "Unassigned" or api.get("/rooms/"..roomId)["name"] end for i,j in pairs(api.get("/devices/")) do if j.id==1 or not j.properties.nodeId then goto nextId end if not debug then api.delete("/scenes/" .. __fibaroSceneId .. "/debugMessages") end;print(ygF.."Retrieving working routes and neighbor lists for "..eF..wF..j.id..":"..j.name.."
") if not jDlist[j.parentId] then jDlist[j.parentId]=" "..bF..j.properties.zwaveCompany.." v"..j.properties.zwaveVersion..eF.."

" end if j.parentId>1 then jDlist["numDev"]=jDlist["numDev"]+1;jDlist[j.parentId]=jDlist[j.parentId]..string.format("%4d",j.id)..":"..j.name.."
" elseif j.parentId==1 and j.properties.lastWorkingRoute then jP[#jP+1]=j.id;mStr=json.encode(j.properties.lastWorkingRoute):gsub("[%[%]]","") if #mStr==1 then jDlist["idColor"..j.id]=lgF;mStr="";dNum[1]=dNum[1]+1 elseif #mStr==0 then jDlist["idColor"..j.id]=irF;mStr="";dNum[3]=dNum[3]+1 elseif #mStr >1 then mStr=","..mStr:sub(3)..",";_,tmpNum=mStr:gsub(",","");jDlist["idColor"..j.id]=string.format("",255-math.min(4,tmpNum-2)*30);dNum[2]=dNum[2]+1 end jDlist["iCtable"..j.id]=j.properties.neighborList;jDlist["pRoute"..j.id]=mStr;jDlist["pName"..j.id]=j.name;jDlist["pRoom"..j.id]=j.roomID;jDlist["roomName"..j.id]=getRoom(j.roomID);jDlist["phDev"]=jDlist["phDev"]+1;dMaxLen=math.max(dMaxLen,#j.name + #jDlist["roomName"..j.id]+10) jDlist["nList"..j.id]=j.properties.neighborListRequestStatus:gsub(".+",function (a) if nStat[a:lower()] then return nStat[a:lower()] else return a end end) if j.properties.lastWorkingRouteResponseTimestamp > 0 then dateRange.min=math.min(dateRange.min,j.properties.lastWorkingRouteResponseTimestamp);dateRange.max=math.max(dateRange.min,j.properties.lastWorkingRouteResponseTimestamp) end jDlist["nDate"..j.id]=jDlist["idColor"..j.id]..os.date("%b/%d/%y %X",j.properties.lastWorkingRouteResponseTimestamp):gsub(".+",function (a) if a:find("01/70") then return "out of date" else return a end end)..eF; jDlist["iSee"..j.id]=#j.properties.neighborList;iSeeMax=math.max(iSeeMax,jDlist["iSee"..j.id]);if j.properties.neighborList[1]==1 then iSeeHC=iSeeHC+1;jDlist["iSee"..j.id]=jDlist["iSee"..j.id]-1 else iSeeMax1=math.max(iSeeMax1,jDlist["iSee"..j.id]) end end ::nextId:: end dateRange.range="12Devices: masters="..jDlist["phDev"].." slaves="..jDlist["numDev"].."123Date range: "..os.date("%d %b %Y - ",dateRange.min)..os.date("%d %b %Y",dateRange.Max) for _,j in ipairs(jP) do iSeeTotal=iSeeTotal+math.floor(math.min(jDlist["iSee"..j], jDlist["phDev"]*meshFactor));jDlist["iCdev"..j]="";jDlist["mStyle"..j]="";sMod=math.min(4,math.ceil(#jDlist["iCtable"..j]/10)) if sMod>1 then jDlist["mStyle"..j]="style='position:fixed;top:auto;bottom:10px;right:40px;'>" end for i=1,#jDlist["iCtable"..j] do inId=jDlist["iCtable"..j][i];jDlist["iCdev"..j]=jDlist["iCdev"..j]..jDlist["idColor"..inId]..string.format("%-"..dMaxLen.."s",inId..":"..jDlist["pName"..inId]..":"..jDlist["roomName"..inId])..endStr[(i % sMod)+1]..eF end end zBuf[#zBuf+1]="" ..api.get("/settings/info/")["hcName"]..""..snHC.." efficiency: " specLocAll=irF..math.min(100,math.ceil(iSeeTotal/(jDlist["phDev"]*jDlist["phDev"])*100)).."%"; specLoc=""..math.min(100,math.ceil(iSeeTotal/((jDlist["phDev"]-dNum[3])*(jDlist["phDev"]-dNum[3]))*100)).."%" if dNum[3]>0 then zBuf[#zBuf+1]=wF.."HC location "..irF..math.min(100,math.ceil(iSeeHC/jDlist["phDev"]*100))..eF.."%/"..lgF..math.min(100,math.ceil(iSeeHC/(dNum[1]+dNum[2])*100))..eF.."% Devices location ".. irF..math.min(100,math.ceil(iSeeTotal/(jDlist["phDev"]*jDlist["phDev"]*meshFactor)*100))..eF.."%/"..lgF..math.min(100,math.ceil(iSeeTotal/((jDlist["phDev"]-dNum[3])*(jDlist["phDev"]-dNum[3])*meshFactor)*100))..eF.."%
Full mesh setup %

"..specLocAll.." / "..specLoc.."
" else zBuf[#zBuf+1]=wF.."HC location "..math.min(100,math.ceil(iSeeHC/jDlist["phDev"]*100)).."% Devices location "..math.min(100,math.ceil(iSeeTotal/(jDlist["phDev"]*jDlist["phDev"]*meshFactor)*100)).."%
Full mesh setup %

"..specLocAll.."
" end for i=1,#tHeader do zBuf[#zBuf+1]="" end;jMesh["iRouteMax"]=0 for _,j in ipairs(jP) do iSeeTotal=iSeeTotal+math.min(jDlist["iSee"..j], jDlist["phDev"]*meshFactor); if not jMesh["iRoute"..j] then jMesh["iRoute"..j]="";jMesh[j]=0 end for i=1,#jP do if jDlist["pRoute"..jP[i]]:find(","..j..",") then jMesh[j]=jMesh[j]+1;jMesh["iRouteMax"]=math.max(jMesh["iRouteMax"],jMesh[j]);jMesh["iRoute"..j]=jMesh["iRoute"..j]..jDlist["idColor"..jP[i]]..string.format("%4s",jP[i])..":"..jDlist["pName"..jP[i]]..":"..jDlist["roomName"..jP[i]]..eF.."
"; end end end for j=1,#order do for i=1,#jP do if jDlist["idColor"..jP[i]]==order[j] then sn=sn+1;zBuf[#zBuf+1]="" zBuf[#zBuf+1]="" if not jDlist["pRoute"..jP[i]]:find(",") then zBuf[#zBuf+1]="" else zBuf[#zBuf+1]="" end tmpNum=math.max(0,255-(math.floor(150/jMesh["iRouteMax"]*jMesh[jP[i]]))); if jMesh[jP[i]]>0 then zBuf[#zBuf+1]="" else zBuf[#zBuf+1]="" end tmpNum=math.max(0,255-(math.floor(255/jDlist["phDev"]*jDlist["iSee"..jP[i]])));tmpStr=string.format("",tmpNum,tmpNum) if jDlist["iSee"..jP[i]]>0 then if not jDlist["iCdev"..jP[i]]:find("1:HC") then tmpNum=math.max(0,(math.floor(200/iSeeMax1*jDlist["iSee"..jP[i]])));tmpStr=string.format("",tmpNum,tmpNum) end zBuf[#zBuf+1]="" else zBuf[#zBuf+1]="" end zBuf[#zBuf+1]="";zBuf[#zBuf+1]="" end end end if not debug then api.delete("/scenes/" .. __fibaroSceneId .. "/debugMessages") end print("ZRangev1.0"..dateRange.range.."
"..table.concat(zBuf).."
"..tHeader[i].."
"..wF..sn..eF..""..jDlist["nList"..jP[i]]..""..jDlist["nDate"..jP[i]].."


Color index:
"..irF.." "..dNum[3].." Device(s) unknown working route."..eF.."
".. " "..yF..dNum[2]..eF.." device(s) in shades from orange "..eF.."to yellow "..eF.."in descending order of nodes number in route.
"..eF..lgF.." "..dNum[1].." Device(s) in direct route to controller."..eF.."

")