Skip to content

Commit

Permalink
Merge pull request #337 from michikrug/pr-mired
Browse files Browse the repository at this point in the history
  • Loading branch information
michikrug authored Aug 12, 2022
2 parents 55f694c + 70b35cb commit 4cba21e
Show file tree
Hide file tree
Showing 12 changed files with 158 additions and 67 deletions.
8 changes: 4 additions & 4 deletions docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,17 @@ Dimmer { ga="Light" }
Color { ga="Light" [ colorTemperatureRange="2000,9000" ] }
```
#### `Light as Group with separate Color and Brightness`
#### `Light as Group with separate Controls`
| | |
|---|---|
| **Device Type** | [Light](https://developers.google.com/assistant/smarthome/guides/light) |
| **Supported Traits** | [OnOff](https://developers.google.com/assistant/smarthome/traits/onoff), [ColorSetting](https://developers.google.com/assistant/smarthome/traits/colorsetting), [Brightness](https://developers.google.com/assistant/smarthome/traits/brightness) |
| **Supported Items** | Group as `light` with the following members: (optional) Number or Dimmer as `lightBrightness`, (optional) Number or Dimmer as `lightColorTemperature`, (optional) Color as `lightColor`, (optional) Switch as `lightPower` |
| **Configuration** | (optional) `useKelvin=true/false`<br>(optional) `checkState=true/false`<br>(optional) `colorTemperatureRange="minK,maxK"`<br>_Hint: if you want to use `lightColorTemperature` you either need to set `useKelvin=true` or `colorTemperatureRange`_ |
| **Supported Items** | Group as `SpecialColorLight` with the following members: (optional) Number or Dimmer as `lightBrightness`, (optional) Number or Dimmer as `lightColorTemperature`, (optional) Color as `lightColor`, (optional) Switch as `lightPower` |
| **Configuration** | (optional) `colorUnit=percent/kelvin/mired`<br>(optional) `checkState=true/false`<br>(optional) `colorTemperatureRange="minK,maxK"`<br>_Hint: if you want to use `lightColorTemperature` you either need to set `colorUnit` to `kelvin` or `mired` or define a `colorTemperatureRange` as `colorUnit` defaults to `percent`_ |
```shell
Group lightGroup { ga="Light" [ useKelvin=true, colorTemperatureRange="2000,9000" ] }
Group lightGroup { ga="SpecialColorLight" [ colorUnit="kelvin", colorTemperatureRange="2000,9000" ] }
Switch powerItem (lightGroup) { ga="lightPower" }
Dimmer brightnessItem (lightGroup) { ga="lightBrightness" }
Color colorItem (lightGroup) { ga="lightColor" }
Expand Down
11 changes: 7 additions & 4 deletions functions/commands/colorabsolutetemperature.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const DefaultCommand = require('./default.js');
const SpecialColorLight = require('../devices/specialcolorlight.js');
const rgb2hsv = require('../utilities.js').rgb2hsv;
const kelvin2rgb = require('../utilities.js').kelvin2rgb;
const { convertMired, convertRgbToHsv, convertKelvinToRgb } = require('../utilities.js');

