Skip to content

Commit 5379e21

Browse files
committed
Refactored to split stats server and web server
1 parent 43d5a57 commit 5379e21

File tree

9 files changed

+384
-0
lines changed

9 files changed

+384
-0
lines changed

mqtt/app.css

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
body {
2+
font-family: Verdana,Tahoma,"DejaVu Sans",sans-serif;
3+
color: #201E1C;
4+
background-color: AntiqueWhite;
5+
}
6+
7+
p {
8+
width: 100%;
9+
}
10+
11+
table, th, td {
12+
border: 1px solid #CABFAF;
13+
}
14+
15+
16+
.clear {
17+
clear: both;
18+
}

mqtt/config.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"mqtt":
3+
{
4+
"host": "127.0.0.1",
5+
"port": "1833"
6+
}
7+
}

mqtt/index.html

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>
5+
Charlestown Power
6+
</title>
7+
<link type="text/css" rel="stylesheet" href="/app.css" media="all">
8+
</head>
9+
<body>
10+
Current total current power consumption <span id="sensors/power/0"></span>
11+
<table>
12+
<tr>
13+
<td><table id="myTablePower"><tr>
14+
</tr>
15+
</table>
16+
</td>
17+
<td>
18+
<table id="myTableTemp"></table>
19+
</td>
20+
<td>
21+
<table id="myTableHumidity"></table>
22+
</td>
23+
</tr></table>
24+
<table id="myTableNO2"></table>
25+
<table id="myTablePressure"></table>
26+
<table id="myTableCO"></table>
27+
<P>
28+
Total power today <span id="sensors/power/0powercumulativeToday"></span> KWh
29+
<P>
30+
Total power this hour <span id="sensors/power/0powercumulativeHour"></span> KWh
31+
<P>
32+
<canvas id="mycanvas" width="500" height="100"></canvas>
33+
<P>
34+
<div id="time" style="font-size:x-small"></div>
35+
36+
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
37+
<script src="http://www.trease.eu:8500/socket.io/socket.io.js"></script>
38+
<script type="text/javascript" src="http://github.com/joewalnes/smoothie/raw/master/smoothie.js"></script>
39+
<script>
40+
ElementExists = function(id) {
41+
return !!document.getElementById(id);
42+
};
43+
BeginsWith = function(needle, haystack){
44+
return (haystack.substr(0, needle.length) == needle);
45+
}
46+
47+
48+
var smoothie = new SmoothieChart({millisPerPixel: 500});
49+
var line1 = new TimeSeries();
50+
smoothie.streamTo(document.getElementById("mycanvas"));
51+
smoothie.addTimeSeries(line1);
52+
53+
var socket = io.connect("http://192.168.1.103:8500");
54+
socket.on('data', function(data) {
55+
// console.log("Message received " + data.topic + " of " + data.value);
56+
57+
// check the target topic exisits & if not create a target table entry
58+
if (!ElementExists (data.topic)) {
59+
// console.log("Creating target " + data.topic);
60+
var topictag = "sensors/power/";
61+
if (data.topic.substring(0,topictag.length) == topictag) {
62+
var table=document.getElementById("myTablePower");
63+
}
64+
var topictag = "sensors/temperature/";
65+
if (data.topic.substring(0,topictag.length) == topictag) {
66+
var table=document.getElementById("myTableTemp");
67+
}
68+
var topictag = "sensors/humidity/";
69+
if (data.topic.substring(0,topictag.length) == topictag) {
70+
var table=document.getElementById("myTableHumidity");
71+
}
72+
var topictag = "sensors/co/";
73+
if (data.topic.substring(0,topictag.length) == topictag) {
74+
var table=document.getElementById("myTableCO");
75+
}
76+
var topictag = "sensors/no2/";
77+
if (data.topic.substring(0,topictag.length) == topictag) {
78+
var table=document.getElementById("myTableNO2");
79+
}
80+
var topictag = "sensors/pressure/";
81+
if (data.topic.substring(0,topictag.length) == topictag) {
82+
var table=document.getElementById("myTablePressure");
83+
}
84+
85+
86+
var row=table.insertRow(0);
87+
var cell=row.insertCell(0);
88+
cell.id = data.topic;
89+
var cell=row.insertCell(0);
90+
cell.id = data.topic + "name";
91+
document.getElementById(data.topic).style.textAlign="right";
92+
document.getElementById(data.topic + "name").innerHTML= data.topic;
93+
}
94+
// new we know there is a target, update it
95+
// console.log("Setting target " + data.topic + " to " + data.value);
96+
document.getElementById(data.topic).innerHTML= data.value;
97+
98+
// if data topic is 0 it is the overall power consumption, so update the graph
99+
if (data.topic == "sensors/power/0") {
100+
line1.append (new Date().getTime(), data.value);
101+
}
102+
103+
// print the time the refresh happened
104+
var dt = new Date();
105+
document.getElementById("time").innerHTML= dt.toLocaleTimeString();
106+
});
107+
</script>
108+
</body>
109+
</html>
110+

