diff --git a/config.schema.json b/config.schema.json index cfcff58..dfc4a72 100644 --- a/config.schema.json +++ b/config.schema.json @@ -22,8 +22,19 @@ "title": "Prefix Name", "description": "Prefix the name of each service with the name of the vehicle", "type": "boolean", - "required": false, "default": true + }, + "latitude": { + "title": "Latitude", + "type": "string", + "default": "", + "description": "Latitude of your Homelink device. Required to use Homelink." + }, + "longitude": { + "title": "Longitude", + "type": "string", + "default": "", + "description": "Longitude of your Homelink device. Required to use Homelink." } } } diff --git a/src/vehicle-services/defrost.ts b/src/vehicle-services/defrost.ts new file mode 100644 index 0000000..26ddc71 --- /dev/null +++ b/src/vehicle-services/defrost.ts @@ -0,0 +1,20 @@ +import { VehicleAccessory } from "../vehicle.js"; +import { BaseService } from "./base.js"; + +export class DefrostService extends BaseService { + constructor(parent: VehicleAccessory) { + super(parent, parent.platform.Service.Switch, "Defrost", "defrost"); + + const on = this.service + .getCharacteristic(this.parent.platform.Characteristic.On) + .onSet(async (value) => { + await this.parent.wakeUpAndWait() + .then(() => this.vehicle.set_preconditioning_max(value as boolean, false)) + .then(() => on.updateValue(value)); + }); + + this.parent.emitter.on("vehicle_data", (data) => { + on.updateValue(data.climate_state.defrost_mode > 0); + }); + } +} diff --git a/src/vehicle-services/homelink.ts b/src/vehicle-services/homelink.ts new file mode 100644 index 0000000..15ec39d --- /dev/null +++ b/src/vehicle-services/homelink.ts @@ -0,0 +1,26 @@ +import { VehicleAccessory } from "../vehicle.js"; +import { BaseService } from "./base.js"; + +export class HomelinkService extends BaseService { + constructor(parent: VehicleAccessory) { + super(parent, parent.platform.Service.GarageDoorOpener, "Homelink", "homelink"); + + const current = this.service + .getCharacteristic(this.parent.platform.Characteristic.CurrentDoorState); + + const target = this.service + .getCharacteristic(this.parent.platform.Characteristic.TargetDoorState) + .onSet(async (value) => { + if (value) { + target.updateValue(value); + await this.parent.wakeUpAndWait() + .then(() => this.vehicle.trigger_homelink(this.platform.config.latitude, this.platform.config.longitude)) + .then(() => { + current.updateValue(false); + target.updateValue(false); + }); + } + }); + + } +} diff --git a/src/vehicle-services/sentry.ts b/src/vehicle-services/sentry.ts new file mode 100644 index 0000000..dc98175 --- /dev/null +++ b/src/vehicle-services/sentry.ts @@ -0,0 +1,20 @@ +import { VehicleAccessory } from "../vehicle.js"; +import { BaseService } from "./base.js"; + +export class SentryService extends BaseService { + constructor(parent: VehicleAccessory) { + super(parent, parent.platform.Service.Switch, "Sentry", "sentry"); + + const on = this.service + .getCharacteristic(this.parent.platform.Characteristic.On) + .onSet(async (value) => { + await this.parent.wakeUpAndWait() + .then(() => this.vehicle.set_sentry_mode(value as boolean)) + .then(() => on.updateValue(value)); + }); + + this.parent.emitter.on("vehicle_data", (data) => { + on.updateValue(data.vehicle_state.sentry_mode); + }); + } +} diff --git a/src/vehicle-services/wake.ts b/src/vehicle-services/wake.ts new file mode 100644 index 0000000..eba0ef0 --- /dev/null +++ b/src/vehicle-services/wake.ts @@ -0,0 +1,20 @@ +import { VehicleAccessory } from "../vehicle.js"; +import { BaseService } from "./base.js"; + +export class WakeService extends BaseService { + constructor(parent: VehicleAccessory) { + super(parent, parent.platform.Service.Switch, "Awake", "wake"); + + const on = this.service + .getCharacteristic(this.parent.platform.Characteristic.On) + .onSet(async (value) => { + if (value) { + await this.parent.wakeUpAndWait().then(() => on.updateValue(value)); + } + }); + + this.parent.emitter.on("vehicle_data", (data) => { + on.updateValue(data.state === "online"); + }); + } +} diff --git a/src/vehicle.ts b/src/vehicle.ts index 4c4c91c..9ded7ba 100644 --- a/src/vehicle.ts +++ b/src/vehicle.ts @@ -19,9 +19,13 @@ import { ChargeLimitService } from "./vehicle-services/chargelimit.js"; import { ChargePortService } from "./vehicle-services/chargeport.js"; import { ChargeSwitchService } from "./vehicle-services/chargeswitch.js"; import { ClimateService } from "./vehicle-services/climate.js"; +import { DefrostService } from "./vehicle-services/defrost.js"; import { DoorService } from "./vehicle-services/door.js"; +import { HomelinkService } from "./vehicle-services/homelink.js"; import { AccessoryInformationService } from "./vehicle-services/information.js"; import { LockService } from "./vehicle-services/lock.js"; +import { SentryService } from "./vehicle-services/sentry.js"; +import { WakeService } from "./vehicle-services/wake.js"; import { WindowService } from "./vehicle-services/windows.js"; export type VehicleContext = { @@ -66,10 +70,18 @@ export class VehicleAccessory { new ChargeLimitService(this); new ChargePortService(this); new ChargeSwitchService(this); + new DefrostService(this); new DoorService(this, "front"); new DoorService(this, "rear"); + new HomelinkService(this); new LockService(this); + new SentryService(this); new WindowService(this); + new WakeService(this); + + if (this.platform.config.latitude && this.platform.config.longitude) { + // + } // Get data and schedule refresh