Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

system to make adding configuration easy #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@
"type": "string",
"required": true
},
"ignitionOnDuration": {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will always need to add any new configuration option to this file. This is what Homebridge uses to create the UI.

"title": "Ignition On Duration",
"type": "number",
"required": true,
"enum": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
]
},
"targetTemperature": {
"title": "Target Temperature (F)",
"type": "string",
Expand Down
5 changes: 3 additions & 2 deletions src/kiaconnect/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
HeatVentType,
LogInRequest,
LogInResponse,
OneToTen,
RemoteClimateRequest,
VehicleInfoList,
VehicleInfoResponse,
Expand Down Expand Up @@ -103,7 +104,7 @@ export class KiaConnect {
return res.data.header.xid;
}

async startClimate(vin: string, targetTempF: string): Promise<string> {
async startClimate(vin: string, targetTempF: string, ignitionOnDuration: OneToTen): Promise<string> {
await this.logIn({userId: this.userId, password: this.password});
const req: RemoteClimateRequest = {
action: 'ACTION_EXEC_REMOTE_CLIMATE_ON',
Expand All @@ -116,7 +117,7 @@ export class KiaConnect {
defrost: false,
ventilationWarning: false,
ignitionOnDuration: {
value: 10,
value: ignitionOnDuration,
unit: 4,
},
heatingAccessory: {
Expand Down
4 changes: 3 additions & 1 deletion src/kiaconnect/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ export enum HeatVentLevel {
Off = 1,
}

export type OneToTen = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;

export interface RemoteClimateRequest {
action: 'ACTION_EXEC_REMOTE_CLIMATE_ON';
remoteClimate: {
Expand All @@ -177,7 +179,7 @@ export interface RemoteClimateRequest {
defrost: boolean;
ventilationWarning: boolean;
ignitionOnDuration: {
value: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
value: OneToTen;
unit: 4;
};
heatingAccessory: {
Expand Down
23 changes: 21 additions & 2 deletions src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,16 @@ export class Platform implements DynamicPlatformPlugin {

// create the accessory handler for the restored accessory
// this is imported from `platformAccessory.ts`
new Car(this, existingAccessory, this.kiaConnect, car.name, car.vin, car.targetTemperature, car.refreshInterval);
new Car(
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will pass all other fields in the car object from the configuration to new Car. This will ensure that the Car class is receiving everything, it will just be up to us to interpret it.

this,
existingAccessory,
this.kiaConnect,
car.name,
car.vin,
{
...car,
},
);

// it is possible to remove platform accessories at any time using `api.unregisterPlatformAccessories`, eg.:
// remove platform accessories when no longer present
Expand All @@ -84,7 +93,17 @@ export class Platform implements DynamicPlatformPlugin {

// create the accessory handler for the newly create accessory
// this is imported from `platformAccessory.ts`
new Car(this, accessory, this.kiaConnect, car.name, car.vin, car.targetTemperature, car.refreshInterval);
new Car(
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here!

this,
accessory,
this.kiaConnect,
car.name,
car.vin,
{
targetTemperature: car.targetTemperature,
refreshInterval: car.refreshInterval,
},
);

// link the accessory to your platform
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
Expand Down
29 changes: 23 additions & 6 deletions src/platformAccessory.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';

import { Platform } from './platform';
import { VehicleInfoList } from './kiaconnect/types';
import { OneToTen, VehicleInfoList } from './kiaconnect/types';
import { KiaConnect } from './kiaconnect/client';

type CarConfig = {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a typed version of what we expect.

ignitionOnDuration: OneToTen; // in minutes
refreshInterval: number; // in milliseconds
targetTemperature: string; // in farenheit
};

type Door = {
id: string;
name: string;
Expand All @@ -25,16 +31,19 @@ export class Car {
private engine: Service;
private lock: Service;
private target: Target;
private config: CarConfig;

constructor(
private readonly platform: Platform,
private readonly accessory: PlatformAccessory,
private readonly kiaConnect: KiaConnect,
private readonly name: string,
private readonly vin: string,
private readonly targetTemperature: string,
private readonly refreshInterval: number,
config: Partial<CarConfig>,
) {
// Initialize config to default values
this.config = initializeConfig(config);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will take the input from the user specified config, and make sure every option is either set to the user provided value, or some default.


// target indicate where we want each value to be. These are sane defaults.
this.target = {
lockState: 0,
Expand Down Expand Up @@ -287,7 +296,7 @@ export class Car {
if (value) {
// Turn on the engine
this.platform.log.info('Turning on the engine');
xid = await this.kiaConnect.startClimate(this.vin, this.targetTemperature);
xid = await this.kiaConnect.startClimate(this.vin, this.config.targetTemperature, this.config.ignitionOnDuration);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use this.config anywhere where we would want a user-overidable value.

} else {
// Turn off the engine
this.platform.log.info('Turning off the engine');
Expand Down Expand Up @@ -316,14 +325,22 @@ export class Car {

private async startControlLoop() {
this.platform.log.info('Starting control loop', {
refreshInterval: this.refreshInterval,
refreshInterval: this.config.refreshInterval,
vin: this.vin,
});
this.refresh();
setInterval(this.refresh.bind(this), this.refreshInterval || 1000 * 60 * 60); // Every 1 hour
setInterval(this.refresh.bind(this), this.config.refreshInterval || 1000 * 60 * 60); // Every 1 hour
}
}

const initializeConfig = (config: Partial<CarConfig>): CarConfig => {
return {
ignitionOnDuration: config.ignitionOnDuration || 10,
refreshInterval: config.refreshInterval || 1000 * 60 * 60, // Every 1 hour
targetTemperature: config.targetTemperature || '72',
};
};

type VehicleInfo = {
areDoorsLocked: boolean;
areDoorsClosed: {
Expand Down
Loading