mqtt/package.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "hello-world",
3+
"description": "hello world test app",
4+
"version": "0.0.1",
5+
"private": true,
6+
"dependencies": {
7+
"express": "3.x",
8+
"socket.io": "*",
9+
"smoothie": "*",
10+
"redis : "0.8.*",
11+
"mqtt": "*"
12+
}
13+
}

mqtt/power.html

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>
5+
Charlestown Power
6+
</title>
7+
<link type="text/css" rel="stylesheet" href="/app.css" media="all">
8+
</head>
9+
<body>
10+
Current total current power consumption <span id="sensors/power/0"></span>
11+
<table id="myTablePower"><tr>
12+
</tr>
13+
</table>
14+
<P>
15+
Total power today <span id="sensors/power/0powercumulativeToday"></span> KWh
16+
<P>
17+
Total power this hour <span id="sensors/power/0powercumulativeHour"></span> KWh
18+
<P>
19+
<canvas id="mycanvas" width="500" height="100"></canvas>
20+
<P>
21+
<div id="time" style="font-size:x-small"></div>
22+
23+
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
24+
<script src="http://www.trease.eu:8500/socket.io/socket.io.js"></script>
25+
<script type="text/javascript" src="http://github.com/joewalnes/smoothie/raw/master/smoothie.js"></script>
26+
<script>
27+
ElementExists = function(id) {
28+
return !!document.getElementById(id);
29+
};
30+
BeginsWith = function(needle, haystack){
31+
return (haystack.substr(0, needle.length) == needle);
32+
}
33+
34+
35+
var smoothie = new SmoothieChart({millisPerPixel: 500});
36+
var line1 = new TimeSeries();
37+
smoothie.streamTo(document.getElementById("mycanvas"));
38+
smoothie.addTimeSeries(line1);
39+
40+
var socket = io.connect("http://192.168.1.103:8500");
41+
socket.on('data', function(data) {
42+
// console.log("Message received " + data.topic + " of " + data.value);
43+
44+
// check the target topic exisits & if not create a target table entry
45+
if (!ElementExists (data.topic)) {
46+
// console.log("Creating target " + data.topic);
47+
var topictag = "sensors/power/";
48+
if (data.topic.substring(0,topictag.length) == topictag) {
49+
var table=document.getElementById("myTablePower");
50+
var row=table.insertRow(0);
51+
var cell=row.insertCell(0);
52+
cell.id = data.topic;
53+
var cell=row.insertCell(0);
54+
cell.id = data.topic + "name";
55+
document.getElementById(data.topic).style.textAlign="right";
56+
document.getElementById(data.topic + "name").innerHTML= data.topic;
57+
}
58+
}
59+
// now we know there is a target, update it (unless it is one we don't want one this page)
60+
// console.log("Setting target " + data.topic + " to " + data.value);
61+
if (ElementExists(data.topic)) {
62+
document.getElementById(data.topic).innerHTML= data.value;
63+
} else {
64+
// console.log("ignoring " + data.topic);
65+
}
66+
67+
// if data topic is 0 it is the overall power consumption, so update the graph
68+
if (data.topic == "sensors/power/0") {
69+
line1.append (new Date().getTime(), data.value);
70+
}
71+
72+
// print the time the refresh happened
73+
var dt = new Date();
74+
document.getElementById("time").innerHTML= dt.toLocaleTimeString();
75+
});
76+
</script>
77+
</body>
78+
</html>
79+

mqtt/run-server.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
cd /home/download/mqtt
3+
nodemon server.js

mqtt/run-stats.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
cd /home/download/mqtt
3+
nodemon server-stats.js

