84 lines
2.5 KiB
JavaScript
84 lines
2.5 KiB
JavaScript
const { intervalToDuration, secondsToMilliseconds, formatDuration } = require('date-fns/fp')
|
|
const _ = require('lodash/fp')
|
|
|
|
const ticker = require('../ticker')
|
|
const settingsLoader = require('./settings-loader')
|
|
|
|
const db = require('../db')
|
|
const machineLoader = require('../machine-loader')
|
|
|
|
const CONSIDERED_UP_SECS = 30
|
|
|
|
function checkWasConfigured () {
|
|
return settingsLoader.loadLatest()
|
|
.then(() => true)
|
|
.catch(() => false)
|
|
}
|
|
|
|
function machinesLastPing () {
|
|
const sql = `select min(extract(epoch from (now() - created))) as age
|
|
from machine_events
|
|
group by device_id`
|
|
|
|
return Promise.all([machineLoader.getMachineNames(), db.any(sql)])
|
|
.then(([machines, events]) => {
|
|
if (machines.length === 0) return 'No paired machines'
|
|
|
|
const addName = event => {
|
|
const machine = _.find(['deviceId', event.deviceId], machines)
|
|
if (!machine) return null
|
|
return _.set('name', machine.name, event)
|
|
}
|
|
|
|
const mapper = _.flow(_.filter(row => row.age > CONSIDERED_UP_SECS), _.map(addName), _.compact)
|
|
const downRows = mapper(events)
|
|
|
|
if (downRows.length === 0) return 'All machines are up'
|
|
|
|
if (downRows.length === 1) {
|
|
const row = downRows[0]
|
|
const age = intervalToDuration({ start: 0, end: secondsToMilliseconds(row.age) })
|
|
return `${row.name} down for ${formatDuration(age)}`
|
|
}
|
|
|
|
return 'Multiple machines down'
|
|
})
|
|
}
|
|
|
|
function status () {
|
|
const sql = `select extract(epoch from (now() - created)) as age
|
|
from server_events
|
|
where event_type=$1
|
|
order by created desc
|
|
limit 1`
|
|
|
|
return Promise.all([checkWasConfigured(), db.oneOrNone(sql, ['ping']), machinesLastPing()])
|
|
.then(([wasConfigured, statusRow, machineStatus]) => {
|
|
const age = statusRow && intervalToDuration({ start: 0, end: secondsToMilliseconds(statusRow.age) })
|
|
const up = statusRow ? statusRow.age < CONSIDERED_UP_SECS : false
|
|
const lastPing = statusRow && formatDuration(age)
|
|
|
|
return settingsLoader.loadLatest()
|
|
.catch(() => null)
|
|
.then(settings => {
|
|
return getRates(settings)
|
|
.then(rates => ({wasConfigured, up, lastPing, rates, machineStatus}))
|
|
})
|
|
})
|
|
}
|
|
|
|
function getRates (settings) {
|
|
if (!settings) return Promise.resolve([])
|
|
|
|
return ticker.getRates(settings, 'USD', 'BTC')
|
|
.then(ratesRec => {
|
|
return [{
|
|
crypto: 'BTC',
|
|
bid: parseFloat(ratesRec.rates.bid),
|
|
ask: parseFloat(ratesRec.rates.ask)
|
|
}]
|
|
})
|
|
.catch(() => [])
|
|
}
|
|
|
|
module.exports = {status}
|