This commit is contained in:
Josh Harvey 2016-02-11 01:43:24 +02:00
parent 8734849511
commit 056d035805
6 changed files with 182 additions and 8 deletions

2
.gitignore vendored
View file

@ -27,3 +27,5 @@ options.mine.js
.vagrant
raqia.json
scratch/

40
lib/email.js Normal file
View file

@ -0,0 +1,40 @@
var SMTPConnection = require('smtp-connection')
/*
Nice job signing up! Let's finish getting you set up.
Simply change the settings in your email software to these:
SMTP Server: mail.smtp2go.com
SMTP Port: 2525 (recommended)
Username: josh@lamassu.is
Password: view / edit
*/
var options = {
port: 2525,
host: 'mail.smtp2go.com',
requireTLS: true
}
function send (from, to, subject, body, cb) {
var connection = new SMTPConnection(options)
connection.connect(function () {
connection.login({user: 'josh@lamassu.is', pass: 'HPtXGp}9baafiqns%6YFH'}, function (err) {
if (err) return console.error(err)
var envelope = {
from: from,
to: to
}
var message = 'Subject: ' + subject + '\n\n' + body
connection.send(envelope, message, function (err, info) {
connection.quit()
cb(err, info)
})
})
})
}
send('josh@lamassu.is', 'joshmh@gmail.com', 'Another test', 'Screen is stale.\n\nTest3', function (err, info) {
console.log(err)
console.log(info)
})

90
lib/notifier.js Normal file
View file

@ -0,0 +1,90 @@
'use strict'
var R = require('ramda')
var db = null
function init (_db) {
db = _db
}
function toInt10 (str) { return parseInt(str, 10) }
function jsonParse (event) {
return R.assoc('note', JSON.parse(event.note), event)
}
function sameState (a, b) {
return a.note.sessionId === b.note.sessionId && a.note.state === b.note.state
}
function checkStuckScreen (deviceEvents) {
var sortedEvents = R.sortBy(R.compose(toInt10, R.prop('device_time')), R.map(jsonParse, deviceEvents))
var noRepeatEvents = R.dropRepeatsWith(sameState, sortedEvents)
var lastEvent = R.last(noRepeatEvents)
var IDLE_STATES = ['idle', 'dualIdle']
var STALE_STATE = 60 * 1000
if (!lastEvent) {
console.log('No data for device')
return
}
var state = lastEvent.note.state
if (R.contains(state, IDLE_STATES)) {
console.log('Machine is idle [OK]')
return
}
console.log(lastEvent.age)
if (lastEvent.age > STALE_STATE) {
console.log('Stale state: ' + state + ' [ALERT]')
return
}
console.log('[OK]')
}
function checkStatus () {
/*
- Fetch devices from devices table
- Fetch all machine_events into memory
- For each device, verify the following:
- stuck on screen
- last screen is >5m stale and is not idle screen
- report stuck on screen and name of screen
- not scanning qr codes?
- low bitcoins -- need a separate strategy, but server has this info
- var fiatBalance = plugins.fiatBalance();
- machine isn't pinging server
*/
db.devices(function (err, devices) {
if (err) return console.error(err)
db.machineEvents(function (err, events) {
if (err) return console.error(err)
devices.rows.forEach(function (deviceRow) {
var deviceFingerprint = deviceRow.fingerprint
var deviceEvents = events.rows.filter(function (eventRow) {
return eventRow.device_fingerprint === deviceFingerprint
})
console.log('DEVICE: ' + deviceRow.fingerprint)
checkStuckScreen(deviceEvents)
})
})
})
}
var _db = require('./postgresql_interface')
var connectionString = 'postgres://lamassu:lamassu@localhost/lamassu'
_db.init(connectionString)
init(_db)
checkStatus()
// TODO: How to know which alerts have been sent?
// Send alert every 10m while alert state
// Remember last sent alert in memory

View file

