Add logging
This commit is contained in:
parent
df45a32113
commit
ab0011c08d
3645
package-lock.json
generated
3645
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,8 @@
|
||||
"convert-units": "^2.3.4",
|
||||
"lodash": "^4.17.21",
|
||||
"onstarjs": "^2.2.1",
|
||||
"uuid": "^8.3.2"
|
||||
"uuid": "^8.3.2",
|
||||
"winston": "^3.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "^9.0.0",
|
||||
|
118
src/index.js
118
src/index.js
@ -1,4 +1,3 @@
|
||||
|
||||
const OnStar = require('onstarjs');
|
||||
const mqtt = require('async-mqtt');
|
||||
const uuidv4 = require('uuid').v4;
|
||||
@ -7,6 +6,8 @@ const Vehicle = require('./vehicle');
|
||||
const {Diagnostic} = require('./diagnostic');
|
||||
const MQTT = require('./mqtt');
|
||||
const Commands = require('./commands');
|
||||
const logger = require('./logger');
|
||||
|
||||
|
||||
const onstarConfig = {
|
||||
deviceId: process.env.ONSTAR_DEVICEID || uuidv4(),
|
||||
@ -18,6 +19,7 @@ const onstarConfig = {
|
||||
refreshInterval: parseInt(process.env.ONSTAR_REFRESH) || (30 * 60 * 1000), // 30 min
|
||||
allowCommands: _.toLower(_.get(process, 'env.ONSTAR_ALLOW_COMMANDS', 'true')) === 'true'
|
||||
};
|
||||
logger.info('OnStar Config', {onstarConfig});
|
||||
|
||||
const mqttConfig = {
|
||||
host: process.env.MQTT_HOST || 'localhost',
|
||||
@ -27,71 +29,75 @@ const mqttConfig = {
|
||||
tls: process.env.MQTT_TLS || false,
|
||||
prefix: process.env.MQTT_PREFIX || 'homeassistant',
|
||||
};
|
||||
logger.info('MQTT Config', {mqttConfig});
|
||||
|
||||
let loop, commands, vehicles;
|
||||
const init = () => new Commands(OnStar.create(onstarConfig));
|
||||
|
||||
const init = async () => {
|
||||
commands = new Commands(OnStar.create(onstarConfig));
|
||||
console.log('Requesting vehicles.');
|
||||
const getVehicles = async commands => {
|
||||
logger.info('Requesting vehicles');
|
||||
const vehiclesRes = await commands.getAccountVehicles();
|
||||
console.log(_.get(vehiclesRes, 'status'));
|
||||
vehicles = _.map(
|
||||
logger.info('Vehicle request status', {status: _.get(vehiclesRes, 'status')});
|
||||
const vehicles = _.map(
|
||||
_.get(vehiclesRes, 'response.data.vehicles.vehicle'),
|
||||
v => new Vehicle(v)
|
||||
);
|
||||
console.log('Vehicles returned:');
|
||||
for (const v of vehicles) {
|
||||
console.log(v.toString());
|
||||
}
|
||||
logger.debug('Vehicle request response', {vehicles: _.map(vehicles, v => v.toString())});
|
||||
return vehicles;
|
||||
}
|
||||
|
||||
const connectMQTT = async () => {
|
||||
const mqttHA = new MQTT(vehicles[0], 'homeassistant');
|
||||
const availTopic = mqttHA.getAvailabilityTopic();
|
||||
const client = await mqtt.connectAsync(`${mqttConfig.tls
|
||||
? 'mqtts' : 'mqtt'}://${mqttConfig.host}:${mqttConfig.port}`, {
|
||||
const connectMQTT = async availabilityTopic => {
|
||||
const url = `${mqttConfig.tls ? 'mqtts' : 'mqtt'}://${mqttConfig.host}:${mqttConfig.port}`;
|
||||
const config = {
|
||||
username: mqttConfig.username,
|
||||
password: mqttConfig.password,
|
||||
will: {topic: availTopic, payload: 'false', retain: true}
|
||||
will: {topic: availabilityTopic, payload: 'false', retain: true}
|
||||
};
|
||||
logger.info('Connecting to MQTT', {url, config: _.omit(config, 'password')});
|
||||
const client = await mqtt.connectAsync(url, config);
|
||||
logger.info('Connected to MQTT');
|
||||
return client;
|
||||
}
|
||||
|
||||
const configureMQTT = async (commands, client, mqttHA) => {
|
||||
if (!onstarConfig.allowCommands)
|
||||
return;
|
||||
|
||||
client.on('message', (topic, message) => {
|
||||
logger.debug('Subscription message', {topic, message});
|
||||
const {command, options} = JSON.parse(message);
|
||||
const commandFn = commands[command].bind(commands);
|
||||
logger.info('Command sent', {command});
|
||||
commandFn(options || {})
|
||||
.then(() => logger.info('Command completed', {command}))
|
||||
.catch(err=> logger.error('Command error', {command, err}));
|
||||
});
|
||||
|
||||
if (onstarConfig.allowCommands) {
|
||||
client.on('message', (topic, message) => {
|
||||
console.log(`Subscription message: ${topic} ${message}`);
|
||||
const {command, options} = JSON.parse(message);
|
||||
const commandFn = commands[command].bind(commands);
|
||||
commandFn(options || {})
|
||||
.then(() => console.log(`Command completed: ${command}`))
|
||||
.catch(err=> console.error(`Command error: ${command} ${err}`));
|
||||
});
|
||||
const topic = mqttHA.getCommandTopic();
|
||||
console.log(`Subscribed to: ${topic}`);
|
||||
await client.subscribe(topic);
|
||||
}
|
||||
|
||||
await client.publish(availTopic, 'true', {retain: true});
|
||||
return {mqttHA, client};
|
||||
const topic = mqttHA.getCommandTopic();
|
||||
logger.info('Subscribed to command topic', {topic});
|
||||
await client.subscribe(topic);
|
||||
};
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
await init();
|
||||
const commands = init();
|
||||
const vehicles = await getVehicles(commands);
|
||||
|
||||
const {mqttHA, client} = await connectMQTT();
|
||||
const mqttHA = new MQTT(vehicles[0], 'homeassistant');
|
||||
const availTopic = mqttHA.getAvailabilityTopic();
|
||||
const client = await connectMQTT(availTopic);
|
||||
await configureMQTT(commands, client, mqttHA);
|
||||
|
||||
const configurations = new Map();
|
||||
const run = async () => {
|
||||
const states = new Map();
|
||||
const v = vehicles[0];
|
||||
console.log('Requesting diagnostics:')
|
||||
const statsRes = await commands.diagnostics({
|
||||
diagnosticItem: v.getSupported()
|
||||
});
|
||||
console.log(_.get(statsRes, 'status'));
|
||||
logger.info('Requesting diagnostics');
|
||||
const statsRes = await commands.diagnostics({diagnosticItem: v.getSupported()});
|
||||
logger.info('Diagnostic request status', {status: _.get(statsRes, 'status')});
|
||||
const stats = _.map(
|
||||
_.get(statsRes, 'response.data.commandResponse.body.diagnosticResponse'),
|
||||
d => new Diagnostic(d)
|
||||
);
|
||||
logger.debug('Diagnostic request response', {stats: _.map(stats, s => s.toString())});
|
||||
|
||||
for (const s of stats) {
|
||||
if (!s.hasElements()) {
|
||||
@ -108,30 +114,36 @@ const connectMQTT = async () => {
|
||||
const payload = mqttHA.getStatePayload(s);
|
||||
states.set(topic, payload);
|
||||
}
|
||||
// publish configs
|
||||
const publishes = [];
|
||||
// publish sensor configs
|
||||
for (let [topic, config] of configurations) {
|
||||
// configure once
|
||||
if (!config.configured) {
|
||||
config.configured = true;
|
||||
const {payload} = config;
|
||||
console.log(`${topic} ${JSON.stringify(payload)}`);
|
||||
await client.publish(topic, JSON.stringify(payload), {retain: true});
|
||||
logger.info('Publishing message', {topic, payload});
|
||||
publishes.push(
|
||||
client.publish(topic, JSON.stringify(payload), {retain: true})
|
||||
);
|
||||
}
|
||||
}
|
||||
// update states
|
||||
// update sensor states
|
||||
for (let [topic, state] of states) {
|
||||
console.log(`${topic} ${JSON.stringify(state)}`);
|
||||
await client.publish(topic, JSON.stringify(state), {retain: true});
|
||||
logger.info('Publishing message', {topic, state});
|
||||
publishes.push(
|
||||
client.publish(topic, JSON.stringify(state), {retain: true})
|
||||
);
|
||||
}
|
||||
await Promise.all(publishes);
|
||||
};
|
||||
|
||||
const main = () => run()
|
||||
.then(() => console.log('Done, sleeping.'))
|
||||
.catch(e => console.error(e))
|
||||
const main = async () => run()
|
||||
.then(() => logger.info('Updates complete, sleeping.'))
|
||||
.catch(e => logger.error('Error', {error: e}))
|
||||
|
||||
await main();
|
||||
loop = setInterval(main, onstarConfig.refreshInterval);
|
||||
setInterval(main, onstarConfig.refreshInterval);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
logger.error('Main function error.', {error: e});
|
||||
}
|
||||
})();
|
||||
})();
|
||||
|
12
src/logger.js
Normal file
12
src/logger.js
Normal file
@ -0,0 +1,12 @@
|
||||
const winston = require('winston');
|
||||
const _ = require('lodash');
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: _.get(process, 'env.LOG_LEVEL', 'info'),
|
||||
format: winston.format.simple(),
|
||||
// format: winston.format.json(),
|
||||
transports: [new winston.transports.Console({stderrLevels: ['error']})]
|
||||
})
|
||||
|
||||
|
||||
module.exports = logger;
|
Loading…
Reference in New Issue
Block a user