From ef198ee48ec953180075eabadd8c5d7bc79ce69f Mon Sep 17 00:00:00 2001 From: Jorge Schrauwen Date: Sat, 23 Dec 2023 08:37:52 +0100 Subject: [PATCH] feat(ignore): zcl: update ubisys hvacThermostat custom attributes (#835) * ubisys: move all ubisys hvacThermostat manufacture attributes under the hvacThermostat As of firmware 1.5.0 there is no conflict anymore, these are based on draft technical reference ubisys has send me. I noticed the manuSpecificUbisysHeatingRegulatorThermostat which was causing conflict before was also just the generic hvacThermostat cluster with the manufacturerCode set. These halve all been folded into hvacThermostat to be consistent with others like danfoss. * tests: manuSpecificUbisysHeatingRegulatorThermostat is no more, we are conflict free now * ubisys: move manuSpecificUbisysHeatingRegulatorLevelCtrl to levelCtrl Give manuSpecificUbisysHeatingRegulatorLevelCtrl the same treatment, there are no device with converters with these custom attributes at the moment. --- src/zcl/definition/cluster.ts | 72 +++++++++++++++-------------------- test/controller.test.ts | 33 ---------------- 2 files changed, 30 insertions(+), 75 deletions(-) diff --git a/src/zcl/definition/cluster.ts b/src/zcl/definition/cluster.ts index 9374bed83e..df5269d79d 100644 --- a/src/zcl/definition/cluster.ts +++ b/src/zcl/definition/cluster.ts @@ -535,7 +535,20 @@ const Cluster: { defaultMoveRate: {ID: 20, type: DataType.uint16}, startUpCurrentLevel: {ID: 16384, type: DataType.uint8}, elkoStartUpCurrentLevel: {ID: 0x4000, type: DataType.uint8, manufacturerCode: ManufacturerCode.ELKO}, - ubisysMinimumOnLevel: {ID: 0, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysMinimumOnLevel: {ID: 0x0000, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysValveType: {ID: 0x0001, type: DataType.bitmap8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysCyclePeriod: {ID: 0x0002, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysSeason: {ID: 0x0003, type: DataType.enum8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysBackupLevel: {ID: 0x0004, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysAlternateBackupLevel: {ID: 0x0005, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysLowerRange: {ID: 0x0006, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysUpperRange: {ID: 0x0007, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysPumpThresholdOn: {ID: 0x0008, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysPumpThresholdOff: {ID: 0x0009, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysHeatingDemandEnableThreshold: {ID: 0x000A, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysHeatingDemandDisableThreshold: {ID: 0x000B, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysCoolingDemandEnableThreshold: {ID: 0x000C, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysCoolingDemandDisableThreshold: {ID: 0x000D, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, }, commands: { moveToLevel: { @@ -2058,6 +2071,22 @@ const Cluster: { elkoLastMessageStatus: {ID: 0x0419, type: DataType.uint8}, fourNoksHysteresisHigh: {ID: 0x0101, type: DataType.uint16, manufacturerCode: ManufacturerCode._4_NOKS}, fourNoksHysteresisLow: {ID: 0x0102, type: DataType.uint16, manufacturerCode: ManufacturerCode._4_NOKS}, + ubisysClassBTemperatureOffset: {ID: 0x0000, type: DataType.int8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysReturnFlowTemperatureWeight: {ID: 0x0001, type: DataType.int8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysRawOutdoorTemperature: {ID: 0x0002, type: DataType.struct, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysRawLocalTemperatureA: {ID: 0x0003, type: DataType.struct, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysRawLocalTemperatureB: {ID: 0x0004, type: DataType.struct, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysRawForwardFlowTemperature: {ID: 0x0005, type: DataType.struct, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysRawReturnFlowTemperature: {ID: 0x0006, type: DataType.struct, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysInstalledExtensions: {ID: 0x0007, type: DataType.bitmap64, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysTemperatureOffset: {ID: 0x0010, type: DataType.int8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysDefaultOccupiedHeatingSetpoint: {ID: 0x0011, type: DataType.int16, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysVacationMode: {ID: 0x0012, type: DataType.boolean, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysRemoteTemperature: {ID: 0x0013, type: DataType.int16, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysRemoteTemperatureValidDuration: {ID: 0x0014, type: DataType.uint8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysProportionalGain: {ID: 0x0020, type: DataType.int16, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysProportionalShift: {ID: 0x0021, type: DataType.int8, manufacturerCode: ManufacturerCode.Ubisys}, + ubisysIntegralFactor: {ID: 0x0022, type: DataType.int16, manufacturerCode: ManufacturerCode.Ubisys}, }, commands: { setpointRaiseLower: { @@ -4285,47 +4314,6 @@ const Cluster: { commandsResponse: { } }, - manuSpecificUbisysHeatingRegulatorThermostat: { - ID: 0x0201, // = 513 - manufacturerCode: ManufacturerCode.Ubisys, - attributes: { - classBTemperatureOffset: {ID: 0x0000, type: DataType.int8}, - returnFlowTemperatureWeight: {ID: 0x0001, type: DataType.int8}, - rawOutdoorTemperature: {ID: 0x0002, type: DataType.struct}, - rawLocalTemperatureA: {ID: 0x0003, type: DataType.struct}, - rawLocalTemperatureB: {ID: 0x0004, type: DataType.struct}, - rawForwardFlowTemperature: {ID: 0x0005, type: DataType.struct}, - rawReturnFlowTemperature: {ID: 0x0006, type: DataType.struct}, - installedExtensions: {ID: 0x0007, type: DataType.bitmap64}, - }, - commands: { - }, - commandsResponse: { - } - }, - manuSpecificUbisysHeatingRegulatorLevelCtrl: { - ID: 8, - manufacturerCode: ManufacturerCode.Ubisys, - attributes: { - valveType: {ID: 0x0000, type: DataType.bitmap8}, - cyclePeriod: {ID: 0x0001, type: DataType.uint8}, - season: {ID: 0x0002, type: DataType.enum8}, - backupLevel: {ID: 0x0003, type: DataType.uint8}, - alternateBackupLevel: {ID: 0x0004, type: DataType.uint8}, - lowerRange: {ID: 0x0005, type: DataType.uint8}, - upperRange: {ID: 0x0006, type: DataType.uint8}, - pumpThresholdOn: {ID: 0x0007, type: DataType.uint8}, - pumpThresholdOff: {ID: 0x0008, type: DataType.uint8}, - heatingDemandEnableThreshold: {ID: 0x0009, type: DataType.uint8}, - heatingDemandDisableThreshold: {ID: 0x000A, type: DataType.uint8}, - coolingDemandEnableThreshold: {ID: 0x000B, type: DataType.uint8}, - coolingDemandDisableThreshold: {ID: 0x000C, type: DataType.uint8}, - }, - commands: { - }, - commandsResponse: { - } - }, manuSpecificLegrandDevices: { ID: 0xfc01, manufacturerCode: ManufacturerCode.LegrandNetatmo, diff --git a/test/controller.test.ts b/test/controller.test.ts index cd8888f2d6..8cbee6406f 100755 --- a/test/controller.test.ts +++ b/test/controller.test.ts @@ -2688,39 +2688,6 @@ describe('Controller', () => { expect(deepClone(call[3])).toStrictEqual({"Header":{"frameControl":{"reservedBits":0,"frameType":0,"direction":0,"disableDefaultResponse":true,"manufacturerSpecific":false},"transactionSequenceNumber":11,"manufacturerCode":null,"commandIdentifier":6},"Payload":[{"direction":0,"attrId":1,"dataType":32,"minRepIntval":1,"maxRepIntval":10,"repChange":1}],"Cluster":{"ID":1,"attributes":{"mainsVoltage":{"ID":0,"type":33,"name":"mainsVoltage"},"mainsFrequency":{"ID":1,"type":32,"name":"mainsFrequency"},"mainsAlarmMask":{"ID":16,"type":24,"name":"mainsAlarmMask"},"mainsVoltMinThres":{"ID":17,"type":33,"name":"mainsVoltMinThres"},"mainsVoltMaxThres":{"ID":18,"type":33,"name":"mainsVoltMaxThres"},"mainsVoltageDwellTripPoint":{"ID":19,"type":33,"name":"mainsVoltageDwellTripPoint"},"batteryVoltage":{"ID":32,"type":32,"name":"batteryVoltage"},"batteryPercentageRemaining":{"ID":33,"type":32,"name":"batteryPercentageRemaining"},"batteryManufacturer":{"ID":48,"type":66,"name":"batteryManufacturer"},"batterySize":{"ID":49,"type":48,"name":"batterySize"},"batteryAHrRating":{"ID":50,"type":33,"name":"batteryAHrRating"},"batteryQuantity":{"ID":51,"type":32,"name":"batteryQuantity"},"batteryRatedVoltage":{"ID":52,"type":32,"name":"batteryRatedVoltage"},"batteryAlarmMask":{"ID":53,"type":24,"name":"batteryAlarmMask"},"batteryVoltMinThres":{"ID":54,"type":32,"name":"batteryVoltMinThres"},"batteryVoltThres1":{"ID":55,"type":32,"name":"batteryVoltThres1"},"batteryVoltThres2":{"ID":56,"type":32,"name":"batteryVoltThres2"},"batteryVoltThres3":{"ID":57,"type":32,"name":"batteryVoltThres3"},"batteryPercentMinThres":{"ID":58,"type":32,"name":"batteryPercentMinThres"},"batteryPercentThres1":{"ID":59,"type":32,"name":"batteryPercentThres1"},"batteryPercentThres2":{"ID":60,"type":32,"name":"batteryPercentThres2"},"batteryPercentThres3":{"ID":61,"type":32,"name":"batteryPercentThres3"},"batteryAlarmState":{"ID":62,"type":27,"name":"batteryAlarmState"}},"name":"genPowerCfg","commands":{},"commandsResponse":{}},"Command":{"ID":6,"name":"configReport","parameters":[{"name":"direction","type":32},{"name":"attrId","type":33},{"name":"dataType","type":32,"conditions":[{"type":"directionEquals","value":0}]},{"name":"minRepIntval","type":33,"conditions":[{"type":"directionEquals","value":0}]},{"name":"maxRepIntval","type":33,"conditions":[{"type":"directionEquals","value":0}]},{"name":"repChange","type":1000,"conditions":[{"type":"directionEquals","value":0},{"type":"dataTypeValueTypeEquals","value":"ANALOG"}]},{"name":"timeout","type":33,"conditions":[{"type":"directionEquals","value":1}]}],"response":7}}); }); - it('Endpoint configure reporting for manufacturer specific cluster with cluster ID collision', async () => { - await controller.start(); - await mockAdapterEvents['deviceJoined']({networkAddress: 129, ieeeAddr: '0x129'}); - const device = controller.getDeviceByIeeeAddr('0x129'); - const endpoint = device.getEndpoint(1); - mocksendZclFrameToEndpoint.mockClear(); - await endpoint.configureReporting('manuSpecificUbisysHeatingRegulatorThermostat', [{ - attribute: 'classBTemperatureOffset', - minimumReportInterval: 1, - maximumReportInterval: 10, - reportableChange: 1, - }]) - - const call = mocksendZclFrameToEndpoint.mock.calls[0]; - expect(call[0]).toBe('0x129'); - expect(call[1]).toBe(129); - expect(call[2]).toBe(1) - expect(deepClone(call[3])).toStrictEqual({"Header":{"frameControl":{"reservedBits":0,"frameType":0,"direction":0,"disableDefaultResponse":true,"manufacturerSpecific":true},"transactionSequenceNumber":11,"manufacturerCode":4338,"commandIdentifier":6},"Payload":[{"direction":0,"attrId":0,"dataType":40,"minRepIntval":1,"maxRepIntval":10,"repChange":1}],"Cluster":{"ID":513,"attributes":{"classBTemperatureOffset":{"ID":0,"type":40,"name":"classBTemperatureOffset"},"returnFlowTemperatureWeight":{"ID":1,"type":40,"name":"returnFlowTemperatureWeight"},"rawOutdoorTemperature":{"ID":2,"type":76,"name":"rawOutdoorTemperature"},"rawLocalTemperatureA":{"ID":3,"type":76,"name":"rawLocalTemperatureA"},"rawLocalTemperatureB":{"ID":4,"type":76,"name":"rawLocalTemperatureB"},"rawForwardFlowTemperature":{"ID":5,"type":76,"name":"rawForwardFlowTemperature"},"rawReturnFlowTemperature":{"ID":6,"type":76,"name":"rawReturnFlowTemperature"},"installedExtensions":{"ID":7,"type":31,"name":"installedExtensions"}},"manufacturerCode":4338,"name":"manuSpecificUbisysHeatingRegulatorThermostat","commands":{},"commandsResponse":{}},"Command":{"ID":6,"name":"configReport","parameters":[{"name":"direction","type":32},{"name":"attrId","type":33},{"name":"dataType","type":32,"conditions":[{"type":"directionEquals","value":0}]},{"name":"minRepIntval","type":33,"conditions":[{"type":"directionEquals","value":0}]},{"name":"maxRepIntval","type":33,"conditions":[{"type":"directionEquals","value":0}]},{"name":"repChange","type":1000,"conditions":[{"type":"directionEquals","value":0},{"type":"dataTypeValueTypeEquals","value":"ANALOG"}]},{"name":"timeout","type":33,"conditions":[{"type":"directionEquals","value":1}]}],"response":7}}); - - await endpoint.configureReporting('hvacThermostat', [{ - attribute: 'localTemp', - minimumReportInterval: 1, - maximumReportInterval: 10, - reportableChange: 1, - }]) - - expect(endpoint.configuredReportings.length).toBe(2); - expect(endpoint.configuredReportings[0].attribute.name).toBe('classBTemperatureOffset'); - expect(endpoint.configuredReportings[0].cluster.name).toBe('manuSpecificUbisysHeatingRegulatorThermostat'); - expect(endpoint.configuredReportings[1].attribute.name).toBe('localTemp'); - expect(endpoint.configuredReportings[1].cluster.name).toBe('hvacThermostat'); - }); - it('Should replace legacy configured reportings without manufacturerCode', async () => { await controller.start(); await mockAdapterEvents['deviceJoined']({networkAddress: 129, ieeeAddr: '0x129'});