mqtt/server-stats.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// service settings file
2+
// ur
3+
var config = require('./config.json');
4+
5+
var redis = require('redis')
6+
,redisClient = redis.createClient();
7+
8+
9+
redisClient.on('connect' , log('connect'));
10+
redisClient.on('ready' , log('ready'));
11+
redisClient.on('reconnecting', log('reconnecting'));
12+
redisClient.on('error' , log('error'));
13+
function log(type) {
14+
return function() {
15+
console.log(type, arguments);
16+
}
17+
}
18+
19+
20+
var powerlasttime = new Date(); // UNIX time in ms
21+
22+
// get last stored values from Redis
23+
var execSync = require('execSync');
24+
var result = execSync.exec('redis-cli get powercumulativeHour');
25+
var powercumulativeHour = parseFloat(result.stdout);
26+
var result = execSync.exec('redis-cli get powercumulativeToday');
27+
var powercumulativeToday = parseFloat(result.stdout);
28+
29+
console.log("loaded powercumulativeHour: " + powercumulativeHour + " (" + typeof powercumulativeHour + ")");
30+
console.log("loaded powercumulativeToday: " + powercumulativeToday + " (" + typeof powercumulativeToday + ")");
31+
32+
// subscribe to MQTT
33+
var mqtt = require('mqtt');
34+
var mqttclient = mqtt.createClient(1883, config.mqtt.host, function(err, client) {
35+
keepalive: 1000
36+
});
37+
console.log('connecting to mqtt on ' + config.mqtt.host + '(' + config.mqtt.port + ')');
38+
39+
40+
mqttclient.on('connect', function() {
41+
mqttclient.subscribe('sensors/power/+');
42+
console.log('subscribing to sensors/power/+ on ' + config.mqtt.host + '(' + config.mqtt.port + ')');
43+
44+
mqttclient.on('message', function(topic, message) {
45+
// console.log('topic: ' + topic + ' payload: ' + message);
46+
if (topic == "sensors/power/0") {
47+
var powercurrenttime = new Date();
48+
// Is it now a different day from the last time this block ran?
49+
if (powerlasttime.getDate() != powercurrenttime.getDate()) {
50+
powercumulativeToday = 0;
51+
}
52+
if (powerlasttime.getHours() != powercurrenttime.getHours()) {
53+
powercumulativeHour = 0;
54+
}
55+
// caluclate cumlative power used in KWh
56+
var duration = (powercurrenttime - powerlasttime) / 1000.0;
57+
var powerused = parseInt(message, 10) * (duration / 3600.0) / 1000.0; // convert to KWh
58+
powercumulativeToday += powerused;
59+
powercumulativeHour += powerused;
60+
redisClient.set("powercumulativeToday", powercumulativeToday);
61+
redisClient.set("powercumulativeHour", powercumulativeHour);
62+
// console.log("duration ", duration, "period ", powerused, "today ", powercumulativeToday, "hour ", powercumulativeHour);
63+
mqttclient.publish("sensors/power/0powercumulativeToday", powercumulativeToday.toString());
64+
mqttclient.publish("sensors/power/0powercumulativeHour", powercumulativeHour.toString());
65+
powerlasttime = powercurrenttime;
66+
}
67+
});
68+
});

mqtt/server.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
var express = require('express');
2+
var app = express()
3+
, http = require('http')
4+
, server = http.createServer(app)
5+
, io = require('socket.io').listen(server, {'log level': 1});
6+
var fs = require('fs');
7+
8+
// service settings file
9+
var config = require('./config.json');
10+
11+
12+
var connectionCount = 0;
13+
14+
15+
16+
app.get('/app.css', function (req, res) {
17+
console.log('connection %j %s %s', req.connection.remoteAddress, req.method, req.url);
18+
res.sendfile(__dirname + '/app.css');
19+
});
20+
app.get('/stats', function(req, res){
21+
res.send(connectionCount + " clients connected");
22+
console.log('connection %j %s %s', req.connection.remoteAddress, req.method, req.url);
23+
console.log('This process is pid ' + process.pid + " with an uptime of " + process.uptime());
24+
console.log('Running on ' + process.platform + ' (' + process.arch + ')');
25+
});
26+
app.get('/power', function(req, res) {
27+
console.log('connection %j %s %s', req.connection.remoteAddress, req.method, req.url);
28+
fs.readFile(__dirname + '/power.html',
29+
function (err, data) {
30+
if (err) {
31+
res.writeHead(500);
32+
return res.end('Error loading power.html');
33+
}
34+
res.writeHead(200);
35+
res.end(data);
36+
});
37+
38+
});
39+
app.get('/', function(req, res) {
40+
console.log('connection %j %s %s', req.connection.remoteAddress, req.method, req.url);
41+
fs.readFile(__dirname + '/index.html',
42+
function (err, data) {
43+
if (err) {
44+
res.writeHead(500);
45+
return res.end('Error loading index.html');
46+
}
47+
res.writeHead(200);
48+
res.end(data);
49+
});
50+
51+
});
52+
53+
54+
55+
// start the server
56+
server.listen(8500);
57+
console.log('listening on port 8500');
58+
59+
60+
io.sockets.on('connection', function (socket) {
61+
connectionCount++;
62+
});
63+
io.sockets.on('disconnet', function (socket) {
64+
connectionCount--;
65+
});
66+
67+
68+
// subscribe to MQTT
69+
var mqtt = require('mqtt');
70+
var client = mqtt.createClient(1883, config.mqtt.host, function(err, client) {
71+
keepalive: 1000
72+
});
73+
console.log('connecting to mqtt on ' + config.mqtt.host + '(' + config.mqtt.port + ')');
74+
75+
client.on('connect', function() {
76+
client.subscribe('sensors/+/+');
77+
console.log('subscribing to sensors/+/+ on ' + config.mqtt.host + '(' + config.mqtt.port + ')');
78+
79+
client.on('message', function(topic, message) {
80+
// console.log('topic: ' + topic + ' payload: ' + message);
81+
io.sockets.emit('data', { topic: topic, value: message });
82+
});
83+
});

0 commit comments

Comments
 (0)