Skip to content

Commit

Permalink
feat(add): SR-ZG9030A-MW (#8509)
Browse files Browse the repository at this point in the history
  • Loading branch information
niracler authored Dec 24, 2024
1 parent ead17e1 commit 0a714e0
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 0 deletions.
196 changes: 196 additions & 0 deletions src/devices/sunricher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,20 @@ import {
commandsScenes,
deviceEndpoints,
electricityMeter,
enumLookup,
humidity,
iasZoneAlarm,
identify,
illuminance,
light,
numeric,
occupancy,
onOff,
temperature,
} from '../lib/modernExtend';
import * as reporting from '../lib/reporting';
import * as globalStore from '../lib/store';
import * as sunricher from '../lib/sunricher';
import {Configure, DefinitionWithExtend, Expose, Fz, ModernExtend, Tz, Zh} from '../lib/types';
import * as utils from '../lib/utils';

Expand Down Expand Up @@ -362,6 +365,195 @@ async function syncTime(endpoint: Zh.Endpoint) {
}

const definitions: DefinitionWithExtend[] = [
{
zigbeeModel: ['ZG9030A-MW'],
model: 'SR-ZG9030A-MW',
vendor: 'Sunricher',
description: 'Zigbee compatible ceiling mount occupancy sensor',
extend: [
numeric({
name: 'light_pwm_frequency',
cluster: 'genBasic',
attribute: {ID: 0x9001, type: 0x21},
valueMin: 0,
valueMax: 65535,
description: 'Light PWM frequency (0-65535, default: 3300)',
access: 'ALL',
}),
enumLookup({
name: 'brightness_curve',
cluster: 'genBasic',
attribute: {ID: 0x8806, type: 0x20},
lookup: {
linear: 0,
gamma_logistics_1_5: 0x0f,
gamma_logistics_1_8: 0x12,
},
description: 'Brightness curve (default: Linear)',
access: 'ALL',
}),
enumLookup({
name: 'start_up_on_off',
cluster: 'genOnOff',
attribute: {ID: 0x4003, type: 0x30},
lookup: {
last_state: 0xff,
on: 1,
off: 0,
},
description: 'Start up on/off (default: last_state)',
access: 'ALL',
}),
numeric({
name: 'motion_sensor_light_duration',
cluster: 'genBasic',
attribute: {ID: 0x8902, type: 0x21},
valueMin: 0,
valueMax: 65535,
unit: 's',
description: 'Motion sensor light duration (0s-65535s, default: 5s)',
access: 'ALL',
}),
numeric({
name: 'motion_sensor_light_sensitivity',
cluster: 'genBasic',
attribute: {ID: 0x8903, type: 0x21},
valueMin: 0,
valueMax: 255,
description: 'Motion sensor light sensitivity (0-255, default: 0)',
access: 'ALL',
}),
enumLookup({
name: 'motion_sensor_working_mode',
cluster: 'genBasic',
attribute: {ID: 0x8904, type: 0x20},
lookup: {
automatic: 0,
manual: 1,
},
description: 'Motion sensor working mode (default: Automatic)',
access: 'ALL',
}),
numeric({
name: 'motion_sensor_sensing_distance',
cluster: 'genBasic',
attribute: {ID: 0x8905, type: 0x20},
valueMin: 0,
valueMax: 15,
description: 'Motion sensor sensing distance (0-15, default: 1)',
access: 'ALL',
}),
enumLookup({
name: 'motion_sensor_microwave_switch',
cluster: 'genBasic',
attribute: {ID: 0x8906, type: 0x20},
lookup: {
on: 1,
off: 0,
},
description: 'Motion sensor microwave switch (default: On)',
access: 'ALL',
}),
enumLookup({
name: 'motion_sensor_onoff_broadcast',
cluster: 'genBasic',
attribute: {ID: 0x8907, type: 0x20},
lookup: {
on: 1,
off: 0,
},
description: 'Motion sensor on/off broadcast (default: On)',
access: 'ALL',
}),
enumLookup({
name: 'motion_sensor_light_state',
cluster: 'genBasic',
attribute: {ID: 0x890c, type: 0x20},
lookup: {
on: 1,
off: 0,
},
description: 'Motion sensor light state (default: On)',
access: 'ALL',
}),
numeric({
name: 'motion_sensor_in_pwm_brightness',
cluster: 'genBasic',
attribute: {ID: 0x8908, type: 0x21},
valueMin: 0,
valueMax: 1000,
unit: 'lux',
description: 'Motion sensor IN PWM brightness (0-1000 lux, default: 0)',
access: 'ALL',
}),
numeric({
name: 'motion_sensor_in_pwm_output',
cluster: 'genBasic',
attribute: {ID: 0x8909, type: 0x20},
valueMin: 0,
valueMax: 254,
description: 'Motion sensor IN PWM output (0-254, default: 254)',
access: 'ALL',
}),
numeric({
name: 'motion_sensor_leave_pwm_output',
cluster: 'genBasic',
attribute: {ID: 0x890a, type: 0x20},
valueMin: 0,
valueMax: 100,
unit: '%',
description: 'Motion sensor LEAVE PWM output (0%-100%, default: 0%)',
access: 'ALL',
}),
numeric({
name: 'motion_sensor_leave_delay',
cluster: 'genBasic',
attribute: {ID: 0x8901, type: 0x21},
valueMin: 0,
valueMax: 65535,
unit: 's',
description: 'Motion sensor LEAVE delay (0s-65535s, default: 0s)',
access: 'ALL',
}),
numeric({
name: 'motion_sensor_pwm_output_after_delay',
cluster: 'genBasic',
attribute: {ID: 0x890b, type: 0x20},
valueMin: 0,
valueMax: 100,
unit: '%',
description: 'Motion sensor PWM output after delay (0%-100%, default: 0%)',
access: 'ALL',
}),
numeric({
name: 'linear_error_ratio_coefficient_of_lux_measurement',
cluster: 'genBasic',
attribute: {ID: 0x890d, type: 0x21},
valueMin: 100,
valueMax: 10000,
description: 'Linear error ratio coefficient of LUX measurement (100‰-10000‰, default: 1000‰)',
access: 'ALL',
}),
numeric({
name: 'fixed_deviation_of_lux_measurement',
cluster: 'genBasic',
attribute: {ID: 0x890e, type: 0x29},
valueMin: -100,
valueMax: 100,
description: 'Fixed deviation of LUX measurement (-100~100, default: 0)',
access: 'ALL',
}),
deviceEndpoints({endpoints: {'1': 1, '2': 2, '3': 3}}),
light(),
occupancy(),
illuminance({endpointNames: ['3']}),
commandsOnOff(),
commandsLevelCtrl(),
],
meta: {multiEndpoint: true},
toZigbee: [sunricher.tz.setModel],
exposes: [e.enum('model', ea.SET, ['HK-DIM', 'ZG9030A-MW']).withDescription('Model of the device')],
},
{
zigbeeModel: ['HK-ZRC-K5&RS-E'],
model: 'SR-ZG2836D5-Pro',
Expand Down Expand Up @@ -708,6 +900,10 @@ const definitions: DefinitionWithExtend[] = [
description: 'LED dimmable driver',
extend: [light()],
whiteLabel: [{vendor: 'Yphix', model: '50208702'}],
toZigbee: [sunricher.tz.setModel],
// Some ZG9030A-MW devices were mistakenly set with the modelId HK-DIM during manufacturing.
// This allows users to update the modelId from HK-DIM to ZG9030A-MW to ensure proper device functionality.
exposes: [e.enum('model', ea.SET, ['HK-DIM', 'ZG9030A-MW']).withDescription('Model of the device')],
},
{
zigbeeModel: ['SR-ZG9040A-S'],
Expand Down
13 changes: 13 additions & 0 deletions src/lib/sunricher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {Tz} from './types';

const tz = {
setModel: {
key: ['model'],
convertSet: async (entity, key, value, meta) => {
await entity.write('genBasic', {modelId: value});
return {state: {model: value}};
},
} satisfies Tz.Converter,
};

export {tz};
4 changes: 4 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
removeExternalDefinitions,
} from '../src/index';
import {access as _access, enum as _enum, list as _list, composite, numeric, presets} from '../src/lib/exposes';
import * as sunricher from '../src/lib/sunricher';
import {tz} from '../src/lib/tuya';
import {getFromLookup, toNumber} from '../src/lib/utils';
import {COLORTEMP_RANGE_MISSING_ALLOWED} from './colortemp_range_missing_allowed';
Expand Down Expand Up @@ -421,6 +422,9 @@ describe('index.js', () => {
// tuya.tz.datapoints is generic, keys cannot be used to determine expose access
if (device.toZigbee.includes(tz.datapoints)) return;

// sunricher.tz.setModel is used to switch modelId for devices with conflicting modelId, skip expose access check
if (device.toZigbee.includes(sunricher.tz.setModel)) return;

const toCheck = [];
const expss = typeof device.exposes == 'function' ? device.exposes() : device.exposes;
for (const expose of expss) {
Expand Down

0 comments on commit 0a714e0

Please sign in to comment.