@ -109,6 +109,7 @@ function query(client, queryStr, values, cb) {
client.query(queryStr, values, function(err, results) {
if (err) {
if (!isLowSeverity(err)) {
console.error(err)
console.log(queryStr);
console.log(values);
}
@ -127,6 +128,7 @@ function silentQuery(client, queryStr, values, cb) {
client.query(queryStr, values, function(err) {
if (err) {
if (!isLowSeverity(err)) {
console.error(err)
console.log(queryStr);
console.log(values);
}
@ -506,12 +508,12 @@ exports.machineEvent = function machineEvent(rec, cb) {
var TTL = 2 * 60 * 60 * 1000
connect(function(cerr, client, done) {
if (cerr) return cb(cerr);
var fields = ['id', 'device_fingerprint', 'event_type', 'note', 'device_time', 'created']
var fields = ['id', 'device_fingerprint', 'event_type', 'note', 'device_time']
var sql = getInsertQuery('machine_events', fields, false)
var values = [rec.id, rec.fingerprint, rec.eventType, rec.note, rec.deviceTime, new Date().toISOString()]
var values = [rec.id, rec.fingerprint, rec.eventType, rec.note, rec.deviceTime]
var deleteSql = 'DELETE FROM machine_events WHERE created < $1';
var deleteValues = [new Date(Date.now() - TTL).toISOString()];
var deleteSql = 'DELETE FROM machine_events WHERE (EXTRACT(EPOCH FROM (now() - created))) * 1000 > $1';
var deleteValues = [TTL];
query(client, deleteSql, deleteValues, function(err) {
if (err) console.error(err)
@ -524,6 +526,31 @@ exports.machineEvent = function machineEvent(rec, cb) {
});
};
exports.devices = function devices(cb) {
connect(function(cerr, client, done) {
if (cerr) return cb(cerr);
var sql = 'SELECT fingerprint, name FROM devices ' +
'WHERE authorized=$1';
query(client, sql, [true], function(err, results) {
done();
if (err) return cb(err);
cb(null, results)
})
})
}
exports.machineEvents = function machineEvents(cb) {
connect(function(cerr, client, done) {
if (cerr) return cb(cerr);
var sql = 'SELECT *, (EXTRACT(EPOCH FROM (now() - created))) * 1000 AS age FROM machine_events'
query(client, sql, [], function(err, results) {
done();
if (err) return cb(err);
cb(null, results)
})
})
}
/*
exports.init('postgres://lamassu:lamassu@localhost/lamassu');
connect(function(err, client, done) {

12
lib/sms.js Normal file
View file

@ -0,0 +1,12 @@
var accountSid = 'AC5b08587439d5e0adb5132d133941ab76'
var authToken = 'b4acf1212c0271d852706d17711e9670'
var client = require('twilio')(accountSid, authToken)
client.messages.create({
body: '[Lamassu] ALERT Stale screen: acceptingFirstBill',
to: '+359899948650',
from: '+16035383222'
}, function (err, message) {
console.log(err)
console.log(message)
})

View file

@ -16,21 +16,24 @@
"joi": "^5.1.0",
"lamassu-bitcoinaverage": "~1.0.0",
"lamassu-bitcoind": "^1.1.0",
"lamassu-bitgo": "^0.1.3",
"lamassu-bitpay": "~1.0.0",
"lamassu-bitstamp": "^1.0.2",
"lamassu-blockchain": "^1.1.3",
"lamassu-blockcypher": "~0.1.0",
"lamassu-coinapult": "^0.4.5",
"lamassu-coinbase": "^1.0.4",
"lamassu-coindesk": "~1.0.0",
"lamassu-coinfloor": "^0.1.2",
"lamassu-config": "~0.4.0",
"lamassu-identitymind": "^1.0.1",
"lamassu-coinbase": "^1.0.4",
"lamassu-coinapult": "^0.4.5",
"lamassu-coinfloor": "^0.1.2",
"lamassu-bitgo": "^0.1.3",
"lodash": "^2.4.1",
"minimist": "0.0.8",
"node-uuid": "^1.4.2",
"pg": "~2.11.1",
"ramda": "^0.19.1",
"smtp-connection": "^2.2.1",
"twilio": "^3.3.0-edge",
"wreck": "5.1.0"
},
"repository": {