252 lines
No EOL
11 KiB
Cheetah
252 lines
No EOL
11 KiB
Cheetah
<h1 class="page-header">Zigbee Node Overview</h1>
|
|
|
|
<h2>Network info</h2>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="panel panel-default drop-shadow">
|
|
<div class="panel-heading">Node Description</div>
|
|
<div class="panel-body">
|
|
<table class="table table-hover table-condensed">
|
|
<thead>
|
|
<tr>
|
|
<th class="text-right">PAN ID:</th>
|
|
<td>{{controller.getZigbeePanId()}}</td>
|
|
</tr>
|
|
<tr>
|
|
<th class="text-right">Extended PAN ID:</th>
|
|
<td>{{controller.getZigbeeExtendedPanId()}}</td>
|
|
</tr>
|
|
</thead>
|
|
<tr>
|
|
<th class="text-right">Channel:</th>
|
|
<td>{{controller.getZigbeeChannel()}}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h2>Network Graph</h2>
|
|
|
|
<div id="network_graph"></div>
|
|
|
|
<script>
|
|
fetch('/api/zigbee')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
var nodes = [];
|
|
var links = [];
|
|
|
|
data.forEach(node => {
|
|
nodes.add({"id": node.address, "name": node.address});
|
|
nodes.neighbours.forEach(neighbour => {
|
|
links.add({"source": node.address, "target": neighbour})
|
|
}
|
|
});
|
|
|
|
const Graph = ForceGraph()
|
|
(document.getElementById('network_graph'))
|
|
.linkDirectionalParticles(2)
|
|
.graphData({
|
|
nodes: nodes,
|
|
links: links
|
|
}
|
|
);
|
|
});
|
|
</script>
|
|
|
|
<h2>Connected Nodes</h2>
|
|
|
|
{{#nodes}}
|
|
<div class="col-md-12">
|
|
<div class="panel panel-default drop-shadow">
|
|
<!-- NODE -->
|
|
|
|
<div class="panel-heading clearfix">
|
|
<a href="#a" class="pull-left" data-toggle="collapse" data-target="#node-{{.getIeeeAddress()}}">
|
|
Node: {{.getIeeeAddress()}}
|
|
</a>
|
|
|
|
<div class="btn-toolbar pull-right">
|
|
<form method="POST">
|
|
<input type="hidden" name="nodeAddress" value="{{.getIeeeAddress()}}">
|
|
<button type="submit" class="btn btn-danger btn-xs" name="action" value="node_remove">
|
|
<small class="glyphicon glyphicon-trash"></small>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div id="node-{{.getIeeeAddress()}}" class="panel-body collapse">
|
|
<div class="col-md-6">
|
|
<div class="panel panel-default drop-shadow">
|
|
<div class="panel-heading">Node Description</div>
|
|
<div class="panel-body">
|
|
<table class="table table-hover table-condensed">
|
|
<thead>
|
|
<tr>
|
|
<th class="text-right">Manufacturer Code:</th>
|
|
<td>{{.getNodeDescriptor().getManufacturerCode()}}</td>
|
|
</tr>
|
|
<tr>
|
|
<th class="text-right">Logical Type:</th>
|
|
<td>{{.getNodeDescriptor().getLogicalType()}}</td>
|
|
</tr>
|
|
</thead>
|
|
<tr>
|
|
<th class="text-right">Frequency Bands:</th>
|
|
<td>{{.getNodeDescriptor().getFrequencyBands()}}</td>
|
|
</tr>
|
|
<tr>
|
|
<th class="text-right">Mac Capabilities:</th>
|
|
<td>{{.getNodeDescriptor().getMacCapabilities()}}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="panel panel-default drop-shadow">
|
|
<div class="panel-heading">Power Descriptor</div>
|
|
<div class="panel-body">
|
|
<table class="table table-hover table-condensed">
|
|
<thead>
|
|
<tr>
|
|
<th class="text-right">Current Power Mode:</th>
|
|
<td>{{.getPowerDescriptor().getCurrentPowerMode()}}</td>
|
|
</tr>
|
|
<tr>
|
|
<th class="text-right">Available Power Sources:</th>
|
|
<td>{{.getPowerDescriptor().getAvailablePowerSources()}}</td>
|
|
</tr>
|
|
</thead>
|
|
<tr>
|
|
<th class="text-right">Current Power Source:</th>
|
|
<td>{{.getPowerDescriptor().getCurrentPowerSource()}}</td>
|
|
</tr>
|
|
<tr>
|
|
<th class="text-right">Power Level:</th>
|
|
<td>{{.getPowerDescriptor().getPowerLevel()}}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ENDPOINTS -->
|
|
|
|
<div class="col-md-12">
|
|
{{#.getEndpoints()}}
|
|
<div class="panel panel-default drop-shadow">
|
|
<div class="panel-heading">
|
|
<a href="#a" data-toggle="collapse" data-target="#node-{{.getIeeeAddress()}}-endpoint-{{.getDeviceId()}}">
|
|
Endpoint: {{.getDeviceId()}}
|
|
</a>
|
|
</div>
|
|
<div id="node-{{.getIeeeAddress()}}-endpoint-{{.getDeviceId()}}" class="panel-body collapse">
|
|
|
|
<p><b>Input Clusters:</b></p>
|
|
|
|
{{#.inputClusters.values()}}
|
|
<div class="panel panel-default drop-shadow">
|
|
<div class="panel-heading">
|
|
<a href="#a" data-toggle="collapse" data-target="#node-{{.getZigBeeAddress().getAddress()}}-endpoint-{{.getZigBeeAddress().getEndpoint()}}-in-cluster-{{.getClusterId()}}">
|
|
Cluster: {{.CLUSTER_NAME}} ({{.getClusterId()}})
|
|
</a>
|
|
</div>
|
|
<div id="node-{{.getZigBeeAddress().getAddress()}}-endpoint-{{.getZigBeeAddress().getEndpoint()}}-in-cluster-{{.getClusterId()}}" class="panel-body collapse">
|
|
<table class="table table-hover table-condensed">
|
|
<thead>
|
|
<th>ID</th>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Last Value</th>
|
|
<th>Last Report Time</th>
|
|
<th></th>
|
|
</thead>
|
|
{{#.getAttributes()}}
|
|
<tr>
|
|
<td>{{.getId()}}</td>
|
|
<td>{{.getName()}}</td>
|
|
<td>{{.getDataType()}}</td>
|
|
<td>{{.getLastValue()}}</td>
|
|
<td><span class="timestamp">{{.getLastReportTime().getTimeInMillis()}}</span></td>
|
|
<td>
|
|
<form method="POST">
|
|
<input type="hidden" name="nodeAddress" value="{{.cluster.zigbeeEndpoint.node.getIeeeAddress()}}">
|
|
<input type="hidden" name="endpointId" value="{{.cluster.zigbeeEndpoint.getEndpointId()}}">
|
|
<input type="hidden" name="clusterId" value="{{.cluster.getClusterId()}}">
|
|
<input type="hidden" name="attributeId" value="{{.getId()}}">
|
|
|
|
<div class="btn-toolbar pull-right">
|
|
<button type="submit" class="btn btn-primary btn-xs" name="action" value="refresh">
|
|
<span class="glyphicon glyphicon-refresh"></span>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{{/.getAttributes()}}
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{{/.inputClusters.values()}}
|
|
|
|
<p><b>Output Clusters:</b></p>
|
|
|
|
{{#.outputClusters.values()}}
|
|
<div class="panel panel-default drop-shadow">
|
|
<div class="panel-heading">
|
|
<a data-toggle="collapse" data-target="#node-{{.getZigBeeAddress().getAddress()}}-endpoint-{{.getZigBeeAddress().getEndpoint()}}-out-cluster-{{.getClusterId()}}">
|
|
Cluster: {{.CLUSTER_NAME}} ({{.getClusterId()}})
|
|
</a>
|
|
</div>
|
|
<div id="node-{{.getZigBeeAddress().getAddress()}}-endpoint-{{.getZigBeeAddress().getEndpoint()}}-out-cluster-{{.getClusterId()}}" class="panel-body collapse">
|
|
|
|
<table class="table table-hover table-condensed">
|
|
<thead>
|
|
<th>ID</th>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Last Value</th>
|
|
<th>Last Report Time</th>
|
|
<th></th>
|
|
</thead>
|
|
{{#.getAttributes()}}
|
|
<tr>
|
|
<td>{{.getId()}}</td>
|
|
<td>{{.getName()}}</td>
|
|
<td>{{.getDataType()}}</td>
|
|
<td>{{.getLastValue()}}</td>
|
|
<td><span class="timestamp">{{.getLastReportTime().getTimeInMillis()}}</span></td>
|
|
<td></td>
|
|
</tr>
|
|
{{/.getAttributes()}}
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{{/.outputClusters.values()}}
|
|
</div>
|
|
</div>
|
|
{{/.getEndpoints()}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{/nodes}}
|
|
|
|
<script>
|
|
$('.collapse').each(function(index) {
|
|
if (localStorage.getItem($(this).attr("id"))) {
|
|
$(this).collapse('show');
|
|
}
|
|
});
|
|
|
|
$('.collapse').on('show.bs.collapse', function () {
|
|
localStorage.setItem($(this).attr("id"), true);
|
|
})
|
|
$('.collapse').on('hide.bs.collapse', function () {
|
|
localStorage.removeItem($(this).attr("id"));
|
|
})
|
|
</script> |