Hallo,
vielleicht kann das noch jemand gebrauchen.
Ich habe mir ein Skript geschrieben, das
a) für jede Geräte/Gateway Kombination die RSSI Werte ausliest und die Werte als Objekt ablegt
b) für jedes Gateway die Anzahl der verbundenen Geräte zählt (wichtig wg. Duty Cycle)
c) für jedes Gerät zählt, wie oft der Zustand "unreach" gesetzt wird. Bei Änderung des Gateways wird der Zähler auf 0 zurückgesetzt
d) mittels der angelegten Objekte "Gateway" / "Roaming" die Einstellungen auf der CCU ändert
e) mir eine CSS Tabelle mit allen Werten erzeugt und ich daraus die Einstellung des Gateways und Romaing ändern kann
Benutzung:
a) "objectFolder" definieren (hier werden die Werte abgelegt)
b) "HM_RPC" definieren (für diese HM-RPC Instanz arbeitet das Script)
c) "SQL_Logging" auf true/false setzen - bei "true" wird auch direkt die Aufnahme für alle Geräte/Gateway Kombis gesetzt (was wiederum zu Folge hat, dass man ggf. "max_connections" in seiner MySQL Datenbank erhöhen muss)
d) in gatewayNames ggf. die Namen/Orte der Gateways aufführen - diese Info konnte ich nicht aus der CCU holen
e) in "objectFolder".CSS liegt die CSS formatierte Tabelle. Die Werte des derzeitigen Gateways sind farbig hinterlegt (grün bis rot). Kann in VIS in einem "Basic string [unescaped]" angezeigt werden.
f) CCU: XML-API muss installiert sein
g) javascript Instanz:setObject muss aktiviert sein
Ist noch nicht ganz perfekt (ein paar Log Ausgaben muss ich noch nachgehen).
Getestet mit
- 1xCCU + 5*LAN Config Adapter
- 1xCCU + 1xLAN Gateway
Am liebsten wäre mir, wenn man sowas als Teil des HMI-RPC Adapters integrieren könnte. Dann könnte auch gleich jemand mein "software-rumgebastel" richtig umsetzen
Gruß
Georg
letzte Aktualisierung: 23.08.2020 17:50
// V1-14
var objectFolder = '0_userdata.0.RSSI';
var HM_RPC = 'hm-rpc.0';
var SQL_Logging = false;
schedule("*/15 * * * *", function () {getCCUData(false,false);});
var gatewayNames = [
{ ID: 'GEQ0208425', name: 'Dach' },
{ ID: 'GEQ0208299', name: 'Hobbyraum' },
{ ID: 'LEQ0049884', name: 'Wohnzimmer' },
{ ID: 'KEQ1023440', name: 'Garten' },
{ ID: 'LEQ0986282', name: 'Keller' },
{ ID: 'IEQ0062040', name: "TH" }
];
const CSS_TableHeight = "34em";
const CSS_ColumnWidth_Name = "17em";
const CSS_ColumnWidth_Data = "3em";
const CSS_ColumnWidth_ID = "7em";
//
// script starts here
//
const devicePath = objectFolder +".Devices.";
const gatewayPath = objectFolder +".Gateways.";
const CSSId = objectFolder + ".CSS";
const CSSUpdateId = objectFolder + ".CSSUpdate";
const CSSResetId = objectFolder + ".CSSReset";
const CSSAutoUpdateId = objectFolder + ".CSSAutoUpdate";
const CCSGatewayColumns = 4;
var updateRequest = [];
var CCU_Gateways = [];
var CCU_Gateways_Name = [];
var CCU_Gateways_DutyCycle = [];
var CCU_Gateways_Counter = [];
var loggingObjects = [];
var rssiObjects = [];
var UNREACH = $('channel[state.id=*.UNREACH]');
UNREACH.on(function(obj) {increaseUnreachableCounter(obj);});
on(CSSUpdateId,function(obj){if(getState(obj.id).val) {log("Update Request");getCCUData(false,true);}});
on(CSSResetId,function(obj){if(getState(obj.id).val) {log("Reset Request");resetUnreachableCounters();}});
var newObjectCounter = 0;
var createEntriesForEachGateway = false;
var CSS_AutoUpdate = false; // if false, the CSS table is only updated when using the update button after changing the setup
// functions
getCCUData(true,false);
var functionLock_getCCUData = false;
function getCCUData(firstCall,manuallUpdate)
{
if(functionLock_getCCUData) return;
functionLock_getCCUData = true;
init();
sendTo(HM_RPC, 'listBidcosInterfaces', {}, res =>
{
var gatewayList = JSON.stringify(res.result);
analyseGatewayList(gatewayList);
sendTo(HM_RPC, 'listDevices', {}, res =>
{
var deviceList = JSON.stringify(res.result);
analyseDeviceList(deviceList);
sendTo(HM_RPC, 'rssiInfo', {}, res =>
{
var rssiList = JSON.stringify(res.result);
analyseRSSIList(rssiList);
saveGatewayCounters();
deleteOldDevices();
extendObjects();
functionLock_getCCUData = false;
if(firstCall)
{
initCallbacks();
setTimeout(function(){createCSS();},newObjectCounter*10+2000); // the system might need more time to create all objects after first call
}
else
if (CSS_AutoUpdate||manuallUpdate) setTimeout(function(){createCSS();},newObjectCounter*2+1000); // usually there are no or little changes after first call
firstCall = false;
if (updateRequest.length > 0)
{
var id = updateRequest.pop();
log ("UNQUEUE - " + updateRequest.length + " - " + id);
setTimeout(function(){changeGateway(id);},500);
}
setRSSIState(CSSUpdateId,"",false,'boolean');
log ("Done")
});
});
});
}
function analyseGatewayList(gatewayList)
{
var gatewayData = JSON.parse(gatewayList);
gatewayData.forEach( gd =>{addGateway(gd.ADDRESS,gd.DUTY_CYCLE);});
}
function analyseDeviceList(deviceList)
{
var deviceData = JSON.parse(deviceList);
deviceData.forEach (dd =>
{
var deviceID = dd.ADDRESS;
if ( deviceID.indexOf("BidCoS-RF")<0
&& deviceID.indexOf("*")<0
&& deviceID.indexOf(":")<0
&& !CCU_Gateways.includes(deviceID)
&& dd.ROAMING != isNaN
)
{
if (!rssiObjects.includes(deviceID))
{
var o= getObject(HM_RPC + "." + deviceID);
if (o)
{
var deviceName = o.common.name;
var gateway = dd.INTERFACE;
var roaming = dd.ROAMING;
addDevice(deviceID,deviceName,gateway,roaming);
increaseGatewayCounter(gateway);
}
}
else
{
removeDeviceFromList(getGatewayId(deviceID));
removeDeviceFromList(getUnreachableCounterId(deviceID));
removeDeviceFromList(getRoamingId(deviceID));
removeDeviceFromList(getNameId(deviceID));
increaseGatewayCounter(getState(getGatewayId(deviceID)).val);
}
}
});
}
function analyseRSSIList(rssiList)
{
var rp= JSON.parse(rssiList);
for (const rssiID in rp)
{
if ( rssiID.indexOf("BidCoS-RF")<0
&& !CCU_Gateways.includes(rssiID)
&& isState(getNameId(rssiID))
)
{
analyseRSSIData(rp[rssiID],rssiID);
}
}
}
function analyseRSSIData(rssiData,rssiID)
{
var deviceName = getObject(getNameId(rssiID));
var deviceGatewayID = getState(getGatewayId(rssiID)).val;
for ( const gateway in rssiData )
{
if (CCU_Gateways.includes(gateway))
{
var rssi1 = writeDeviceRSSI(rssiData[gateway], rssiID, deviceName, gateway, 1);
var rssi2 = writeDeviceRSSI(rssiData[gateway], rssiID, deviceName, gateway, 2);
if (gateway == deviceGatewayID)
{
if ( createEntriesForEachGateway )
{
writeGatewayRSSI(rssiID, deviceName, gateway, rssi1, 1);
writeGatewayRSSI(rssiID, deviceName, gateway, rssi2, 2);
}
}
}
}
}
function addGateway(gatewayID,dc)
{
var name = "";
gatewayNames.forEach((gateway,i) => {if(gateway.ID.indexOf(gatewayID)>-1) name=gateway.name;});
CCU_Gateways.push(gatewayID);
CCU_Gateways_DutyCycle.push(parseInt(dc));
setRSSIState(getGatewayDutyCycleId(gatewayID),parseInt(dc),getGatewayDutyCycleName(gatewayID),'number');
CCU_Gateways_Name.push(name);
CCU_Gateways_Counter.push(0);
}
function addDevice(deviceID,deviceName,gatewayID,roaming)
{
var unr=0;
if (isState(getUnreachableCounterId(deviceID))) unr = getState(getUnreachableCounterId(deviceID)).val;
setRSSIState(getGatewayId(deviceID),gatewayID,getGatewayName(deviceName),'string');
setRSSIState(getUnreachableCounterId(deviceID),unr,getUnreachableCounterName(deviceName),'number');
setRSSIState(getRoamingId(deviceID),roaming,getRoamingName(deviceName),'number');
setRSSIState(getNameId(deviceID),deviceName,getNameName(deviceName),'string');
}
function init()
{
CCU_Gateways.length = 0;
CCU_Gateways_Name.length = 0;
CCU_Gateways_Counter.length=0;
CCU_Gateways_DutyCycle.length=0;
loggingObjects.length = 0;
rssiObjects.length=0;
newObjectCounter = 0;
if (!isState(CSSAutoUpdateId)) setRSSIState(CSSAutoUpdateId,CSS_AutoUpdate,"",'boolean')
if (!isState(CSSResetId)) setRSSIState(CSSResetId,false,"",'boolean')
else
{
CSS_AutoUpdate = false;
var au = getState(CSSAutoUpdateId).val.toString();
log (au);
if (au=="true") CSS_AutoUpdate = true;
log("Auto Update: " + CSS_AutoUpdate);
}
readRSSIObjects();
}
function initCallbacks()
{
var roaming = $('[id=' + getRoamingId("*") + ']');
roaming.on(function(obj){changeGateway(obj);});
var gateway = $('[id=' + getGatewayId("*") + ']');
gateway.on(function(obj){changeGateway(obj);});
on(CSSAutoUpdateId,function(obj)
{
CSS_AutoUpdate = false;
if ( obj.state.val == "true") CSS_AutoUpdate = true;
log("Auto Update: " + CSS_AutoUpdate);
});
}
function writeDeviceRSSI(rssiData, deviceID, deviceName, gateway, i)
{
var rssi = rssiData[i-1];
var rssiId = getDeviceRssiId(deviceID,gateway,i);
var rssiName = getDeviceRssiName(deviceName,gateway,i);
setRSSIState(rssiId,rssi,rssiName,'number');
return rssi;
}
function writeGatewayRSSI(deviceID, deviceName, gateway, rssi, i)
{
var rssiId = getGatewayRssiId(gateway,deviceID,i);
var rssiName = getGatewayRssiName(gateway,deviceName,i);
setRSSIState(rssiId,rssi,rssiName,'number');
}
function setRSSIState(id,value,name,typeString)
{
var newState = false;
if (removeDeviceFromList(id))
{
var oldValue = getState(id).val.toString();
if (oldValue != value) newState=true;
setState(id,value);
}
else
{
createState(id, value, true, {name: name ,type: typeString});
newObjectCounter++;
// store objects which should be enabled for logging
if ( id.indexOf(devicePath)>-1
&& id.indexOf(".Roaming")<0
&& id.indexOf(".Gateway")<0
&& id.indexOf(".Name")<0
) loggingObjects.push(id);
newState = true;
}
return newState;
}
function removeDeviceFromList(id)
{
var removed = false;
var index = rssiObjects.indexOf(id);
if ( index > -1 )
{
rssiObjects.splice(index,1);
removed = true;
}
return removed;
}
function increaseGatewayCounter(gateway)
{
var index = CCU_Gateways.indexOf(gateway);
if(index > -1)
{
var cnt = CCU_Gateways_Counter[index] + 1;
CCU_Gateways_Counter.splice(index,1,cnt);
}
else
log("not a gateway: -" + gateway + "-", "error");
}
function saveGatewayCounters()
{
CCU_Gateways.forEach((gateway,i) =>
{
var cnt = CCU_Gateways_Counter[i];
setRSSIState(getGatewayCounterId(gateway),cnt,gateway+"_DEVICE_COUNTER",'number');
});
}
function deleteOldDevices()
{
removeDeviceFromList(CSSId);
removeDeviceFromList(CSSUpdateId);
removeDeviceFromList(CSSResetId);
removeDeviceFromList(CSSAutoUpdateId);
rssiObjects.forEach(id => {log("delete: " + id); deleteState(id);});
}
function readRSSIObjects()
{
var ids = $('[id=' + objectFolder + '.*]');
ids.each(id => {rssiObjects.push(id);});
}
function extendObjects()
{
loggingObjects.forEach(id => {extendObject(id, {common: {custom: {'sql.0': {enabled: SQL_Logging}}}}) });;
}
function changeGateway(obj)
{
changeGW (obj.id);
}
function changeGW (id)
{
if (functionLock_getCCUData)
{
updateRequest.push(id);
return;
}
log(id);
var updateRoaming = id.indexOf("Roaming")>-1 ? true:false;
var deviceID = readDeviceID(id,devicePath);
var gateway = getState(getGatewayId(deviceID)).val;
if ( CCU_Gateways.includes(gateway))
{
var roaming = parseInt(getState(getRoamingId(deviceID)).val) == 1 ? true: false;
sendTo('hm-rpc.0', 'setBidcosInterface', {ID: deviceID, paramType: gateway,params: roaming}, res =>
{
if (updateRoaming)
{
log ("ROAMING CHANGED - Device:" + deviceID + ": new Roaming Status: " + roaming + " " + JSON.stringify(res));
}
else
{
log ("GATEWAY CHANGED - Device:" + deviceID + ": new Gateway: " + gateway + " " + JSON.stringify(res));
// if (CSS_AutoUpdate) setTimeout(function(){getCCUData(false)},500);
setState(getUnreachableCounterId(deviceID),0);
}
});
}
else
log(gateway + " is not a valid gateway","error");
}
var functionLock_createCSS = false;
function createCSS()
{
if (functionLock_createCSS) return;
functionLock_createCSS = true;
var css = '';
css += '<!DOCTYPE html>';
css += '<html>';
css += '<head>';
css += '<style>';
css += 'table {border-collapse: collapse;table-layout: fixed } ';
css += 'table, th, td {border: 1px solid grey;} ';
css += 'thead { display: block;}';
css += 'tbody { display: block; overflow: auto; height:'+CSS_TableHeight+'}';
css += 'td:nth-child(1),th:nth-child(1) {width: '+CSS_ColumnWidth_Name+'}';
for (var i=0;i<CCU_Gateways.length;i++)
{
css += 'td:nth-child('+(2+i*CCSGatewayColumns)+'),th:nth-child('+(2+i*CCSGatewayColumns)+') {width: '+CSS_ColumnWidth_Data+'}';
css += 'td:nth-child('+(3+i*CCSGatewayColumns)+'),th:nth-child('+(3+i*CCSGatewayColumns)+') {width: '+CSS_ColumnWidth_Data+'}';
css += 'td:nth-child('+(4+i*CCSGatewayColumns)+'),th:nth-child('+(4+i*CCSGatewayColumns)+') {width: '+CSS_ColumnWidth_Data+'}';
css += 'td:nth-child('+(5+i*CCSGatewayColumns)+'),th:nth-child('+(5+i*CCSGatewayColumns)+') {width: '+CSS_ColumnWidth_Data+'}';
}
css += 'td:nth-child('+(6+(i-1)*CCSGatewayColumns)+'),th:nth-child('+(6+(i-1)*CCSGatewayColumns)+') {width: '+CSS_ColumnWidth_Data+'}';
css += 'td:nth-child('+(7+(i-1)*CCSGatewayColumns)+'),th:nth-child('+(7+(i-1)*CCSGatewayColumns)+') {width: '+CSS_ColumnWidth_ID+'}';
css += 'th:nth-child('+(8+(i-1)*CCSGatewayColumns)+') {width: 1em}';
css += '</style>';
css += createJavascripts();
css += '</head>';
css += '<body>';
css += '<table>';
css += createCSSHeader();
css += createCSSRows();
css += '</table>';
css += '</body>';
css += '</html>';
setRSSIState(CSSId,css,"",'string');
functionLock_createCSS = false;
}
function createJavascripts()
{
var css = '';
css += '<script>';
css += createInit();
css += createEventUpdateButton();
css += createEventResetButton();
css += createEventAutoUpdateCB();
css += createEventRadioButton();
css += createEventCheckBox();
css += '</script>';
return css;
}
function createCSSHeader()
{
var css = '<thead>';
css += '<tr>';
css += createUpdateButton();
css += createResetButton();
css += createAutoUpdateCB();
CCU_Gateways.forEach((gateway,i) =>
{
var name = "";
if (i<CCU_Gateways_Name.length) name = CCU_Gateways_Name[i];
css += '<th scope="colgroup" colspan="4">' + gateway + '<br>' + name + '</th>';
});
css += '<th scope="col">R</th>';
css += '<th scope="col">ID</th>';
css += '<th scope="col"></th>';
css += '</tr>';
css += '<tr>';
css += '<th scope="col" style="text-align:center">Last Update</th>';
var deviceCnt = 0;
CCU_Gateways.forEach((gateway,i) =>
{
css += '<th scope="col" style="text-align:center">#</th>';
css += '<th scope="col" style="text-align:center">DC</th>';
css += '<th scope="col" style="text-align:center"></th>';
css += '<th scope="col" style="text-align:center">UNR</th>';
});
css += '<th scope="col" style="text-align:center"></th>';
css += '<th scope="col" style="text-align:center">#</th>';
css += "</tr>";
css += '<tr>';
css += '<th scope="col" style="text-align:center">' + createDateTime() + '</th>';
var deviceCnt = 0;
CCU_Gateways.forEach((gateway,i) =>
{
var dutyCycles = CCU_Gateways_DutyCycle[i];
var cnt = CCU_Gateways_Counter[i];
var unr = getSumOfUnreachableCounter(gateway);
css += '<th scope="col" style="text-align:center">' + cnt + '</th>';
css += '<th scope="col" style="text-align:center">' + dutyCycles + '</th>';
css += '<th scope="col" style="text-align:center"></th>';
css += '<th scope="col" style="text-align:center">' + unr + '</th>';
deviceCnt+=cnt;
});
css += '<th scope="col" style="text-align:center"></th>';
css += '<th scope="col" style="text-align:center">'+deviceCnt+'</th>';
css += "</tr>";
css += "</thead>";
return css;
}
function getSumOfUnreachableCounter(gateway)
{
var unr = 0;
var ids = $('[id=' + getGatewayId("*") + ']');
ids.each(id =>
{
var deviceId = readDeviceID(id,devicePath);
if (getState(id).val.indexOf(gateway)>-1)
unr += getState(getUnreachableCounterId(deviceId)).val;
});
return unr;
}
function createDateTime()
{
var dt = new Date();
var sDay = fDate(dt.getDate().toString());
var sMonth = fDate((dt.getMonth()+1).toString());
var sHours = fDate(dt.getHours().toString());
var sMinutes = fDate(dt.getMinutes().toString());
var sSeconds = fDate(dt.getSeconds().toString());
return sDay + "." + sMonth + "." + dt.getFullYear() + " " + sHours +":" +sMinutes + ":" + sSeconds;
}
function createCSSRows()
{
var objList = [];
var ids = $('[id='+ getNameId("*")+']');
ids.each(id => {objList.push(getState(id).val);})
objList.sort();
var css = "<tbody>";
objList.forEach(name =>
{
css += "<tr>";
// var name = objList[i];
var id = getIdByName(name).toString();
var pos = HM_RPC.length+1;
id = id.substring(pos,pos+10);
css += '<td scope="col" style="text-align:left;font-weight:bold">'+ name +'</td>';
var deviceGateway = getState(getGatewayId(id)).val;
for (var ii=0;ii<CCU_Gateways.length;ii++)
css += createCSSRSSIRows(ii,deviceGateway,id);
css += createRoamingCheckbox(id);
css += '<td scope="col" style="text-align:center">'+ id +'</td>';
css += "</tr>";
});
css += "</tbody>";
return css;
}
function createCSSRSSIRows(ii,deviceGateway,id)
{
var css = "";
var gateway = CCU_Gateways[ii];
var ownGateway = gateway.indexOf(deviceGateway)>-1;
css += createGatewayRadioButton(id,gateway,ownGateway);
for (var iii=1; iii<3; iii++)
{
var rssiId = getDeviceRssiId(id,gateway,iii);
var rssi = 0;
if (isState(rssiId,true)) rssi = parseInt(getState(rssiId).val);
if (rssi<0)
{
if (ownGateway)
{
var color = "#FFFFFF";
color = createRSSIColour(rssi);
css += '<td scope="col" style="text-align:center;color:black;background-color:' + color + '">' + rssi.toString() + '</td>';
}
else
css += '<td scope="col" style="text-align:center">' + rssi.toString() + '</td>';
}
else
css += '<td scope="col"></td>';
}
var unreachable = parseInt(getState(getUnreachableCounterId(id)).val);
var unr = (unreachable > 0) && ownGateway ? unreachable.toString() : ""
css += '<td scope="col" style="text-align:center">'+ unr +'</td>';
return css;
}
function createInit()
{
var css = ""
// css += 'window.addEventListener("DOMContentLoaded",init);';
// css += 'window.onload = function load () {console.log("#############################################");init();};'
css += 'function init(e) ';
css += '{';
css += 'console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>A");'
// css += 'document.getElementById("cbAutoUpdate").checked = true;';
// css += 'servConn.getStates("'+ CSSAutoUpdateId = + '", (error, states) =>';
// css += '{';
// css += 'console.log(CSS_AutoUpdate);'
// css += '});';
css += 'console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>B");'
css += '}';
return css;
}
function createUpdateButton()
{
var css = ""
css += '<th scope="col" >';
css += '<input type = "button" name="update" value="Update" onclick="updateButton()">';
return css;
}
function createResetButton()
{
var css = ""
css += '<input type = "button" name="reset" value="Reset" onclick="resetButton()">';
return css;
}
function createEventUpdateButton()
{
var css = '';
css += 'function updateButton() {servConn.setState("' + CSSUpdateId + '", "true");}';
return css;
}
function createEventResetButton()
{
var css = '';
css += 'function resetButton() {servConn.setState("' + CSSResetId + '", "true");}';
return css;
}
function createAutoUpdateCB()
{
var css = "";
var autoUpdate = "";
if(CSS_AutoUpdate) autoUpdate = "checked";
// css += '<input type="checkbox" id="cbAutoUpdate" name="cbAutoUpdate" onchange="autoUpdate(this.checked)"'+ autoUpdate + '>';
// css += '<label for="cbAutoUpdate">Auto Update</label>';
css += '</th>';
return css;
}
function createEventAutoUpdateCB()
{
var css = '';
css += 'function autoUpdate(checked)';
css += '{';
css += 'servConn.setState("' + CSSAutoUpdateId + '", checked ? "true" : "false");';
css += '}';
return css;
}
function createGatewayRadioButton(id,gateway,ownGateway)
{
var css="";
var rbID = "rb" + id;
var checked = ownGateway ? "checked" : "";
css += '<td scope="col" style="text-align:center">';
css += '<input type="radio" id="'+rbID+'" name="'+id+'" onchange="radioButton(\'' + getGatewayId(id) + '\',\'' + gateway + '\')" '+ checked + '>';
css += '</td>';
return css;
}
function createEventRadioButton()
{
var css = '';
css += 'function radioButton(id,gateway) {servConn.setState(id, gateway);}';
return css;
}
function createRoamingCheckbox(id)
{
var css = "";
var roaming = parseInt(getState(getRoamingId(id)).val) == 1 ? "checked" : "";
css += '<td scope="col" style="text-align:center">';
css += '<input type="checkbox" id="' +id+ '" name="'+id+'" onchange="checkBox(\'' + getRoamingId(id) + '\',this.checked)" '+ roaming + '>';
css += '</td>';
return css;
}
function createEventCheckBox()
{
var css = '';
css += 'function checkBox(id,checked) {servConn.setState(id, checked?"1":"0");}';
return css;
}
function createRSSIColour(value)
{
var yellow=100-80; // -80dbm shall be the center and show yellow;
var v=100+value;
if (v<0) v=0;
var r = (v<=yellow) ? 255 : Math.round(255 - 255*(v-yellow)/yellow);
var g = (v<=yellow) ? Math.round(255-255*(yellow-v)/yellow) : 255;
var b=0;
if(r<0) r=0;
var rs = r.toString(16); if (r<16) rs = "0"+rs;
var gs = g.toString(16); if (g<16) gs = "0"+gs;
var bs = b.toString(16); if (b<16) bs = "0"+bs;
return "#" + rs.toUpperCase() + gs.toUpperCase() + bs.toUpperCase();
}
function increaseUnreachableCounter(obj)
{
var unreachable = getState(obj.id).val;
if (unreachable)
{
var cntID = getUnreachableCounterId(readDeviceID(obj.id,HM_RPC));
var cnt = parseInt(getState(cntID).val);
setState(cntID,cnt+1);
}
}
function resetUnreachableCounters()
{
log("reset unreachable counters");
var ids = $('[id='+ getUnreachableCounterId("*")+']');
ids.each(id => {setState(id,0);});
setRSSIState(CSSResetId,"",false,'boolean');
}
function readDeviceID(objId,path)
{
var deviceID = ""
if (path[path.length-1] == ".") path = path.substring(0,path.length-1); //get rid of the last "."
var pos = objId.indexOf(path)+path.length+1;
deviceID = objId.substring(pos,pos+10);
return deviceID;
}
function getDeviceRssiId(deviceID,gateway,i) {return devicePath + deviceID + ".Gateways." + gateway + ".RSSI" + i;}
function getDeviceRssiName(deviceName,gateway,i) {return deviceName + "-" + gateway + "-RSSI" + i;}
function getGatewayId(deviceID) {return devicePath + deviceID + ".Info.Gateway"}
function getGatewayName(deviceName) {return deviceName + "_Gateway"}
function getUnreachableCounterId(deviceID) {return devicePath + deviceID + ".Info.UnreachCounter";}
function getUnreachableCounterName(deviceName) {return deviceName +"_UnreachCounter";};
function getRoamingId(deviceID) {return devicePath + deviceID + ".Info.Roaming";}
function getRoamingName(deviceName) {return deviceName+"_Roaming";};
function getNameId(deviceID) {return devicePath + deviceID + ".Info.Name";}
function getNameName(deviceName) {return deviceName + "_Name";};
function getGatewayRssiId(gateway,deviceID,i) {return gatewayPath + gateway + ".Devices." + deviceID + ".RSSI" + i;};
function getGatewayRssiName(gateway,deviceName,i) {return gateway + "-" + deviceName + "-RSSI" + i;}
function getGatewayCounterId(gateway) {return gatewayPath + gateway + ".Info.DeviceCounter";}
function getGatewayDutyCycleId(gateway) {return gatewayPath + gateway + ".Info.DutyCycle";}
function getGatewayDutyCycleName(gateway) {return gateway + "_DutyCycle";}
function fDate(date) {return date.length<2 ? "0"+date:date;}
/**
* checks if a a given state or part of state is existing.
* This is a workaround, as getObject() or getState() throw warnings in the log.
* Set strict to true if the state shall match exactly. If it is false, it will add a wildcard * to the end.
* See: https://forum.iobroker.net/topic/11354/
* @param {string} strStatePath Input string of state, like 'javascript.0.switches.Osram.Bedroom'
* @param {boolean} [strict=false] Optional: if true, it will work strict, if false, it will add a wildcard * to the end of the string
* @return {boolean} true if state exists, false if not
*/
function isState(strStatePath, strict) {
let mSelector;
if (strict) {
mSelector = $('state[id=' + strStatePath + '$]');
} else {
mSelector = $('state[id=' + strStatePath + ']');
}
if (mSelector.length > 0) {
return true;
} else {
return false;
}
}
Beispieltabelle in VIS
Zahlen unterhalb der Gateways
- Anzahl Geräte
- DutyCycle
- Summe "UNREACHABLE" aller Geräte des Gateways (die Spalte zeigt die Anzahl der "UNREACH" Status des Geräts)
Buttons
- Update: Erstellt neue Tabelle
- Reset: Setzt alle "Unreachable Counters" auf 0