-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
executable file
·118 lines (87 loc) · 3.26 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env node
const Prometheus = require( 'prom-client' );
const Registry = Prometheus.Registry;
const register = new Registry();
const logger = require( './logger' );
const cli = require( './cli' );
const port = cli.args.tcpport;
const host = cli.args.address;
const Host = require( './host' );
const Renogy = require( './renogy' );
const { prometheusDataMap } = require( './prometheus' );
let renogyData, controllerInfo = null;
const path = require( 'path' );
const express = require( 'express' );
const app = express()
app.use( express.static( 'web' ) );
app.use( ( request, response, next ) => {
response.header( 'Access-Control-Allow-Origin', '*' );
response.header( 'Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept' );
logger.trace( `Received a request for '${request.url}'` );
next();
});
app.get( '/', function ( request, response ) {
logger.trace( 'Got a request for ' );
response.sendFile( path.join( __dirname, '/web/index.html ') );
});
app.get( '/metrics', async function ( request, response ) {
const metrics = await register.metrics();
response.set( 'Content-type', register.contentType );
response.status( 200 ).send( metrics );
});
app.get( '/metrics.json', async function ( request, response ) {
response.set( 'Content-type', 'application/json' );
response.status( 200 ).send( JSON.stringify( renogyData ) );
});
app.get( '/info.json', async function ( request, response ) {
if( !controllerInfo )
controllerInfo = await Renogy.getControllerInfo();
response.set( 'Content-type', 'application/json' );
response.status( 200 ).send( JSON.stringify( controllerInfo ) );
});
async function initRegister()
{
Renogy.begin();
logger.info( 'Preparing metrics...' );
for( element in prometheusDataMap )
{
const thisMetric = new Prometheus.Gauge({
name: prometheusDataMap[element].name,
help: prometheusDataMap[element].help
});
register.registerMetric( thisMetric );
logger.trace( `Added ${thisMetric.name}` )
}
logger.info( '...metrics ready.' )
}
async function readRenogyData()
{
try {
renogyData = await Renogy.getData();
if( !renogyData )
return;
for( const [ key, value ] of Object.entries( renogyData ) )
{
if( prometheusDataMap.hasOwnProperty( key ) )
register.getSingleMetric( prometheusDataMap[key].name ).set( value );
}
}
catch( e )
{
logger.warn( e, 'Failed to read data from Renogy device. Exception:' )
}
}
async function readHostData()
{
const hostCpuTemp = await Host.getCpuTemp();
if( hostCpuTemp )
register.getSingleMetric( 'renogy_host_cpu_temp' ).set( hostCpuTemp );
}
app.listen( port, host, () => {
initRegister();
// We refresh the metrics register on a timed loop instead of per-request so that data is ready to go immediately when
// requested, and also as a simple measure to reduce load for spammy requests that are repeated too frequently.
setInterval( readRenogyData, 1000 );
setInterval( readHostData, 5000 );
logger.info( `SerialRenogy is ready to service requests on http://${host}:${port}/` );
});