diff --git a/lib/property-transformer.js b/lib/property-transformer.js index 80a2ff1..e1690c4 100644 --- a/lib/property-transformer.js +++ b/lib/property-transformer.js @@ -6,6 +6,7 @@ const PROPERTY_VENDOR_CODES = { mode: 'Mod', temperatureUnit: 'TemUn', temperature: 'SetTem', + currentTemperature: 'TemSen', fanSpeed: 'WdSpd', air: 'Air', blow: 'Blo', @@ -19,6 +20,19 @@ const PROPERTY_VENDOR_CODES = { powerSave: 'SvSt', }; +const PROPERTY_OPTIONS = { + currentTemperature: { + readOnly: true, + fromVendorTransformer: function (value) { + // Temperature from the AC should be transformed by subtract 40 to get real temperature + // AC returns temperature+40. I believe it's because it has unsigned data type + // When TemSen=0 it means real temperature is -40 degrees + // @see https://github.com/ddenisyuk/homebridge-gree-heatercooler/blob/3979fc6dad9d1935c59c686eb1764a062246ee7c/index.js#L224-L226 + return value - 40; + }, + } +} + /** * Transforms device properties from vendor names to human friendly names and back * @private @@ -52,7 +66,10 @@ class PropertyTransformer { let ret = {}; for (let [property, value] of Object.entries(properties)) { const reversedProperty = this._reversedProperties[property]; - ret[reversedProperty] = this._reversedValues[reversedProperty][value] || value; + const transformValue = PROPERTY_OPTIONS[reversedProperty] + && PROPERTY_OPTIONS[reversedProperty].fromVendorTransformer || (v => v); + const reversedValue = this._reversedValues[reversedProperty][value] || value; + ret[reversedProperty] = transformValue(reversedValue); } return ret; } @@ -65,6 +82,10 @@ class PropertyTransformer { toVendor(properties) { let ret = {}; for (let [property, value] of Object.entries(properties)) { + const propertyOptions = PROPERTY_OPTIONS[property] || {}; + if (propertyOptions.readOnly) { + throw new Error(`Cannot set read-only property ${property}`) + } const vendorProperty = this._properties[property]; const values = this._values[property] || {}; ret[vendorProperty] = values[value] !== undefined ? values[value] : value; diff --git a/lib/property-value.js b/lib/property-value.js index c7b1a5b..c805f90 100644 --- a/lib/property-value.js +++ b/lib/property-value.js @@ -76,6 +76,7 @@ const PROPERTY_VALUE = { fahrenheit: 'fahrenheit' }, temperature: {}, + currentTemperature: {}, fanSpeed: { auto: 'auto', low: 'low', diff --git a/lib/property-vendor-value.js b/lib/property-vendor-value.js index 5bc489b..9dc23ec 100644 --- a/lib/property-vendor-value.js +++ b/lib/property-vendor-value.js @@ -77,6 +77,7 @@ const PROPERTY_VALUE = { fahrenheit: 1 }, temperature: {}, + currentTemperature: {}, fanSpeed: { auto: 0, low: 1, diff --git a/lib/property.js b/lib/property.js index 9bd2282..5f9e6c9 100644 --- a/lib/property.js +++ b/lib/property.js @@ -8,6 +8,7 @@ * @property {string} mode - Mode of operation * @property {string} temperatureUnit - Temperature unit (must be together with set temperature) * @property {string} temperature - Set temperature (must be together with temperature unit) + * @property {string} currentTemperature - Get current temperature from the internal (?) sensor (This value can not be set, only received) * @property {string} fanSpeed - Fan speed * @property {string} air - Fresh air valve * @property {string} blow - Keeps the fan running for a while after shutting down (also called "X-Fan", only usable in Dry and Cool mode) @@ -25,6 +26,7 @@ const PROPERTY = { mode: 'mode', temperatureUnit: 'temperatureUnit', temperature: 'temperature', + currentTemperature: 'currentTemperature', fanSpeed: 'fanSpeed', air: 'air', blow: 'blow', diff --git a/test/property-transformer-test.js b/test/property-transformer-test.js index d576c01..71eeddb 100644 --- a/test/property-transformer-test.js +++ b/test/property-transformer-test.js @@ -7,12 +7,14 @@ describe('PropertyTransformer', function () { const SUT = new PropertyTransformer(); const result = SUT.fromVendor({ Mod: 1, - SetTem: 25 + SetTem: 25, + TemSen: 67, }); assert.deepEqual(result, { mode: 'cool', - temperature: 25 + temperature: 25, + currentTemperature: 27 }); }); }); @@ -29,5 +31,16 @@ describe('PropertyTransformer', function () { SetTem: 25 }); }); + it('should not allow to change read-only property', function () { + const SUT = new PropertyTransformer(); + assert.throws(() => { + SUT.toVendor({ + currentTemperature: 30 + }) + }, { + name: 'Error', + message: 'Cannot set read-only property currentTemperature' + }); + }); }); });