Skip to content

Commit

Permalink
prettier & lint
Browse files Browse the repository at this point in the history
  • Loading branch information
asednev committed Mar 11, 2021
1 parent 925b9e9 commit 1bce76f
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 80 deletions.
3 changes: 1 addition & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@
"dist"
],
"rules": {
"quotes": ["warn", "single"],
"quotes": ["warn", "double"],
"indent": ["warn", 2, { "SwitchCase": 1 }],
"linebreak-style": ["warn", "unix"],
"semi": ["warn", "always"],
"comma-dangle": ["warn", "always-multiline"],
"dot-notation": "off",
"eqeqeq": "warn",
"curly": ["warn", "all"],
Expand Down
8 changes: 4 additions & 4 deletions src/deviceContext.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export type DeviceContext = {
address: string,
model: string,
uuid: string
};
address: string;
model: string;
uuid: string;
};
8 changes: 4 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { API } from 'homebridge';
import { API } from "homebridge";

import { PLATFORM_NAME } from './settings';
import { GoveeHomebridgePlatform } from './platform';
import { PLATFORM_NAME } from "./settings";
import { GoveeHomebridgePlatform } from "./platform";

/**
* This method registers the platform with Homebridge
*/
export = (api: API) => {
api.registerPlatform(PLATFORM_NAME, GoveeHomebridgePlatform);
}
};
85 changes: 54 additions & 31 deletions src/platform.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import { API, DynamicPlatformPlugin, Logger, PlatformAccessory, PlatformConfig, Service, Characteristic } from 'homebridge';

import { PLATFORM_NAME, PLUGIN_NAME } from './settings';
import { GoveePlatformAccessory } from './platformAccessory';

import { startDiscovery, debug as GoveeDebug, GoveeReading } from 'govee-bt-client';
import { DeviceContext } from './deviceContext';
import {
API,
DynamicPlatformPlugin,
Logger,
PlatformAccessory,
PlatformConfig,
Service,
Characteristic,
} from "homebridge";

import { PLATFORM_NAME, PLUGIN_NAME } from "./settings";
import { GoveePlatformAccessory } from "./platformAccessory";

import {
startDiscovery,
debug as GoveeDebug,
GoveeReading,
} from "govee-bt-client";
import { DeviceContext } from "./deviceContext";

