Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add SR-ZG9002KR12-Pro SR-ZG9002KR12-Pro configure and use extend instead only fromZigbee #8427

Merged
merged 1 commit into from
Dec 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fix: add SR-ZG9002KR12-Pro SR-ZG9002KR12-Pro configure and use extend…
… instead only fromZigbee
  • Loading branch information
niracler committed Dec 3, 2024
commit 972707ad21aba9563ff8fe2fe7d41aa82ad0b96b
268 changes: 155 additions & 113 deletions src/devices/sunricher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,159 @@ function sunricherMinimumPWM(): ModernExtend {
};
}

function sunricherSRZG9002KR12Pro(): ModernExtend {
const cluster = 0xff03;

const fromZigbee: Fz.Converter[] = [
{
cluster: 0xff03,
type: ['raw'],
convert: (model, msg, publish, options, meta) => {
const bytes = [...msg.data];
const messageType = bytes[3];
let action = 'unknown';

if (messageType === 0x01) {
const pressTypeMask: number = bytes[6];
const pressTypeLookup: {[key: number]: string} = {
0x01: 'short_press',
0x02: 'double_press',
0x03: 'hold',
0x04: 'hold_released',
};
action = pressTypeLookup[pressTypeMask] || 'unknown';

const buttonMask = (bytes[4] << 8) | bytes[5];
const specialButtonMap: {[key: number]: string} = {
9: 'knob',
11: 'k9',
12: 'k10',
15: 'k11',
16: 'k12',
};

const actionButtons: string[] = [];
for (let i = 0; i < 16; i++) {
if ((buttonMask >> i) & 1) {
const button = i + 1;
actionButtons.push(specialButtonMap[button] ?? `k${button}`);
}
}
return {action, action_buttons: actionButtons};
} else if (messageType === 0x03) {
const directionMask = bytes[4];
const actionSpeed = bytes[6];

const directionMap: {[key: number]: string} = {
0x01: 'clockwise',
0x02: 'anti_clockwise',
};
const direction = directionMap[directionMask] || 'unknown';

action = `${direction}_rotation`;
return {action, action_speed: actionSpeed};
}

return {action};
},
},
];

const exposes: Expose[] = [e.action(['short_press', 'double_press', 'hold', 'hold_released', 'clockwise_rotation', 'anti_clockwise_rotation'])];

const configure: [Configure] = [
async (device, coordinatorEndpoint, definition) => {
const endpoint = device.getEndpoint(1);
await endpoint.bind(cluster, coordinatorEndpoint);
},
];

return {
fromZigbee,
exposes,
configure,
isModernExtend: true,
};
}

function sunricherSRZG2836D5Pro(): ModernExtend {
const cluster = 0xff03;

const fromZigbee: Fz.Converter[] = [
{
cluster: 0xff03,
type: ['raw'],
convert: (model, msg, publish, options, meta) => {
const bytes = [...msg.data];
const messageType = bytes[3];
let action = 'unknown';

if (messageType === 0x01) {
const pressTypeMask: number = bytes[6];
const pressTypeLookup: {[key: number]: string} = {
0x01: 'short_press',
0x02: 'double_press',
0x03: 'hold',
0x04: 'hold_released',
};
action = pressTypeLookup[pressTypeMask] || 'unknown';

const buttonMask = bytes[5];
const specialButtonLookup: {[key: number]: string} = {
0x01: 'top_left',
0x02: 'top_right',
0x03: 'bottom_left',
0x04: 'bottom_right',
0x05: 'center',
};

const actionButtons: string[] = [];
for (let i = 0; i < 5; i++) {
if ((buttonMask >> i) & 1) {
const button = i + 1;
actionButtons.push(specialButtonLookup[button] || `unknown_${button}`);
}
}
return {action, action_buttons: actionButtons};
} else if (messageType === 0x03) {
const directionMask = bytes[4];
const actionSpeed = bytes[6];
const isStop = bytes[5] === 0x02;

const directionMap: {[key: number]: string} = {
0x01: 'clockwise',
0x02: 'anti_clockwise',
};
const direction = isStop ? 'stop' : directionMap[directionMask] || 'unknown';

action = `${direction}_rotation`;
return {action, action_speed: actionSpeed};
}

return {action};
},
},
];

const exposes: Expose[] = [
e.action(['short_press', 'double_press', 'hold', 'hold_released', 'clockwise_rotation', 'anti_clockwise_rotation', 'stop_rotation']),
];

const configure: [Configure] = [
async (device, coordinatorEndpoint, definition) => {
const endpoint = device.getEndpoint(1);
await endpoint.bind(cluster, coordinatorEndpoint);
},
];

return {
fromZigbee,
exposes,
configure,
isModernExtend: true,
};
}

