Compare commits
9 Commits
2b84618d1e
...
8cb33997fa
Author | SHA1 | Date |
---|---|---|
Lucas Pleß | 8cb33997fa | |
Lucas Pleß | 4b4294972e | |
Lucas Pleß | 3dd8b88f72 | |
Lucas Pleß | 1b29aa6044 | |
Lucas Pleß | 87cdfd7cae | |
Lucas Pleß | d33ee999d1 | |
Lucas Pleß | 484cb71804 | |
Lucas Pleß | 0e913ea3ef | |
Lucas Pleß | d17c24bde7 |
14
README.md
14
README.md
|
@ -6,6 +6,9 @@ Entstanden im Oktober 2013 von Lucas als bastelprojekt im mal etwas mit
|
|||
NodeJS zu machen. Damals mit express, und SpaceAPI Support. Es wurde
|
||||
der Switch im Raum gepingt um zu schauen ob der Raum "auf" ist.
|
||||
|
||||
Das ganze wurde mit Angular (1) und ExpressJS gebaut. Es werden die Daten
|
||||
live via Websockets zwischen Server und Browser übertragen.
|
||||
|
||||
Via nmap Scan im Raum wurde die Anzahl von Geräten ermittelt und angezeigt.
|
||||
Später erfolgte ein Umbau auf SNMP. Es wurde der Router gefragt welche
|
||||
Mac Adressen Online sind, so wurde eine Optionale User-Liste im Status
|
||||
|
@ -18,4 +21,13 @@ zum Treff misst, auch mit eingebaut.
|
|||
Tunix kam dazu und stellte schöne Icons und machts kleinere Verbesserungen,
|
||||
Fionera fügte HTML5 Push notifications hinzu.
|
||||
|
||||
Danach kleinere Änderungen und Erweiterungen von henne, zeus, smash.
|
||||
Danach kleinere Änderungen und Erweiterungen von henne, zeus, smash.
|
||||
|
||||
|
||||
|
||||
## Entrümpelung 2022
|
||||
|
||||
Das meiste an Funktionn wurde wiede raus geworfen weil sich die CTDO infrastruktur
|
||||
sehr verändert hat und einiges kaputt war.
|
||||
|
||||
Der Status zeit nur noch Power und Raumstatus an. Es läuft wie gehabt via nmap-Ping.
|
15
flukso.js
15
flukso.js
|
@ -4,19 +4,22 @@ var request = require('request');
|
|||
|
||||
var Flukso = function(hostname, pathname) {
|
||||
var self = this;
|
||||
var regexp = /([0-9]+)\]\]$/; // /\(([0-9]+) hosts* up\)/;
|
||||
|
||||
this.pollPower = function() {
|
||||
request({url: "http://" + hostname + pathname}, function(error, res, response) {
|
||||
if (error) {
|
||||
self.emit('failed', error)
|
||||
} else {
|
||||
var matches = regexp.exec(response);
|
||||
if(matches != null && matches.length == 2) {
|
||||
var time = Date.now();
|
||||
var num = matches[1];
|
||||
self.emit('done', parseInt(num));
|
||||
|
||||
try {
|
||||
var jsondata = JSON.parse(response);
|
||||
var power = jsondata[jsondata.length-1][1];
|
||||
|
||||
self.emit('done', parseInt(power));
|
||||
} catch(err) {
|
||||
console.log("error parsing fluxo data");
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
49
ip-poll.js
49
ip-poll.js
|
@ -1,50 +1,20 @@
|
|||
//var redis = require("redis");
|
||||
var util = require('util');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var exec = require('child_process').exec;
|
||||
var moment = require('moment');
|
||||
|
||||
|
||||
var redisprefix = "ippoll:";
|
||||
|
||||
var IpPoll = function(switchaddr, hostsaddr) {
|
||||
var self = this;
|
||||
|
||||
// var redisClient = redis.createClient();
|
||||
var regexp = /\(([0-9]+) hosts* up\)/;
|
||||
var nmap = "nmap -n -sP ";
|
||||
|
||||
/*
|
||||
redisClient.on("connect", function () {
|
||||
console.log("IP-Poll: connected to redis");
|
||||
self.emit('ready');
|
||||
});
|
||||
|
||||
this.pollCount = function() {
|
||||
exec(nmap + "--min-hostgroup 10 " + hostsaddr, function (error, stdout, stderr) {
|
||||
if(error == null) {
|
||||
var matches = regexp.exec(stdout);
|
||||
if(matches != null && matches.length == 2) {
|
||||
var time = Date.now();
|
||||
|
||||
redisClient.zremrangebyscore(redisprefix + 'onlinecount', "-inf", time - 7*24*60*1000);
|
||||
|
||||
var num = matches[1];
|
||||
|
||||
redisClient.zadd(redisprefix + 'onlinecount', time, time + "|" + num, function() {
|
||||
self.emit('doneCount', parseInt(num));
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};*/
|
||||
|
||||
this.pollState = function() {
|
||||
exec(nmap + switchaddr, function (error, stdout, stderr) {
|
||||
if(error == null) {
|
||||
var matches = regexp.exec(stdout);
|
||||
if(matches != null && matches.length == 2) {
|
||||
self.emit('doneState', matches[1] == "1");
|
||||
if(matches != null && matches.length === 2) {
|
||||
self.emit('doneState', matches[1] === "1");
|
||||
}
|
||||
} else {
|
||||
self.emit('doneState', "unknown");
|
||||
|
@ -52,22 +22,7 @@ var IpPoll = function(switchaddr, hostsaddr) {
|
|||
});
|
||||
};
|
||||
|
||||
/*
|
||||
this.getHistory = function(start, end, callback) {
|
||||
|
||||
redisClient.zrangebyscore(redisprefix + 'onlinecount', "-inf", "+inf", function(err, replies) {
|
||||
var data = [];
|
||||
|
||||
replies.forEach(function (reply, i) {
|
||||
var line = reply.split('|');
|
||||
data.push( { at: moment(parseInt(line[0])).format(), value: line[1] });
|
||||
});
|
||||
|
||||
callback(data);
|
||||
});
|
||||
};*/
|
||||
};
|
||||
|
||||
util.inherits(IpPoll, EventEmitter);
|
||||
|
||||
module.exports = IpPoll;
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -31,12 +31,6 @@ h2 {
|
|||
margin-bottom: 0.7em;
|
||||
}
|
||||
|
||||
#graph {
|
||||
max-width: 400px;
|
||||
height: 200px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#gauge {
|
||||
width: 290px;
|
||||
height: 200px;
|
||||
|
@ -44,75 +38,12 @@ h2 {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
.btn-block {
|
||||
|
||||
margin-top: 5px;
|
||||
|
||||
}
|
||||
.btn-danger.focus, .btn-danger:focus {
|
||||
|
||||
color: #FFF;
|
||||
background-color: #C9302C;
|
||||
border-color: #761C19;
|
||||
|
||||
}
|
||||
.btn.focus, .btn:focus, .btn:hover {
|
||||
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
|
||||
}
|
||||
.btn.active.focus, .btn.active:focus, .btn.focus, .btn.focus:active, .btn:active:focus, .btn:focus {
|
||||
|
||||
outline: thin dotted;
|
||||
outline-offset: -2px;
|
||||
|
||||
}
|
||||
a:focus {
|
||||
|
||||
outline: thin dotted;
|
||||
outline-offset: -2px;
|
||||
|
||||
}
|
||||
a:focus, a:hover {
|
||||
|
||||
a:focus, a:hover {
|
||||
color: #23527C;
|
||||
text-decoration: underline;
|
||||
|
||||
}
|
||||
.btn-block {
|
||||
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
.btn-danger {
|
||||
|
||||
color: #FFF;
|
||||
background-color: #D9534F;
|
||||
border-color: #D43F3A;
|
||||
|
||||
}
|
||||
.btn-success {
|
||||
color: #FFF;
|
||||
background-color: #5CB85C;
|
||||
border-color: #4CAE4C;
|
||||
}
|
||||
.btn {
|
||||
|
||||
display: inline-block;
|
||||
padding: 6px 12px;
|
||||
margin-bottom: 0px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 1.42857;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
-moz-user-select: none;
|
||||
background-image: none;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ var gpower;
|
|||
angular.module('roomstateapp.controllers', []).
|
||||
controller('StatusCtrl', function ($scope, $http, Socket) {
|
||||
|
||||
// on page load request current data via simple API.
|
||||
$http({
|
||||
method: 'GET',
|
||||
url: '/api/simple/v2'
|
||||
|
@ -18,8 +19,9 @@ angular.module('roomstateapp.controllers', []).
|
|||
console.log("error getting data");
|
||||
});
|
||||
|
||||
// while page is loaded, new data will arrive via Websocket.
|
||||
Socket.on('sdata', function(message) {
|
||||
console.log("received data from server: " + message.data.names);
|
||||
console.log("received data from server: " + JSON.stringify(message.data));
|
||||
$scope.simple = message.data;
|
||||
gpower.refresh(message.data.power);
|
||||
});
|
||||
|
@ -61,7 +63,7 @@ angular.module('roomstateapp.services', []).
|
|||
|
||||
angular.module('roomstateapp.statusfilter', []).filter('statustostring', function() {
|
||||
return function(input) {
|
||||
return input == true ? 'geöffnet' : input == false ? 'geschlossen' : 'unbekannt';
|
||||
return input === true ? 'geöffnet' : input === false ? 'geschlossen' : 'unbekannt';
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
( function(){
|
||||
var autoload = {
|
||||
|
||||
/***************************
|
||||
* DatePicker - Default CSS selector is .ink-datepicker
|
||||
***************************/
|
||||
'DatePicker_1': '.ink-datepicker',
|
||||
|
||||
/***************************
|
||||
* Gallery - Default CSS selector is ul.ink-gallery-source
|
||||
***************************/
|
||||
'Gallery_1': 'ul.ink-gallery-source',
|
||||
|
||||
/***************************
|
||||
* Modal - Default CSS selector is .ink-modal
|
||||
***************************/
|
||||
'Modal_1': '.ink-modal',
|
||||
|
||||
/***************************
|
||||
* ProgressBar - Default CSS selector is .ink-progress-bar
|
||||
***************************/
|
||||
'ProgressBar_1': '.ink-progress-bar',
|
||||
|
||||
/***************************
|
||||
* SortableList - Default CSS selector is .ink-sortable-list
|
||||
***************************/
|
||||
'SortableList_1': '.ink-sortable-list',
|
||||
|
||||
/***************************
|
||||
* Spy - Default CSS selector is *[data-spy="true"]
|
||||
***************************/
|
||||
'Spy_1': '*[data-spy="true"]',
|
||||
|
||||
/***************************
|
||||
* Sticky - Default CSS selector is .ink-navigation.sticky
|
||||
***************************/
|
||||
'Sticky_1': '.ink-navigation.sticky',
|
||||
|
||||
/***************************
|
||||
* Table - Default CSS selector is .ink-table
|
||||
***************************/
|
||||
'Table_1': '.ink-table',
|
||||
|
||||
/***************************
|
||||
* Tabs - Default CSS selector is .ink-tabs
|
||||
***************************/
|
||||
'Tabs_1': '.ink-tabs',
|
||||
|
||||
/***************************
|
||||
* TreeView - Default CSS selector is .ink-tree-view
|
||||
***************************/
|
||||
'TreeView_1': '.ink-tree-view',
|
||||
|
||||
/***************************
|
||||
* Toggle - Default CSS selector is .toggle
|
||||
***************************/
|
||||
'Toggle_1': '.toggle',
|
||||
|
||||
/***************************
|
||||
* Tooltip - Default CSS selector is .tooltip
|
||||
***************************/
|
||||
'Tooltip_1': '.tooltip'
|
||||
};
|
||||
|
||||
Ink.requireModules(['Ink.Dom.Selector_1', 'Ink.Dom.Loaded_1', 'Ink.Util.Array_1', 'Ink.UI.SmoothScroller_1', 'Ink.UI.Close_1'],
|
||||
function( Selector, Loaded, InkArray, Scroller, Close ){
|
||||
|
||||
var elements;
|
||||
var fn = function( Component ) {
|
||||
InkArray.each(elements, function( element ){
|
||||
new Component(element);
|
||||
});
|
||||
};
|
||||
|
||||
Loaded.run(function(){
|
||||
for( var mod in autoload ){
|
||||
if( !autoload.hasOwnProperty(mod) ){
|
||||
continue;
|
||||
}
|
||||
elements = Selector.select( autoload[mod] );
|
||||
if( elements.length ){
|
||||
Ink.requireModules( ['Ink.UI.' + mod ], fn);
|
||||
}
|
||||
}
|
||||
Scroller.init();
|
||||
new Close();
|
||||
});
|
||||
});
|
||||
})();
|
108
snmp-mac.js
108
snmp-mac.js
|
@ -1,108 +0,0 @@
|
|||
var redis = require("redis");
|
||||
var snmp = require("net-snmp");
|
||||
var util = require('util');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var _u = require("underscore");
|
||||
|
||||
var redisprefix = "mac:";
|
||||
|
||||
|
||||
var SnmpMac = function(hostname, community) {
|
||||
var self = this;
|
||||
|
||||
var redisClient = redis.createClient();
|
||||
var session = snmp.createSession(hostname, community, { version: snmp.Version2c } );
|
||||
|
||||
var baseoid = "1.3.6.1.2.1.17.7.1.2.2.1.3";
|
||||
var regexp = /([0-9]+).([0-9]+).([0-9]+).([0-9]+).([0-9]+).([0-9]+)$/;
|
||||
var names = [];
|
||||
|
||||
redisClient.on("connect", function () {
|
||||
//redisClient.set(redisprefix + "00:80:a3:91:39:1c","ripe-atlas-probe");
|
||||
//redisClient.set(redisprefix + "d4:ca:6d:33:cf:79","routerboard");
|
||||
|
||||
console.log("SNMP-MAC: connected to redis");
|
||||
self.emit('ready');
|
||||
});
|
||||
|
||||
redisClient.on('error', function(err) {
|
||||
console.log("redis error: " + err);
|
||||
});
|
||||
|
||||
function getMacFromOID(oid, callback) {
|
||||
var matches = regexp.exec(oid);
|
||||
var mac = "";
|
||||
|
||||
if(matches != null) {
|
||||
for(var i = 1; i < matches.length; i++) {
|
||||
var num = parseInt(matches[i]);
|
||||
if(num <= 15) mac += "0";
|
||||
mac += num.toString(16) + ":";
|
||||
}
|
||||
mac = mac.substr(0, mac.length-1);
|
||||
|
||||
callback(mac);
|
||||
}
|
||||
}
|
||||
|
||||
function doneCb(error) {
|
||||
if (error)
|
||||
console.error(error.toString ());
|
||||
|
||||
self.emit('done', _u.uniq(names));
|
||||
}
|
||||
|
||||
function feedCb(varbinds) {
|
||||
for (var i = 0; i < varbinds.length; i++) {
|
||||
if (snmp.isVarbindError(varbinds[i])) {
|
||||
console.error(snmp.varbindError (varbinds[i]));
|
||||
} else {
|
||||
if(varbinds[i].value == "3") { // only valid arp entries
|
||||
getMacFromOID(varbinds[i].oid, function(mac) {
|
||||
// console.log(mac);
|
||||
redisClient.get(redisprefix + mac, function(err, reply) {
|
||||
if(reply != null) {
|
||||
if (reply.split('')[0] == '"' && reply.split('')[reply.split('').length -1] == '"') {
|
||||
var name = "";
|
||||
for (var i = 1; i < reply.split('').length - 1; i++){
|
||||
name += reply.split('')[i]
|
||||
}
|
||||
names.push(name)
|
||||
} else {
|
||||
names.push(reply);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.poll = function() {
|
||||
names.length = 0;
|
||||
session.subtree(baseoid, 20, feedCb, doneCb);
|
||||
};
|
||||
|
||||
this.stop = function() {
|
||||
redisClient.quit();
|
||||
};
|
||||
|
||||
this.add = function (mac, name, callback) {
|
||||
redisClient.set(redisprefix + mac, name, function (err) {
|
||||
if(typeof callback === "function") callback(err);
|
||||
});
|
||||
};
|
||||
|
||||
this.delete = function(mac, callback) {
|
||||
redisClient.del(redisprefix + mac, function(err) {
|
||||
if(typeof callback === "function") callback(err);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
util.inherits(SnmpMac, EventEmitter);
|
||||
|
||||
module.exports = SnmpMac;
|
|
@ -79,6 +79,7 @@ ippoll.on('doneState', function (state) {
|
|||
simpleanswer.lastchange = spaceanswer.state.lastchange;
|
||||
simpleanswer.lastchange = new Date().getTime();
|
||||
io.sockets.emit('sdata', {data: simpleanswer});
|
||||
console.log("room state changed: " + JSON.stringify(simpleanswer))
|
||||
});
|
||||
|
||||
flukso.on('done', function (num) {
|
||||
|
@ -139,9 +140,9 @@ app.get('/api/simple/v2', function (req, res) {
|
|||
|
||||
|
||||
function getstatusImage(req, res) {
|
||||
if (spaceanswer.state.open == true) {
|
||||
if (spaceanswer.state.open === true) {
|
||||
res.sendFile(path.resolve(__dirname, 'public/img/green.png'));
|
||||
} else if (spaceanswer.state.open == false) {
|
||||
} else if (spaceanswer.state.open === false) {
|
||||
res.sendFile(path.resolve(__dirname, 'public/img/red.png'));
|
||||
} else {
|
||||
res.sendFile(path.resolve(__dirname, 'public/img/yellow.png'));
|
||||
|
|
50
test.js
50
test.js
|
@ -1,50 +0,0 @@
|
|||
var moment = require("moment");
|
||||
var snmp = require("net-snmp");
|
||||
|
||||
|
||||
var baseoid = "1.3.6.1.2.1.17.7.1.2.2.1.3";
|
||||
var regexp = /([0-9]+).([0-9]+).([0-9]+).([0-9]+).([0-9]+).([0-9]+)$/;
|
||||
|
||||
var session = snmp.createSession("juni.ctdo.de", "ctdo23", { version: snmp.Version2c } )
|
||||
|
||||
|
||||
function getMacFromOID(oid, callback) {
|
||||
var matches = regexp.exec(oid);
|
||||
var mac = "";
|
||||
|
||||
if(matches != null) {
|
||||
for(var i = 1; i < matches.length; i++) {
|
||||
var num = parseInt(matches[i]);
|
||||
if(num <= 15) mac += "0";
|
||||
mac += num.toString(16) + ":";
|
||||
}
|
||||
mac = mac.substr(0, mac.length-1);
|
||||
|
||||
callback(mac);
|
||||
}
|
||||
}
|
||||
|
||||
function doneCb(error) {
|
||||
if (error)
|
||||
console.error(error.toString ());
|
||||
|
||||
}
|
||||
|
||||
function feedCb(varbinds) {
|
||||
for (var i = 0; i < varbinds.length; i++) {
|
||||
if (snmp.isVarbindError(varbinds[i])) {
|
||||
console.error(snmp.varbindError (varbinds[i]));
|
||||
} else {
|
||||
if(varbinds[i].value == "3") { // only valid arp entries
|
||||
getMacFromOID(varbinds[i].oid, function(mac) {
|
||||
console.log(mac);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
session.subtree(baseoid, 20, feedCb, doneCb);
|
||||
|
|
@ -3,8 +3,6 @@ html(ng-app="roomstateapp")
|
|||
head
|
||||
title #{title} - CTDO Raumstatus
|
||||
|
||||
//if IE 7
|
||||
link(rel="stylesheet",href="/css/ink-ie7-min.css",type="text/css",media="screen")
|
||||
script(type="text/javascript", src="/js/vendor/angular.min.js")
|
||||
script(type="text/javascript", src="/socket.io/socket.io.js")
|
||||
|
||||
|
|
Loading…
Reference in New Issue