/**
* HomebridgePlatform
Expand All @@ -13,24 +25,25 @@ import { DeviceContext } from './deviceContext';
*/
export class GoveeHomebridgePlatform implements DynamicPlatformPlugin {
public readonly Service: typeof Service = this.api.hap.Service;
public readonly Characteristic: typeof Characteristic = this.api.hap.Characteristic;
public readonly Characteristic: typeof Characteristic = this.api.hap
.Characteristic;

// this is used to track restored cached accessories
public readonly accessories: PlatformAccessory[] = [];

constructor(
public readonly log: Logger,
public readonly config: PlatformConfig,
public readonly api: API,
public readonly api: API
) {
this.log.info('Finished initializing platform:', this.config.name);
this.log.info("Finished initializing platform:", this.config.name);

// When this event is fired it means Homebridge has restored all cached accessories from disk.
// Dynamic Platform plugins should only register new accessories after this event was fired,
// in order to ensure they weren't added to homebridge already. This event can also be used
// to start discovery of new accessories.
this.api.on('didFinishLaunching', () => {
log.debug('Executed didFinishLaunching callback');
this.api.on("didFinishLaunching", () => {
log.debug("Executed didFinishLaunching callback");
// run the method to discover / register your devices as accessories

this.discoverDevices();
Expand All @@ -42,7 +55,7 @@ export class GoveeHomebridgePlatform implements DynamicPlatformPlugin {
* It should be used to setup event handlers for characteristics and update respective values.
*/
configureAccessory(accessory: PlatformAccessory) {
this.log.info('Loading accessory from cache:', accessory.displayName);
this.log.info("Loading accessory from cache:", accessory.displayName);

// add the restored accessory to the accessories cache so we can track if it has already been registered
this.accessories.push(accessory);
Expand All @@ -54,8 +67,7 @@ export class GoveeHomebridgePlatform implements DynamicPlatformPlugin {
* must not be registered again to prevent "duplicate UUID" errors.
*/
discoverDevices() {

this.log.debug('Start discovery');
this.log.debug("Start discovery");

if (this.config.debug) {
GoveeDebug(true);
Expand All @@ -64,11 +76,10 @@ export class GoveeHomebridgePlatform implements DynamicPlatformPlugin {
const discoveryCache = new Map();

startDiscovery((reading: GoveeReading) => {

this.log.debug('Govee reading', reading);
this.log.debug("Govee reading", reading);

let deviceUniqueId = reading.uuid;
if (reading.model !== '') {
if (reading.model !== "") {
deviceUniqueId = reading.model;
}

Expand All @@ -81,18 +92,24 @@ export class GoveeHomebridgePlatform implements DynamicPlatformPlugin {

// see if an accessory with the same uuid has already been registered and restored from
// the cached devices we stored in the `configureAccessory` method above
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
const existingAccessory = this.accessories.find(
(accessory) => accessory.UUID === uuid
);

if (discoveryCache.has(uuid)) {
const cachedInstance = discoveryCache.get(uuid) as GoveePlatformAccessory;
const cachedInstance = discoveryCache.get(
uuid
) as GoveePlatformAccessory;
cachedInstance.updateReading(reading);
return;
}

if (existingAccessory) {

// the accessory already exists
this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);
this.log.info(
"Restoring existing accessory from cache:",
existingAccessory.displayName
);

// if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
existingAccessory.context.batteryThreshold = this.config.batteryThreshold;
Expand All @@ -101,16 +118,18 @@ export class GoveeHomebridgePlatform implements DynamicPlatformPlugin {

// create the accessory handler for the restored accessory
// this is imported from `platformAccessory.ts`
const existingInstance = new GoveePlatformAccessory(this, existingAccessory, reading);
const existingInstance = new GoveePlatformAccessory(
this,
existingAccessory,
reading
);

discoveryCache.set(uuid, existingInstance);

} else {

const displayName = `${this.sanitize(reading.model)}`;

// the accessory does not yet exist, so we need to create it
this.log.info('Adding new accessory:', displayName);
this.log.info("Adding new accessory:", displayName);

// create a new accessory
const accessory = new this.api.platformAccessory(displayName, uuid);
Expand All @@ -128,22 +147,26 @@ export class GoveeHomebridgePlatform implements DynamicPlatformPlugin {

// create the accessory handler for the newly create accessory
// this is imported from `platformAccessory.ts`
const newInstance = new GoveePlatformAccessory(this, accessory, reading);
const newInstance = new GoveePlatformAccessory(
this,
accessory,
reading
);

// link the accessory to your platform
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [
accessory,
]);

discoveryCache.set(uuid, newInstance);
}

});

// it is possible to remove platform accessories at any time using `api.unregisterPlatformAccessories`, eg.:
// this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);

}

private sanitize(s: string): string {
return s.trim().replace('_', '');
return s.trim().replace("_", "");
}
}
104 changes: 67 additions & 37 deletions src/platformAccessory.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { Service, PlatformAccessory, CharacteristicGetCallback } from 'homebridge';
import {
Service,
PlatformAccessory,
CharacteristicGetCallback,
} from "homebridge";

import { GoveeHomebridgePlatform } from './platform';
import { GoveeReading } from 'govee-bt-client';
import { DeviceContext } from './deviceContext';
import { GoveeHomebridgePlatform } from "./platform";
import { GoveeReading } from "govee-bt-client";
import { DeviceContext } from "./deviceContext";

/**
* Platform Accessory
* An instance of this class is created for each accessory your platform registers
* Each accessory may expose multiple services of different service types.
*/
export class GoveePlatformAccessory {

private LOW_BATTERY_THRESHOLD = 25;
private HUMIDITY_OFFSET = 0;

Expand All @@ -21,75 +24,102 @@ export class GoveePlatformAccessory {
constructor(
private readonly platform: GoveeHomebridgePlatform,
private readonly accessory: PlatformAccessory,
private readonly reading: GoveeReading,
private readonly reading: GoveeReading
) {
this.lastReading = reading;

if (!accessory.context.device) {
throw new Error('Missing device context');
throw new Error("Missing device context");
}

const deviceContext: DeviceContext = accessory.context.device;

if (accessory.context.batteryThreshold) {
this.LOW_BATTERY_THRESHOLD = accessory.context.batteryThreshold;
}
if (accessory.context.humidityOffset) {
this.HUMIDITY_OFFSET = accessory.context.humidityOffset;
}
// set accessory information
const accessoryInformationService = this.accessory.getService(this.platform.Service.AccessoryInformation);

accessoryInformationService?.setCharacteristic(this.platform.Characteristic.Manufacturer, 'Govee')
.setCharacteristic(this.platform.Characteristic.Model, deviceContext.model);

if (deviceContext.address && deviceContext.address !== '') {
accessoryInformationService?.setCharacteristic(this.platform.Characteristic.SerialNumber, deviceContext.address);
const accessoryInformationService = this.accessory.getService(
this.platform.Service.AccessoryInformation
);

accessoryInformationService
?.setCharacteristic(this.platform.Characteristic.Manufacturer, "Govee")
.setCharacteristic(
this.platform.Characteristic.Model,
deviceContext.model
);

if (deviceContext.address && deviceContext.address !== "") {
accessoryInformationService?.setCharacteristic(
this.platform.Characteristic.SerialNumber,
deviceContext.address
);
}

// get the HumiditySensor service if it exists, otherwise create a new HumiditySensor service
// you can create multiple services for each accessory
this.humiditySensor = this.accessory.getService(this.platform.Service.HumiditySensor)
|| this.accessory.addService(this.platform.Service.HumiditySensor);
this.humiditySensor.setCharacteristic(this.platform.Characteristic.Name, deviceContext.model);
this.humiditySensor =
this.accessory.getService(this.platform.Service.HumiditySensor) ||
this.accessory.addService(this.platform.Service.HumiditySensor);
this.humiditySensor.setCharacteristic(
this.platform.Characteristic.Name,
deviceContext.model
);
// each service must implement at-minimum the "required characteristics" for the given service type
// see https://developers.homebridge.io/#/service/Lightbulb

this.humiditySensor.getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity)
.on('get', this.getCurrentRelativeHumidity.bind(this));
this.humiditySensor.getCharacteristic(this.platform.Characteristic.StatusLowBattery)
.on('get', this.getStatusLowBattery.bind(this));

this.temperatureSensor = this.accessory.getService(this.platform.Service.TemperatureSensor)
|| this.accessory.addService(this.platform.Service.TemperatureSensor);

this.temperatureSensor.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
.on('get', this.getCurrentTemperature.bind(this));
this.temperatureSensor.getCharacteristic(this.platform.Characteristic.StatusLowBattery)
.on('get', this.getStatusLowBattery.bind(this));

this.humiditySensor
.getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity)
.on("get", this.getCurrentRelativeHumidity.bind(this));
this.humiditySensor
.getCharacteristic(this.platform.Characteristic.StatusLowBattery)
.on("get", this.getStatusLowBattery.bind(this));

this.temperatureSensor =
this.accessory.getService(this.platform.Service.TemperatureSensor) ||
this.accessory.addService(this.platform.Service.TemperatureSensor);

this.temperatureSensor
.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
.on("get", this.getCurrentTemperature.bind(this));
this.temperatureSensor
.getCharacteristic(this.platform.Characteristic.StatusLowBattery)
.on("get", this.getStatusLowBattery.bind(this));
}

getCurrentRelativeHumidity(callback: CharacteristicGetCallback) {
this.platform.log.debug('getCurrentRelativeHumidity', this.lastReading?.humidity, "offset", this.HUMIDITY_OFFSET);
this.platform.log.debug(
"getCurrentRelativeHumidity",
this.lastReading?.humidity,
"offset",
this.HUMIDITY_OFFSET
);
callback(null, this.lastReading?.humidity + this.HUMIDITY_OFFSET);
}

getStatusLowBattery(callback: CharacteristicGetCallback) {
this.platform.log.debug('getStatusLowBattery');
this.platform.log.debug("getStatusLowBattery");
callback(null, this.lastReading?.battery <= this.LOW_BATTERY_THRESHOLD);
}

getCurrentTemperature(callback: CharacteristicGetCallback) {
this.platform.log.debug('getCurrentTemperature', this.lastReading?.tempInC);
this.platform.log.debug("getCurrentTemperature", this.lastReading?.tempInC);
callback(null, this.lastReading?.tempInC);
}

updateReading(reading: GoveeReading) {
this.lastReading = reading;

this.humiditySensor.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, reading.humidity + this.HUMIDITY_OFFSET);
this.temperatureSensor.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, reading.tempInC);
this.humiditySensor.updateCharacteristic(
this.platform.Characteristic.CurrentRelativeHumidity,
reading.humidity + this.HUMIDITY_OFFSET
);
this.temperatureSensor.updateCharacteristic(
this.platform.Characteristic.CurrentTemperature,
reading.tempInC
);
}

}
4 changes: 2 additions & 2 deletions src/settings.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/**
* This is the name of the platform that users will use to register the plugin in the Homebridge config.json
*/
export const PLATFORM_NAME = 'GoveeHomebridgePlugin';
export const PLATFORM_NAME = "GoveeHomebridgePlugin";

/**
* This must match the name of your plugin as defined the package.json
*/
export const PLUGIN_NAME = 'homebridge-plugin-govee';
export const PLUGIN_NAME = "homebridge-plugin-govee";

0 comments on commit 1bce76f

Please sign in to comment.