Skip to content

Commit

Permalink
Merge pull request #155 from BigThunderSR/add-mqtt-button-auto-discov…
Browse files Browse the repository at this point in the history
…ery-for-ha

Added MQTT Button Auto-Discovery for HA
  • Loading branch information
BigThunderSR authored Mar 27, 2024
2 parents b506e4b + 30422ed commit d626601
Show file tree
Hide file tree
Showing 6 changed files with 260 additions and 24 deletions.
3 changes: 1 addition & 2 deletions src/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,7 @@ class Commands {
}

async diagnostics({ diagnosticItem = [
Commands.CONSTANTS.DIAGNOSTICS.AMBIENT_AIR_TEMPERATURE,
Commands.CONSTANTS.DIAGNOSTICS.ENGINE_RPM,
Commands.CONSTANTS.DIAGNOSTICS.AMBIENT_AIR_TEMPERATURE,
Commands.CONSTANTS.DIAGNOSTICS.LAST_TRIP_DISTANCE,
Commands.CONSTANTS.DIAGNOSTICS.ODOMETER,
Commands.CONSTANTS.DIAGNOSTICS.TIRE_PRESSURE,
Expand Down
20 changes: 19 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const MQTT = require('./mqtt');
const Commands = require('./commands');
const logger = require('./logger');
const fs = require('fs');
//const Buttons = require('./buttons');
//const CircularJSON = require('circular-json');


Expand Down Expand Up @@ -516,6 +517,21 @@ logger.info('Starting OnStar2MQTT Polling');
const v = vehicle;
logger.info('Requesting diagnostics');
logger.debug(`GetSupported: ${v.getSupported()}`);

// Get supported commands
logger.info(`GetSupportedCommands: ${v.getSupportedCommands()}`);
// Get button configs and payloads
const { buttonConfigs, configPayloads } = mqttHA.createButtonConfigPayload(v);
// Publish button config and payload for each button
buttonConfigs.forEach((buttonConfig, index) => {
const configPayload = configPayloads[index];
logger.warn(`Button Config Topic: ${JSON.stringify(buttonConfig)}`);
logger.debug(`Button Config Payload: ${JSON.stringify(configPayload)}`);
// Publish configPayload as the payload to the respective MQTT topic
logger.debug(`Publishing Button Config: ${buttonConfig} Payload: ${JSON.stringify(configPayload)}`);
client.publish(buttonConfig, JSON.stringify(configPayload), { retain: true });
});

const statsRes = await commands.diagnostics({ diagnosticItem: v.getSupported() });
logger.info('Diagnostic request status', { status: _.get(statsRes, 'status') });
const stats = _.map(
Expand Down Expand Up @@ -559,10 +575,12 @@ logger.info('Starting OnStar2MQTT Polling');
client.publish(topic, JSON.stringify(state), { retain: true })
);
}

await Promise.all(publishes);
//client.publish(pollingStatusTopicState, JSON.stringify({"ok":{"message":"Data Polled Successfully"}}), {retain: false})

const completionTimestamp = new Date().toISOString();
logger.debug(`Completion Timestamp: ${completionTimestamp}`);
client.publish(pollingStatusTopicState, JSON.stringify({"ok":{"message":"Data Polled Successfully"}}), {retain: false});
client.publish(pollingStatusTopicState,
JSON.stringify({
"error": {
Expand Down
75 changes: 73 additions & 2 deletions src/mqtt.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const _ = require('lodash');
//const Buttons = require('./buttons');

/**
* Supports Home Assistant MQTT Discovery (https://www.home-assistant.io/docs/mqtt/discovery/)
Expand Down Expand Up @@ -44,6 +45,28 @@ const _ = require('lodash');
* }
*/
class MQTT {
static CONSTANTS = {
BUTTONS: {
Alert: 'alert',
AlertFlash: 'alertFlash',
AlertHonk: 'alertHonk',
CancelAlert: 'cancelAlert',
LockDoor: 'lockDoor',
UnlockDoor: 'unlockDoor',
LockTrunk: 'lockTrunk',
UnlockTrunk: 'unlockTrunk',
Start: 'start',
CancelStart: 'cancelStart',
GetLocation: 'getLocation',
Diagnostics: 'diagnostics',
EngineRPM: 'enginerpm',
ChargeOverride: 'chargeOverride',
CancelChargeOverride: 'cancelChargeOverride',
GetChargingProfile: 'getChargingProfile',
SetChargingProfile: 'setChargingProfile',
}
};

constructor(vehicle, prefix = 'homeassistant', namePrefix) {
this.prefix = prefix;
this.vehicle = vehicle;
Expand Down Expand Up @@ -114,6 +137,54 @@ class MQTT {
return `${this.prefix}/device_tracker/${this.instance}/config`;
}

//getButtonConfigTopic() {
// return `${this.prefix}/button/${this.instance}/${this.buttonName}/config`;
//}

createButtonConfigPayload(vehicle) {
const buttonInstances = [];
const buttonConfigs = [];
const configPayloads = [];

for (const buttonName in MQTT.CONSTANTS.BUTTONS) {
const buttonConfig = `${this.prefix}/button/${this.instance}/${MQTT.convertName(buttonName)}/config`;
const button = {
name: buttonName,
config: buttonConfig
};

button.vehicle = vehicle;
buttonInstances.push(button);

let unique_id = `${vehicle.vin}_Command_${button.name}`;
unique_id = unique_id.replace(/\s+/g, '-').toLowerCase();

configPayloads.push({
"device": {
"identifiers": [vehicle.vin],
"manufacturer": vehicle.make,
"model": vehicle.year + ' ' + vehicle.model,
"name": vehicle.toString()
},
"availability": {
"topic": this.getAvailabilityTopic(),
"payload_available": 'true',
"payload_not_available": 'false',
},
"unique_id": unique_id,
"name": `Command ${button.name}`,
"command_topic": this.getCommandTopic(),
"payload_press": JSON.stringify({ "command": MQTT.CONSTANTS.BUTTONS[button.name] }),
"qos": 2,
"enabled_by_default": false,
});

buttonConfigs.push(buttonConfig);
}

return { buttonInstances, buttonConfigs, configPayloads };
}

/**
*
* @param {DiagnosticElement} diag
Expand Down Expand Up @@ -189,7 +260,7 @@ class MQTT {
device: {
identifiers: [this.vehicle.vin],
manufacturer: this.vehicle.make,
model: this.vehicle.year,
model: this.vehicle.year + ' ' + this.vehicle.model,
name: this.vehicle.toString()
},
availability_topic: this.getAvailabilityTopic(),
Expand Down Expand Up @@ -299,4 +370,4 @@ class MQTT {
}
}

module.exports = MQTT;
module.exports = MQTT;
9 changes: 9 additions & 0 deletions src/vehicle.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class Vehicle {
);
this.supportedDiagnostics = _.get(diagCmd,
'commandData.supportedDiagnostics.supportedDiagnostic');

this.supportedCommands = _.get(vehicle, 'commands.command');
}

isSupported(diag) {
Expand All @@ -29,6 +31,13 @@ class Vehicle {
toString() {
return `${this.year} ${this.make} ${this.model}`;
}

getSupportedCommands(commandList = []) {
this.supportedCommands.forEach(command => {
commandList.push(command.name);
});
return commandList;
}
}

module.exports = Vehicle;
Loading

0 comments on commit d626601

Please sign in to comment.