const fzLocal = {
sunricher_SRZGP2801K45C: {
cluster: 'greenPower',
Expand All @@ -196,111 +349,6 @@ const fzLocal = {
return {action: utils.getFromLookup(commandID, lookup)};
},
} satisfies Fz.Converter,
sunricher_SRZG9002KR12Pro: {
cluster: 0xff03,
type: ['raw'],
convert: (model, msg, publish, options, meta) => {
const bytes = [...msg.data];
const messageType = bytes[3];
let action = 'unknown';

if (messageType === 0x01) {
const pressTypeMask: number = bytes[6];
const pressTypeLookup: {[key: number]: string} = {
0x01: 'short_press',
0x02: 'double_press',
0x03: 'hold',
0x04: 'hold_released',
};
action = pressTypeLookup[pressTypeMask] || 'unknown';

const buttonMask = (bytes[4] << 8) | bytes[5];
const specialButtonMap: {[key: number]: string} = {
9: 'knob',
11: 'k9',
12: 'k10',
15: 'k11',
16: 'k12',
};

const actionButtons: string[] = [];
for (let i = 0; i < 16; i++) {
if ((buttonMask >> i) & 1) {
const button = i + 1;
actionButtons.push(specialButtonMap[button] ?? `k${button}`);
}
}
return {action, action_buttons: actionButtons};
} else if (messageType === 0x03) {
const directionMask = bytes[4];
const actionSpeed = bytes[6];

const directionMap: {[key: number]: string} = {
0x01: 'clockwise',
0x02: 'anti_clockwise',
};
const direction = directionMap[directionMask] || 'unknown';

action = `${direction}_rotation`;
return {action, action_speed: actionSpeed};
}

return {action};
},
} satisfies Fz.Converter,
sunricher_SRZG2836D5Pro: {
cluster: 0xff03,
type: ['raw'],
convert: (model, msg, publish, options, meta) => {
const bytes = [...msg.data];
const messageType = bytes[3];
let action = 'unknown';

if (messageType === 0x01) {
const pressTypeMask: number = bytes[6];
const pressTypeLookup: {[key: number]: string} = {
0x01: 'short_press',
0x02: 'double_press',
0x03: 'hold',
0x04: 'hold_released',
};
action = pressTypeLookup[pressTypeMask] || 'unknown';

const buttonMask = bytes[5];
const specialButtonLookup: {[key: number]: string} = {
0x01: 'top_left',
0x02: 'top_right',
0x03: 'bottom_left',
0x04: 'bottom_right',
0x05: 'center',
};

const actionButtons: string[] = [];
for (let i = 0; i < 5; i++) {
if ((buttonMask >> i) & 1) {
const button = i + 1;
actionButtons.push(specialButtonLookup[button] || `unknown_${button}`);
}
}
return {action, action_buttons: actionButtons};
} else if (messageType === 0x03) {
const directionMask = bytes[4];
const actionSpeed = bytes[6];
const isStop = bytes[5] === 0x02;

const directionMap: {[key: number]: string} = {
0x01: 'clockwise',
0x02: 'anti_clockwise',
};
const direction = isStop ? 'stop' : directionMap[directionMask] || 'unknown';

action = `${direction}_rotation`;
return {action, action_speed: actionSpeed};
}

return {action};
},
} satisfies Fz.Converter,
};

async function syncTime(endpoint: Zh.Endpoint) {
Expand All @@ -319,20 +367,14 @@ const definitions: DefinitionWithExtend[] = [
model: 'SR-ZG2836D5-Pro',
vendor: 'Sunricher',
description: 'Zigbee smart remote',
extend: [battery()],
fromZigbee: [fzLocal.sunricher_SRZG2836D5Pro],
exposes: [
e.action(['short_press', 'double_press', 'hold', 'hold_released', 'clockwise_rotation', 'anti_clockwise_rotation', 'stop_rotation']),
],
extend: [battery(), sunricherSRZG2836D5Pro()],
},
{
zigbeeModel: ['HK-ZRC-K12&RS-E'],
model: 'SR-ZG9002KR12-Pro',
vendor: 'Sunricher',
description: 'Zigbee smart wall panel remote',
extend: [battery()],
fromZigbee: [fzLocal.sunricher_SRZG9002KR12Pro],
exposes: [e.action(['short_press', 'double_press', 'hold', 'hold_released', 'clockwise_rotation', 'anti_clockwise_rotation'])],
extend: [battery(), sunricherSRZG9002KR12Pro()],
},
{
zigbeeModel: ['ZV9380A', 'ZG9380A'],
Expand Down
Loading