WIP
This commit is contained in:
parent
8734849511
commit
056d035805
6 changed files with 182 additions and 8 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -27,3 +27,5 @@ options.mine.js
|
||||||
.vagrant
|
.vagrant
|
||||||
|
|
||||||
raqia.json
|
raqia.json
|
||||||
|
|
||||||
|
scratch/
|
||||||
|
|
|
||||||
40
lib/email.js
Normal file
40
lib/email.js
Normal 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
90
lib/notifier.js
Normal 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
|
||||||
|
|
@ -109,6 +109,7 @@ function query(client, queryStr, values, cb) {
|
||||||
client.query(queryStr, values, function(err, results) {
|
client.query(queryStr, values, function(err, results) {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (!isLowSeverity(err)) {
|
if (!isLowSeverity(err)) {
|
||||||
|
console.error(err)
|
||||||
console.log(queryStr);
|
console.log(queryStr);
|
||||||
console.log(values);
|
console.log(values);
|
||||||
}
|
}
|
||||||
|
|
@ -127,6 +128,7 @@ function silentQuery(client, queryStr, values, cb) {
|
||||||
client.query(queryStr, values, function(err) {
|
client.query(queryStr, values, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (!isLowSeverity(err)) {
|
if (!isLowSeverity(err)) {
|
||||||
|
console.error(err)
|
||||||
console.log(queryStr);
|
console.log(queryStr);
|
||||||
console.log(values);
|
console.log(values);
|
||||||
}
|
}
|
||||||
|
|
@ -506,12 +508,12 @@ exports.machineEvent = function machineEvent(rec, cb) {
|
||||||
var TTL = 2 * 60 * 60 * 1000
|
var TTL = 2 * 60 * 60 * 1000
|
||||||
connect(function(cerr, client, done) {
|
connect(function(cerr, client, done) {
|
||||||
if (cerr) return cb(cerr);
|
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 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 deleteSql = 'DELETE FROM machine_events WHERE (EXTRACT(EPOCH FROM (now() - created))) * 1000 > $1';
|
||||||
var deleteValues = [new Date(Date.now() - TTL).toISOString()];
|
var deleteValues = [TTL];
|
||||||
|
|
||||||
query(client, deleteSql, deleteValues, function(err) {
|
query(client, deleteSql, deleteValues, function(err) {
|
||||||
if (err) console.error(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');
|
exports.init('postgres://lamassu:lamassu@localhost/lamassu');
|
||||||
connect(function(err, client, done) {
|
connect(function(err, client, done) {
|
||||||
|
|
|
||||||
12
lib/sms.js
Normal file
12
lib/sms.js
Normal 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)
|
||||||
|
})
|
||||||
11
package.json
11
package.json
|
|
@ -16,21 +16,24 @@
|
||||||
"joi": "^5.1.0",
|
"joi": "^5.1.0",
|
||||||
"lamassu-bitcoinaverage": "~1.0.0",
|
"lamassu-bitcoinaverage": "~1.0.0",
|
||||||
"lamassu-bitcoind": "^1.1.0",
|
"lamassu-bitcoind": "^1.1.0",
|
||||||
|
"lamassu-bitgo": "^0.1.3",
|
||||||
"lamassu-bitpay": "~1.0.0",
|
"lamassu-bitpay": "~1.0.0",
|
||||||
"lamassu-bitstamp": "^1.0.2",
|
"lamassu-bitstamp": "^1.0.2",
|
||||||
"lamassu-blockchain": "^1.1.3",
|
"lamassu-blockchain": "^1.1.3",
|
||||||
"lamassu-blockcypher": "~0.1.0",
|
"lamassu-blockcypher": "~0.1.0",
|
||||||
|
"lamassu-coinapult": "^0.4.5",
|
||||||
|
"lamassu-coinbase": "^1.0.4",
|
||||||
"lamassu-coindesk": "~1.0.0",
|
"lamassu-coindesk": "~1.0.0",
|
||||||
|
"lamassu-coinfloor": "^0.1.2",
|
||||||
"lamassu-config": "~0.4.0",
|
"lamassu-config": "~0.4.0",
|
||||||
"lamassu-identitymind": "^1.0.1",
|
"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",
|
"lodash": "^2.4.1",
|
||||||
"minimist": "0.0.8",
|
"minimist": "0.0.8",
|
||||||
"node-uuid": "^1.4.2",
|
"node-uuid": "^1.4.2",
|
||||||
"pg": "~2.11.1",
|
"pg": "~2.11.1",
|
||||||
|
"ramda": "^0.19.1",
|
||||||
|
"smtp-connection": "^2.2.1",
|
||||||
|
"twilio": "^3.3.0-edge",
|
||||||
"wreck": "5.1.0"
|
"wreck": "5.1.0"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue