Skip to content

Commit

Permalink
feat(ignore): zcl: update ubisys hvacThermostat custom attributes (#835)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
sjorge committed Dec 23, 2023
1 parent 560f0ae commit ef198ee
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 75 deletions.
72 changes: 30 additions & 42 deletions src/zcl/definition/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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,
Expand Down
33 changes: 0 additions & 33 deletions test/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'});
Expand Down

0 comments on commit ef198ee

Please sign in to comment.