add device config and minor updates

This commit is contained in:
Michael Woods 2020-12-27 21:55:49 -05:00
parent 87f2f858a0
commit bf88193d24
6 changed files with 65 additions and 32 deletions

View File

@ -4,7 +4,8 @@ RUN mkdir /app
WORKDIR /app WORKDIR /app
COPY ["package.json", "/app/"] COPY ["package.json", "/app/"]
RUN npm install COPY ["package-lock.json", "/app/"]
RUN npm install --no-fund
COPY ["src", "/app/src"] COPY ["src", "/app/src"]

View File

@ -41,7 +41,7 @@ let loop;
console.log(v.toString()); console.log(v.toString());
} }
const mqttHA = new MQTT('homeassistant', vehicles[0].vin); const mqttHA = new MQTT(vehicles[0], 'homeassistant');
const availTopic = mqttHA.getAvailabilityTopic(); const availTopic = mqttHA.getAvailabilityTopic();
const client = await mqtt.connectAsync(`${mqttConfig.tls const client = await mqtt.connectAsync(`${mqttConfig.tls
? 'mqtts' : 'mqtt'}://${mqttConfig.host}:${mqttConfig.port}`, { ? 'mqtts' : 'mqtt'}://${mqttConfig.host}:${mqttConfig.port}`, {
@ -55,34 +55,33 @@ let loop;
const configurations = new Map(); const configurations = new Map();
const run = async () => { const run = async () => {
const states = new Map(); const states = new Map();
// Note: the library is set to use only the configured VIN, but using multiple for future proofing. const v = vehicles[0];
for (const v of vehicles) { console.log('Requesting diagnostics:')
console.log('Requesting diagnostics:') const statsRes = await onStar.diagnostics({
const statsRes = await onStar.diagnostics({ diagnosticItem: v.getSupported()
diagnosticItem: v.getSupported() });
}); console.log(_.get(statsRes, 'status'));
console.log(_.get(statsRes, 'status')); const stats = _.map(
const stats = _.map( _.get(statsRes, 'response.data.commandResponse.body.diagnosticResponse'),
_.get(statsRes, 'response.data.commandResponse.body.diagnosticResponse'), d => new Diagnostic(d)
d => new Diagnostic(d) );
);
for (const s of stats) { for (const s of stats) {
if (!s.hasElements()) { if (!s.hasElements()) {
continue; continue;
}
// configure once, then set or update states
for (const d of s.diagnosticElements) {
const topic = mqttHA.getConfigTopic(d)
const payload = mqttHA.getConfigPayload(s, d);
configurations.set(topic, {configured: false, payload});
}
const topic = mqttHA.getStateTopic(s);
const payload = mqttHA.getStatePayload(s);
states.set(topic, payload);
} }
// configure once, then set or update states
for (const d of s.diagnosticElements) {
const topic = mqttHA.getConfigTopic(d)
const payload = mqttHA.getConfigPayload(s, d);
configurations.set(topic, {configured: false, payload});
}
const topic = mqttHA.getStateTopic(s);
const payload = mqttHA.getStatePayload(s);
states.set(topic, payload);
} }
// publish configs
for (let [topic, config] of configurations) { for (let [topic, config] of configurations) {
// configure once // configure once
if (!config.configured) { if (!config.configured) {

View File

@ -36,9 +36,10 @@ const _ = require('lodash');
* } * }
*/ */
class MQTT { class MQTT {
constructor(prefix = 'homeassistant', instance = 'XXX') { constructor(vehicle, prefix = 'homeassistant') {
this.prefix = prefix; this.prefix = prefix;
this.instance = instance; this.vehicle = vehicle;
this.instance = vehicle.vin;
} }
static convertName(name) { static convertName(name) {
@ -139,6 +140,12 @@ class MQTT {
return { return {
device_class, device_class,
name, name,
device: {
identifiers: [this.vehicle.vin],
manufacturer: this.vehicle.make,
model: this.vehicle.year,
name: this.vehicle.toString()
},
availability_topic: this.getAvailabilityTopic(), availability_topic: this.getAvailabilityTopic(),
payload_available: 'true', payload_available: 'true',
payload_not_available: 'false', payload_not_available: 'false',

View File

@ -27,7 +27,7 @@ class Vehicle {
} }
toString() { toString() {
return `${this.year} ${this.make} ${this.model} ${this.vin}`; return `${this.year} ${this.make} ${this.model}`;
} }
} }

View File

@ -3,11 +3,13 @@ const _ = require('lodash');
const { Diagnostic } = require('../src/diagnostic'); const { Diagnostic } = require('../src/diagnostic');
const MQTT = require('../src/mqtt'); const MQTT = require('../src/mqtt');
const Vehicle = require('../src/vehicle');
const apiResponse = require('./diagnostic.sample.json'); const apiResponse = require('./diagnostic.sample.json');
describe('MQTT', () => { describe('MQTT', () => {
let mqtt; let mqtt;
beforeEach(() => mqtt = new MQTT()); let vehicle = new Vehicle({make: 'foo', model: 'bar', vin: 'XXX', year: 2020});
beforeEach(() => mqtt = new MQTT(vehicle));
it('should set defaults', () => { it('should set defaults', () => {
assert.strictEqual(mqtt.prefix, 'homeassistant'); assert.strictEqual(mqtt.prefix, 'homeassistant');
@ -57,6 +59,14 @@ describe('MQTT', () => {
it('should generate config payloads', () => { it('should generate config payloads', () => {
assert.deepStrictEqual(mqtt.getConfigPayload(d, d.diagnosticElements[0]), { assert.deepStrictEqual(mqtt.getConfigPayload(d, d.diagnosticElements[0]), {
availability_topic: 'homeassistant/XXX/available', availability_topic: 'homeassistant/XXX/available',
device: {
identifiers: [
'XXX'
],
manufacturer: 'foo',
model: 2020,
name: '2020 foo bar'
},
device_class: 'temperature', device_class: 'temperature',
json_attributes_template: undefined, json_attributes_template: undefined,
name: 'Ambient Air Temperature', name: 'Ambient Air Temperature',
@ -79,6 +89,14 @@ describe('MQTT', () => {
it('should generate config payloads', () => { it('should generate config payloads', () => {
assert.deepStrictEqual(mqtt.getConfigPayload(d, d.diagnosticElements[1]), { assert.deepStrictEqual(mqtt.getConfigPayload(d, d.diagnosticElements[1]), {
availability_topic: 'homeassistant/XXX/available', availability_topic: 'homeassistant/XXX/available',
device: {
identifiers: [
'XXX'
],
manufacturer: 'foo',
model: 2020,
name: '2020 foo bar'
},
device_class: undefined, device_class: undefined,
json_attributes_template: undefined, json_attributes_template: undefined,
name: 'Priority Charge Indicator', name: 'Priority Charge Indicator',
@ -103,6 +121,14 @@ describe('MQTT', () => {
it('should generate payloads with an attribute', () => { it('should generate payloads with an attribute', () => {
assert.deepStrictEqual(mqtt.getConfigPayload(d, d.diagnosticElements[0]), { assert.deepStrictEqual(mqtt.getConfigPayload(d, d.diagnosticElements[0]), {
availability_topic: 'homeassistant/XXX/available', availability_topic: 'homeassistant/XXX/available',
device: {
identifiers: [
'XXX'
],
manufacturer: 'foo',
model: 2020,
name: '2020 foo bar'
},
device_class: 'pressure', device_class: 'pressure',
json_attributes_template: "{{ {'recommendation': value_json.tire_pressure_placard_front} | tojson }}", json_attributes_template: "{{ {'recommendation': value_json.tire_pressure_placard_front} | tojson }}",
name: 'Tire Pressure: Left Front', name: 'Tire Pressure: Left Front',

View File

@ -36,6 +36,6 @@ describe('Vehicle', () => {
}); });
it('should toString() correctly', () => { it('should toString() correctly', () => {
assert.strictEqual(v.toString(), '2020 Chevrolet Bolt EV foobarVIN') assert.strictEqual(v.toString(), '2020 Chevrolet Bolt EV')
}); });
}); });