Skip to content

Instantly share code, notes, and snippets.

@sameeraakbar
Created January 14, 2019 08:20
Show Gist options
  • Save sameeraakbar/7752297d45cdb40f4cd1bd5a86d57b0f to your computer and use it in GitHub Desktop.
Save sameeraakbar/7752297d45cdb40f4cd1bd5a86d57b0f to your computer and use it in GitHub Desktop.
<!doctype html>
<html>
<head>
<title>Network | FIBARO HC2</title>
<style type="text/css">
#mynetwork {
top: 0;
left: 0;
margin: 0 auto;
height: 850px;
}
</style>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis-network.min.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!--<p>Relations between the devices of HC2 network.</p>-->
<p>
Select device: <input type="text" id="selection" value=""><input type="button" id="select" value="Select"><br>
</p>
<p align="center" id="loading">loading...</p>
<div id="mynetwork"></div>
<script type="text/javascript">
function draw(nodes, edges) {
// create a network
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {
//configure: {
// enabled: true,
// filter: 'physics, layout',
// showButton: true
//},
layout: {
randomSeed: 8,
},
interaction: {
selectConnectedEdges: false,
},
nodes: {
shape: 'dot',
size: 16
},
edges: {
smooth: {
enabled: true,
type: "dynamic",
},
arrows: {
to: { enabled: true, scaleFactor: 1, type: 'arrow' },
},
color: {
inherit: false,
highlight: '#FF0000'
}
},
physics: {
forceAtlas2Based: {
gravitationalConstant: -30,
centralGravity: 0.005,
springConstant: 0.05,
springLength: 240,
//gravitationalConstant: -26,
//springLength: 230,
//springConstant: 0.18,
//avoidOverlap: 1
},
maxVelocity: 146,
solver: 'forceAtlas2Based',
timestep: 0.35,
stabilization: true
},
};
var network = new vis.Network(container, data, options);
network.stabilize(2000);
network.on("stabilizationIterationsDone", function () {
network.setOptions({ physics: false });
});
network.on("afterDrawing", function (ctx) {
document.getElementById('loading').style.display = 'none';
});
network.on('select', function (properties) {
// if nodes were clicked:
if (properties.nodes.length > 0) {
var nodeId = properties.nodes[0];
var nodes = (data.nodes.get().filter(function (node) { return node.id === nodeId; }));
var edges = data.edges.get().filter(function (edge) { return edge.owner === nodeId; });
if (nodes.length === 0) return;
if (edges.length === 0) return;
network.setSelection({
nodes: [nodeId].concat(nodes[0].routes),
edges: edges.map(a => a.id)
});
//console.log(edges);
//console.log(nodes);
} else {
network.unselectAll();
}
});
return network;
}
function adoptData(devices, rooms) {
function getDeviceName(dev) {
var slaves = devices.filter(function (el) {
return el.parentId === dev.id &&
el.visible &&
el.enabled;
});
// Oops!
if (slaves.length === 0) return dev.id + ":" + "undefined";
room = rooms.filter(function (room) {
return room.id === slaves[0].roomID;
});
return slaves[0].name + "\n" + (room.length > 0 ? room[0].name : "undefined");
}
var data = { nodes: [], edges: [] };
data.nodes.push({ id: 1, label: "HC2", title: "HC2", routes: [] });
var masters = devices.filter(function (el) {
return el.parentId === 1 && el.enabled;
});
jQuery.each(masters, function (i, dev) {
var item = {};
//var rcolor = '#' + (Math.random(dev.id) * 0xFFFFFF << 0).toString(16);
item.id = dev.id;
item.label = getDeviceName(dev);
item.lastWorkingRouteResponseTimestamp = dev.properties.lastWorkingRouteResponseTimestamp;
item.title = dev.id + " updated at " + new Date(item.lastWorkingRouteResponseTimestamp * 1000).toLocaleDateString() + " " + new Date(item.lastWorkingRouteResponseTimestamp * 1000).toLocaleTimeString();
var routes = $.parseJSON(dev.properties.lastWorkingRoute);
item.routes = routes;
item.font = { 'face': 'Monospace', align: 'center' };
//console.log(dev.interfaces);
var color = null;
color = (dev.interfaces.indexOf("battery") > -1) ? "#d3d3d3" : color;
color = (dev.interfaces.indexOf("zwaveWakeup") > -1) ? "#adadad" : color;
//color = (dev.interfaces.indexOf("battery") > -1 && dev.interfaces.indexOf("zwaveWakeup") > -1) ? "gray" : color;
item.color = (routes.length === 0) ? "Violet" : color;
if (routes.length === 0 || routes.length === 1) {
var ritem = { arrows: { to: { scaleFactor: 0 } } };
ritem.owner = dev.id;
ritem.from = dev.id;
ritem.to = 1;
item.cid = 1;
//route.color = { color: rcolor, highlight: rcolor };
data.edges.push(ritem);
} else {
routes = routes.reverse();
//console.log(routes);
var _id = dev.id;
var l = routes.length;
for (var r = 0; r < l; r++) {
var route = { arrows: { to: { scaleFactor: 0.5 } } };
route.owner = dev.id;
route.from = _id;
route.to = routes[r];
if (route.to === 1) route.arrows.to.scaleFactor = 0;
// route.color = { color: rcolor, highlight: rcolor };
_id = routes[r];
data.edges.push(route);
}
}
data.nodes.push(item);
});
return data;
}
(function () {
var network = null;
$.getJSON("load.php", {
})
.always(function (data) {
$.getJSON("devices.json", function (devices) {
$.getJSON("rooms.json", function (rooms) {
var data = adoptData(devices, rooms);
var str = JSON.stringify(data, undefined, 4);
//document.body.appendChild(document.createElement('pre')).innerHTML = str;
network = draw(new vis.DataSet(data.nodes), new vis.DataSet(data.edges));
});
});
});
var select = document.getElementById('select');
select.onclick = function () {
var selection = document.getElementById('selection');
var searchValue = selection.value.trim();
var nodeId = -1;
if (!isNaN(searchValue)) {
nodeId = parseInt(searchValue);
var items = (network.body.data.nodes.get().filter(function (node) { return node.id === nodeId; }));
if (items.length === 0) nodeId = -1;
} else {
var xitems = (network.body.data.nodes.get().filter(function (node) { return node.label.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1; }));
if (xitems.length !== 0) nodeId = xitems[0].id;
}
if (nodeId !== -1) {
var nodes = network.body.data.nodes.get().filter(function (node) { return node.id === nodeId; });
var edges = network.body.data.edges.get().filter(function (edge) { return edge.owner === nodeId; });
if (nodes.length === 0) return;
if (edges.length === 0) return;
network.setSelection({
nodes: [nodeId].concat(nodes[0].routes),
edges: edges.map(a => a.id)
});
}
};
})();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment