This commit is contained in:
bennythebee 2023-02-28 22:05:50 -06:00
commit f7ab765650
9 changed files with 94 additions and 39 deletions

View File

@ -4,8 +4,8 @@ updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
interval: "monthly"
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
interval: "monthly"

View File

@ -16,7 +16,7 @@ jobs:
strategy:
matrix:
node-version: [12.x]
node-version: [18.x]
steps:
- name: Check out the repo
@ -53,9 +53,9 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Push to DockerHub
uses: docker/build-push-action@v3
uses: docker/build-push-action@v4
with:
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
labels: ${{ steps.docker_meta.outputs.labels }}

View File

@ -32,9 +32,9 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Push to DockerHub
uses: docker/build-push-action@v3
uses: docker/build-push-action@v4
with:
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
labels: ${{ steps.docker_meta.outputs.labels }}

2
.nvmrc
View File

@ -1 +1 @@
lts/erbium
lts/hydrogen

View File

@ -1,5 +1,42 @@
Sample configs for MQTT Home Assistant integration.
### Commands
#### example script yaml:
```yaml
alias: Car - Start Vehicle
sequence:
- service: mqtt.publish
data:
topic: homeassistant/YOUR_CAR_VIN/command
payload: '{"command": "startVehicle"}'
mode: single
icon: 'mdi:car-electric'
```
#### Triger precondition via calendar
````yaml
alias: Car Precondition
description: Precondition if group.family is home (ie, at least one person).
trigger:
- platform: state
entity_id: calendar.YOUR_CAL_NAME
from: 'off'
to: 'on'
condition:
- condition: state
entity_id: group.family
state: home
- condition: state
entity_id: calendar.YOUR_CAL_NAME
state: Bolt Start
attribute: message
action:
- service: script.car_start_vehicle
data: {}
mode: single
````
### Location
Unfortunately, the MQTT Device tracker uses a home/not_home state and the MQTT Json device tracker does not support
the discovery schema so a manual entity configuration is required.
@ -23,23 +60,21 @@ sequence:
mode: single
icon: 'mdi:map-marker'
```
### Lovelace Dashboard
Create a new dashboard, or use the cards in your own view. The `mdi:car-electric` icon works well here.
![lovelace screenshot](images/lovelace.png)
#### script yaml:
```yaml
alias: Car - Start Vehicle
sequence:
- service: mqtt.publish
data:
topic: homeassistant/YOUR_CAR_VIN/command
payload: '{"command": "startVehicle"}'
### Automation:
Create an automation to update the location whenever the odometer changes, instead of on a time interval.
```alias: Update EV Location
description: ""
trigger:
- platform: state
entity_id:
- sensor.odometer_mi
condition: []
action:
- service: script.locate_bolt_ev
data: {}
mode: single
icon: 'mdi:car-electric'
```
#### Commands:
[OnStarJS Command Docs](https://github.com/samrum/OnStarJS#commands)
1. `getAccountVehicles`
@ -53,6 +88,12 @@ icon: 'mdi:car-electric'
9. `cancelChargeOverride`
10. `getLocation`
### Lovelace Dashboard
Create a new dashboard, or use the cards in your own view. The `mdi:car-electric` icon works well here.
![lovelace screenshot](images/lovelace.png)
#### dashboard yaml:
```yaml
views:

View File

@ -13,7 +13,6 @@ Collect the following information:
4. MQTT server information: hostname, username, password
4a. If using TLS, define `MQTT_PORT` and `MQTT_TLS=true`
### Node.js
It's a typical node.js application, that uses .env variables to run. To install and run, follow the steps bellow.
```

2
package-lock.json generated
View File

@ -11445,4 +11445,4 @@
"dev": true
}
}
}
}

View File

@ -49,4 +49,4 @@
"mocha": "^10.2.0",
"nyc": "^15.1.0"
}
}
}

View File

@ -26,7 +26,9 @@ const onstarConfig = {
onStarPin: process.env.ONSTAR_PIN || ospin,
checkRequestStatus: process.env.ONSTAR_SYNC === "true" || true,
refreshInterval: parseInt(process.env.ONSTAR_REFRESH) || (30 * 60 * 1000), // 30 min
allowCommands: _.toLower(_.get(process, 'env.ONSTAR_ALLOW_COMMANDS', 'true')) === 'true'
requestPollingIntervalSeconds: parseInt(process.env.ONSTAR_POLL_INTERVAL) || 6, // 6 sec default
requestPollingTimeoutSeconds: parseInt(process.env.ONSTAR_POLL_TIMEOUT) || 60, // 60 sec default
allowCommands: _.get(process.env, 'ONSTAR_ALLOW_COMMANDS', 'true') === 'true'
};
logger.info('OnStar Config', {onstarConfig});
@ -90,20 +92,23 @@ const configureMQTT = async (commands, client, mqttHA) => {
return;
}
const commandFn = cmd.bind(commands);
logger.info('Command sent', {command});
logger.info('Command sent', { command });
commandFn(options || {})
.then(data => {
// TODO refactor the response handling for commands
logger.info('Command completed', {command});
const location = _.get(data, 'response.data.commandResponse.body.location');
if (data && location) {
logger.info('Command response data', {location});
const topic = mqttHA.getStateTopic({name: command});
// TODO create device_tracker entity. MQTT device tracker doesn't support lat/lon and mqtt_json
// doesn't have discovery
client.publish(topic,
JSON.stringify({latitude: location.lat, longitude: location.long}), {retain: true})
.then(() => logger.info('Published location to topic.', {topic}));
logger.info('Command completed', { command });
const responseData = _.get(data, 'response.data');
if (responseData) {
logger.info('Command response data', { responseData });
const location = _.get(data, 'response.data.commandResponse.body.location');
if (location) {
const topic = mqttHA.getStateTopic({ name: command });
// TODO create device_tracker entity. MQTT device tracker doesn't support lat/lon and mqtt_json
// doesn't have discovery
client.publish(topic,
JSON.stringify({ latitude: location.lat, longitude: location.long }), { retain: true })
.then(() => logger.info('Published location to topic.', { topic }));
}
}
})
.catch(err=> logger.error('Command error', {command, err}));
@ -178,7 +183,17 @@ const configureMQTT = async (commands, client, mqttHA) => {
const main = async () => run()
.then(() => logger.info('Updates complete, sleeping.'))
.catch(e => logger.error('Error', {error: e}))
.catch(e => {
if (e instanceof Error) {
logger.error('Error', {error: _.pick(e, [
'message', 'stack',
'response.status', 'response.statusText', 'response.headers', 'response.data',
'request.method', 'request.body', 'request.contentType', 'request.headers', 'request.url'
])});
} else {
logger.error('Error', {error: e});
}
});
await main();
setInterval(main, onstarConfig.refreshInterval);