class ColorAbsoluteTemperature extends DefaultCommand {
static get type() {
Expand Down Expand Up @@ -35,9 +34,13 @@ class ColorAbsoluteTemperature extends DefaultCommand {
static convertParamsToValue(params, item, device) {
if (this.getDeviceType(device) === 'SpecialColorLight') {
try {
if (SpecialColorLight.useKelvin(item)) {
const colorUnit = SpecialColorLight.getColorUnit(item);
if (colorUnit === 'kelvin') {
return params.color.temperature.toString();
}
if (colorUnit === 'mired') {
return convertMired(params.color.temperature).toString();
}
const { temperatureMinK, temperatureMaxK } = SpecialColorLight.getAttributes(item).colorTemperatureRange;
return (
100 -
Expand All @@ -47,7 +50,7 @@ class ColorAbsoluteTemperature extends DefaultCommand {
return '0';
}
}
const hsv = rgb2hsv(kelvin2rgb(params.color.temperature));
const hsv = convertRgbToHsv(convertKelvinToRgb(params.color.temperature));
const hsvArray = item.state.split(',').map((val) => Number(val));
return [Math.round(hsv.hue * 100) / 100, Math.round(hsv.saturation * 1000) / 10, hsvArray[2]].join(',');
}
Expand Down
4 changes: 2 additions & 2 deletions functions/commands/thermostattemperaturesetpoint.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const DefaultCommand = require('./default.js');
const Thermostat = require('../devices/thermostat.js');
const convertToFahrenheit = require('../utilities.js').convertToFahrenheit;
const convertCelsiusToFahrenheit = require('../utilities.js').convertCelsiusToFahrenheit;

class ThermostatTemperatureSetpoint extends DefaultCommand {
static get type() {
Expand All @@ -26,7 +26,7 @@ class ThermostatTemperatureSetpoint extends DefaultCommand {
static convertParamsToValue(params, item) {
let value = params.thermostatTemperatureSetpoint;
if (Thermostat.useFahrenheit(item)) {
value = convertToFahrenheit(value);
value = convertCelsiusToFahrenheit(value);
}
return value.toString();
}
Expand Down
4 changes: 2 additions & 2 deletions functions/commands/thermostattemperaturesetpointhigh.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const DefaultCommand = require('./default.js');
const Thermostat = require('../devices/thermostat.js');
const convertToFahrenheit = require('../utilities.js').convertToFahrenheit;
const convertCelsiusToFahrenheit = require('../utilities.js').convertCelsiusToFahrenheit;

class ThermostatTemperatureSetpointHigh extends DefaultCommand {
static get type() {
Expand Down Expand Up @@ -28,7 +28,7 @@ class ThermostatTemperatureSetpointHigh extends DefaultCommand {
static convertParamsToValue(params, item) {
let value = params.thermostatTemperatureSetpointHigh;
if (Thermostat.useFahrenheit(item)) {
value = convertToFahrenheit(value);
value = convertCelsiusToFahrenheit(value);
}
return value.toString();
}
Expand Down
4 changes: 2 additions & 2 deletions functions/commands/thermostattemperaturesetpointlow.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const DefaultCommand = require('./default.js');
const Thermostat = require('../devices/thermostat.js');
const convertToFahrenheit = require('../utilities.js').convertToFahrenheit;
const convertCelsiusToFahrenheit = require('../utilities.js').convertCelsiusToFahrenheit;

class ThermostatTemperatureSetpointLow extends DefaultCommand {
static get type() {
Expand All @@ -26,7 +26,7 @@ class ThermostatTemperatureSetpointLow extends DefaultCommand {
static convertParamsToValue(params, item) {
let value = params.thermostatTemperatureSetpointLow;
if (Thermostat.useFahrenheit(item)) {
value = convertToFahrenheit(value);
value = convertCelsiusToFahrenheit(value);
}
return value.toString();
}
Expand Down
24 changes: 18 additions & 6 deletions functions/devices/specialcolorlight.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const DefaultDevice = require('./default.js');
const convertMired = require('../utilities.js').convertMired;

class SpecialColorLight extends DefaultDevice {
static get type() {
Expand All @@ -9,13 +10,17 @@ class SpecialColorLight extends DefaultDevice {
return ['action.devices.traits.OnOff', 'action.devices.traits.Brightness', 'action.devices.traits.ColorSetting'];
}

static isCompatible(item = {}) {
return item.metadata && item.metadata.ga && item.metadata.ga.value.toLowerCase() == 'specialcolorlight';
}

static matchesItemType(item) {
const members = this.getMembers(item);
return (
item.type === 'Group' &&
Object.keys(members).length > 1 &&
(!('lightColorTemperature' in members) ||
this.useKelvin(item) ||
this.getColorUnit(item) !== 'percent' ||
!!this.getAttributes(item).colorTemperatureRange)
);
}
Expand All @@ -30,9 +35,10 @@ class SpecialColorLight extends DefaultDevice {
if ('colorTemperatureRange' in config) {
const [min, max] = config.colorTemperatureRange.split(',').map((s) => Number(s.trim()));
if (!isNaN(min) && !isNaN(max)) {
const colorUnit = this.getColorUnit(item);
attributes.colorTemperatureRange = {
temperatureMinK: min,
temperatureMaxK: max
temperatureMinK: colorUnit === 'mired' ? convertMired(max) : min,
temperatureMaxK: colorUnit === 'mired' ? convertMired(min) : max
};
}
}
Expand Down Expand Up @@ -74,10 +80,15 @@ class SpecialColorLight extends DefaultDevice {
break;
}
try {
if (this.useKelvin(item)) {
const colorUnit = this.getColorUnit(item);
if (colorUnit === 'kelvin') {
state.color = {
temperatureK: Number(members[member].state)
};
} else if (colorUnit === 'mired') {
state.color = {
temperatureK: convertMired(Number(members[member].state))
};
} else {
const { temperatureMinK, temperatureMaxK } = this.getAttributes(item).colorTemperatureRange;
state.color = {
Expand Down Expand Up @@ -111,8 +122,9 @@ class SpecialColorLight extends DefaultDevice {
return members;
}

static useKelvin(item) {
return this.getConfig(item).useKelvin === true;
static getColorUnit(item) {
const colorUnit = this.getConfig(item).colorUnit || 'percent';
return colorUnit.toLowerCase();
}
}

Expand Down
4 changes: 2 additions & 2 deletions functions/devices/temperaturesensor.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const DefaultDevice = require('./default.js');
const convertToCelsius = require('../utilities.js').convertToCelsius;
const convertFahrenheitToCelsius = require('../utilities.js').convertFahrenheitToCelsius;

class TemperatureSensor extends DefaultDevice {
static get type() {
Expand Down Expand Up @@ -28,7 +28,7 @@ class TemperatureSensor extends DefaultDevice {
static getState(item) {
let state = Number(parseFloat(item.state).toFixed(1));
if (this.getConfig(item).useFahrenheit === true) {
state = convertToCelsius(state);
state = convertFahrenheitToCelsius(state);
}
return {
temperatureSetpointCelsius: state,
Expand Down
4 changes: 2 additions & 2 deletions functions/devices/thermostat.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const DefaultDevice = require('./default.js');
const convertToCelsius = require('../utilities.js').convertToCelsius;
const convertFahrenheitToCelsius = require('../utilities.js').convertFahrenheitToCelsius;

class Thermostat extends DefaultDevice {
static get type() {
Expand Down Expand Up @@ -50,7 +50,7 @@ class Thermostat extends DefaultDevice {
} else {
state[member] = Number(parseFloat(members[member].state).toFixed(1));
if (member.indexOf('Temperature') > 0 && this.useFahrenheit(item)) {
state[member] = convertToCelsius(state[member]);
state[member] = convertFahrenheitToCelsius(state[member]);
}
}
}
Expand Down
19 changes: 13 additions & 6 deletions functions/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,22 @@ module.exports = {
* @param {number} value temperature in Fahrenheit
* @returns {number} temperature value converted to Celsius
*/
convertToCelsius: (value) => {
convertFahrenheitToCelsius: (value) => {
return Number((((value - 32) * 5) / 9).toFixed(1));
},
/**
* @param {number} value temperature in Celsius
* @returns {number} temperature value converted to Fahrenheit
*/
convertToFahrenheit: (value) => {
convertCelsiusToFahrenheit: (value) => {
return Math.round((value * 9) / 5 + 32);
},
/**
* @param {number} kelvin color temperature as Kelvin
* @param {number} value color temperature as Kelvin
* @returns {object} color temperature value converted to RGB
*/
kelvin2rgb: (kelvin) => {
const temp = kelvin / 100;
convertKelvinToRgb: (value) => {
const temp = value / 100;
const r = temp <= 66 ? 255 : 329.698727446 * Math.pow(temp - 60, -0.1332047592);
const g =
temp <= 66
Expand All @@ -51,11 +51,18 @@ module.exports = {
b: b < 0 ? 0 : b > 255 ? 255 : Math.round(b)
};
},
/**
* @param {number} value color temperature as Kelvin or Mired
* @returns {number} color temperature value converted to Mired or Kelvin
*/
convertMired: (value) => {
return Math.round(Math.pow(10, 6) / value);
},
/**
* @param {object} rgb color as RGB
* @returns {object} color value converted to HSV
*/
rgb2hsv: ({ r, g, b }) => {
convertRgbToHsv: ({ r, g, b }) => {
r = r / 255;
g = g / 255;
b = b / 255;
Expand Down
16 changes: 15 additions & 1 deletion tests/commands/colorabsolutetemperature.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,28 @@ describe('ColorAbsoluteTemperature Command', () => {
metadata: {
ga: {
config: {
useKelvin: true
colorUnit: 'kelvin'
}
}
}
};
const device = { customData: { deviceType: 'SpecialColorLight' } };
expect(Command.convertParamsToValue(params, item, device)).toBe('2000');
});

test('convertParamsToValue SpecialColorLight Mired', () => {
const item = {
metadata: {
ga: {
config: {
colorUnit: 'mired'
}
}
}
};
const device = { customData: { deviceType: 'SpecialColorLight' } };
expect(Command.convertParamsToValue(params, item, device)).toBe('500');
});
});

test('getResponseStates', () => {
Expand Down
Loading

0 comments on commit 4cba21e

Please sign in to comment.