Skip to content

Commit 3d98d3f

Browse files
authored
feat: Add illuminance_raw (#8592)
1 parent f913273 commit 3d98d3f

31 files changed

+200
-328
lines changed

scripts/modernExtendRefactor.ts

+29-104
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// In the root of this repo, execute: `npx ts-node scripts/modernExtendRefactor.ts`
2+
13
import {Project, QuoteKind, SyntaxKind} from 'ts-morph';
24

35
const project = new Project({
@@ -15,9 +17,12 @@ project.getSourceFiles().forEach((sourceFile) => {
1517
if (sourceFile.getBaseName() === 'index.ts') return;
1618
console.log(`Handling ${sourceFile.getBaseName()}`);
1719

20+
if (sourceFile.getBaseName().includes('philips')) {
21+
return;
22+
}
23+
1824
let changed = true;
1925
let save = false;
20-
const type = 'mullerLichtLight';
2126
while (changed) {
2227
changed = false;
2328
const definitions = sourceFile.getVariableStatementOrThrow('definitions').getDescendantsOfKind(SyntaxKind.ObjectLiteralExpression);
@@ -27,99 +32,31 @@ project.getSourceFiles().forEach((sourceFile) => {
2732
const childs = definition.getChildrenOfKind(SyntaxKind.PropertyAssignment);
2833
const model = childs.find((c) => c.getFirstChildByKind(SyntaxKind.Identifier)?.getText() === 'model');
2934
const extend = childs.find((c) => c.getFirstChildByKind(SyntaxKind.Identifier)?.getText() === 'extend');
30-
// const exposes = childs.find((c) => c.getFirstChildByKind(SyntaxKind.Identifier)?.getText() === 'exposes');
31-
// const configure = childs.find((c) => c.getFirstChildByKind(SyntaxKind.Identifier)?.getText() === 'configure');
35+
const extendArray = extend?.getFirstChildByKind(SyntaxKind.ArrayLiteralExpression);
36+
const exposes = childs.find((c) => c.getFirstChildByKind(SyntaxKind.Identifier)?.getText() === 'exposes');
37+
const exposesArray = exposes?.getFirstChildByKind(SyntaxKind.ArrayLiteralExpression);
38+
const configure = childs.find((c) => c.getFirstChildByKind(SyntaxKind.Identifier)?.getText() === 'configure');
3239
const fromZigbee = childs.find((c) => c.getFirstChildByKind(SyntaxKind.Identifier)?.getText() === 'fromZigbee');
40+
const fromZigbeeArray = fromZigbee?.getFirstChildByKind(SyntaxKind.ArrayLiteralExpression);
3341
const toZigbee = childs.find((c) => c.getFirstChildByKind(SyntaxKind.Identifier)?.getText() === 'toZigbee');
34-
// const meta = childs.find((c) => c.getFirstChildByKind(SyntaxKind.Identifier)?.getText() === 'meta');
35-
// const endpoint = childs.find((c) => c.getFirstChildByKind(SyntaxKind.Identifier)?.getText() === 'endpoint');
36-
37-
// const ota = childs.find((c) => c.getFirstChildByKind(SyntaxKind.Identifier)?.getText() === 'ota');
3842

39-
if (extend?.getFullText().includes('extend.light_onoff') && !fromZigbee && toZigbee?.getFullText().includes('tint_scene')) {
40-
console.log(`Handling ${model?.getFullText().trim()}`);
41-
toZigbee?.remove();
42-
const newOpts: {[s: string]: unknown} = {}; // {endpoints: eval(`(${endpoint.getFullText().split('return ')[1].split(';')[0]})`)};
43-
// configure?.remove();
44-
// endpoint?.remove();
45-
const extendFeatures = extend.getFullText().split('(')[0].split('_');
46-
if (extendFeatures.includes('colortemp')) {
47-
newOpts.colorTemp = {range: null};
48-
}
49-
if (extendFeatures.includes('color')) {
50-
newOpts.color = true;
51-
}
52-
if (extendFeatures.includes('gradient')) {
53-
newOpts.gradient = true;
54-
}
55-
let opts = extend?.getFullText().split('(')[1].slice(0, -1).trim();
56-
if (opts) {
57-
if (opts[opts.length - 1] === ',') {
58-
opts = opts.substring(0, opts.length - 1);
59-
}
60-
const evalOpts = Object.entries(eval(`(${opts})`));
61-
for (const [key, value] of evalOpts) {
62-
if (key === 'colorTempRange') {
63-
newOpts.colorTemp = {...(newOpts.colorTemp as object), range: value};
64-
} else if (key === 'disableColorTempStartup') {
65-
// @ts-expect-error ignore
66-
newOpts.colorTemp = {...newOpts.colorTemp, startup: !value};
67-
} else if (key === 'disablePowerOnBehavior') {
68-
newOpts.powerOnBehavior = !value;
69-
} else if (key === 'disableEffect') {
70-
newOpts.effect = !value;
71-
} else if (key === 'disableHueEffects') {
72-
newOpts.hueEffect = !value;
73-
} else if (key === 'supportsHueAndSaturation' || key === 'preferHueAndSaturation') {
74-
// @ts-expect-error ignore
75-
newOpts.color = {...newOpts.color, modes: evalOpts.preferHueAndSaturation ? ['hs', 'xy'] : ['xy', 'hs']};
76-
} else if (key === 'extraEffects') {
77-
// @ts-expect-error ignore
78-
newOpts.gradient = {...newOpts.gradient, extraEffects: value};
79-
} else if (key === 'noConfigure') {
80-
// ignore
81-
} else {
82-
throw new Error(`Unsupported ${key} - ${value}`);
83-
}
84-
}
43+
const fzIlluminance = fromZigbeeArray?.getElements().find((el) => el.getText() === 'fz.illuminance');
44+
if (fzIlluminance) {
45+
fromZigbeeArray?.removeElement(fzIlluminance);
46+
const exposesIlluminance = exposesArray?.getElements().find((el) => el.getText() === 'e.illuminance()');
47+
if (exposesIlluminance) {
48+
exposesArray?.removeElement(exposesIlluminance);
8549
}
86-
// if (meta) {
87-
// for (const [key, value] of Object.entries(eval(`(${meta?.getFullText().replace('meta: ', '')})`))) {
88-
// if (key === 'turnsOffAtBrightness1') {
89-
// newOpts.turnsOffAtBrightness1 = value;
90-
// } else if (key === 'applyRedFix') {
91-
// // @ts-expect-error ignore
92-
// newOpts.color = {...newOpts.color, applyRedFix: value};
93-
// } else if (key === 'supportsEnhancedHue') {
94-
// // @ts-expect-error ignore
95-
// newOpts.color = {...newOpts.color, enhancedHue: value};
96-
// } else if (key === 'multiEndpoint' || key === 'disableDefaultResponse') {
97-
// // ignore
98-
// } else {
99-
// throw new Error(`Unsupported ${key} - ${value}`);
100-
// }
101-
// }
102-
// // meta.remove();
103-
// }
104-
// if (ota) {
105-
// ota.remove();
106-
// }
10750

108-
localTotalDefinitionsWithModernExtend += 1;
109-
extend.replaceWithText(
110-
`extend: [${type}(${JSON.stringify(newOpts)
111-
.split(`"`)
112-
.join('')
113-
.replace(`range:null`, `range:undefined`)
114-
.replace(`xy`, `'xy'`)
115-
.replace(`hs`, `'hs'`)
116-
.replace(`({})`, `()`)})]`,
117-
);
118-
changed = true;
51+
if (!extend) {
52+
definition.addPropertyAssignment({
53+
name: 'extend',
54+
initializer: '[m.illuminance()]',
55+
});
56+
} else {
57+
extendArray?.addElement('m.illuminance()');
58+
}
11959
save = true;
120-
break;
121-
} else if (extend?.getFirstChildByKind(SyntaxKind.ArrayLiteralExpression)) {
122-
localTotalDefinitionsWithModernExtend += 1;
12360
}
12461
}
12562

@@ -130,22 +67,10 @@ project.getSourceFiles().forEach((sourceFile) => {
13067
}
13168

13269
if (save) {
133-
const modernExtendImport = sourceFile
134-
.getImportDeclarations()
135-
.find((d) => d.getModuleSpecifierSourceFile()?.getBaseName() === 'modernExtend.ts');
136-
if (!modernExtendImport) {
137-
sourceFile.addImportDeclaration({moduleSpecifier: '../lib/modernExtend', namedImports: [type]});
138-
} else {
139-
if (!modernExtendImport.getNamedImports().find((i) => i.getName() === type)) {
140-
modernExtendImport.addNamedImport(type);
141-
}
142-
}
143-
144-
const extendImport = sourceFile.getImportDeclarations().find((d) => d.getModuleSpecifierSourceFile()?.getBaseName() === 'extend.ts');
145-
if (!sourceFile.getFullText().includes('extend.') && extendImport) {
146-
extendImport.remove();
147-
}
148-
70+
sourceFile.addImportDeclaration({
71+
moduleSpecifier: '../lib/modernExtend',
72+
namespaceImport: 'm',
73+
});
14974
sourceFile.saveSync();
15075
}
15176
});

src/converters/fromZigbee.ts

-9
Original file line numberDiff line numberDiff line change
@@ -485,15 +485,6 @@ const converters1 = {
485485
return {soil_moisture: soilMoisture};
486486
},
487487
} satisfies Fz.Converter,
488-
illuminance: {
489-
cluster: 'msIlluminanceMeasurement',
490-
type: ['attributeReport', 'readResponse'],
491-
convert: (model, msg, publish, options, meta) => {
492-
const illuminance = msg.data['measuredValue'];
493-
const illuminanceLux = illuminance === 0 ? 0 : Math.pow(10, (illuminance - 1) / 10000);
494-
return {illuminance: illuminanceLux};
495-
},
496-
} satisfies Fz.Converter,
497488
pressure: {
498489
cluster: 'msPressureMeasurement',
499490
type: ['attributeReport', 'readResponse'],

src/converters/toZigbee.ts

-6
Original file line numberDiff line numberDiff line change
@@ -1893,12 +1893,6 @@ const converters2 = {
18931893
await entity.read('msRelativeHumidity', ['measuredValue']);
18941894
},
18951895
} satisfies Tz.Converter,
1896-
illuminance: {
1897-
key: ['illuminance'],
1898-
convertGet: async (entity, key, meta) => {
1899-
await entity.read('msIlluminanceMeasurement', ['measuredValue']);
1900-
},
1901-
} satisfies Tz.Converter,
19021896
// #endregion
19031897

19041898
// #region Non-generic converters

src/devices/aurora_lighting.ts

+4-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import fz from '../converters/fromZigbee';
22
import tz from '../converters/toZigbee';
33
import * as exposes from '../lib/exposes';
44
import {identify, light} from '../lib/modernExtend';
5+
import * as m from '../lib/modernExtend';
56
import * as reporting from '../lib/reporting';
67
import {Configure, DefinitionWithExtend, Fz, OnEvent, Tz, Zh} from '../lib/types';
78
import * as utils from '../lib/utils';
@@ -176,14 +177,9 @@ const definitions: DefinitionWithExtend[] = [
176177
model: 'AU-A1ZBPIRS',
177178
vendor: 'Aurora Lighting',
178179
description: 'AOne PIR sensor',
179-
fromZigbee: [fz.ias_occupancy_alarm_1, fz.illuminance],
180-
toZigbee: [],
181-
configure: async (device, coordinatorEndpoint) => {
182-
const endpoint = device.getEndpoint(39);
183-
await reporting.bind(endpoint, coordinatorEndpoint, ['msIlluminanceMeasurement']);
184-
await reporting.illuminance(endpoint);
185-
},
186-
exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.illuminance()],
180+
fromZigbee: [fz.ias_occupancy_alarm_1],
181+
exposes: [e.occupancy(), e.battery_low(), e.tamper()],
182+
extend: [m.illuminance()],
187183
},
188184
{
189185
zigbeeModel: ['SingleSocket50AU'],

src/devices/bosch.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
onOff,
2222
quirkCheckinInterval,
2323
} from '../lib/modernExtend';
24+
import * as m from '../lib/modernExtend';
2425
import * as reporting from '../lib/reporting';
2526
import * as globalStore from '../lib/store';
2627
import {DefinitionWithExtend, Expose, Fz, KeyValue, ModernExtend, Tz} from '../lib/types';
@@ -1321,17 +1322,17 @@ const definitions: DefinitionWithExtend[] = [
13211322
model: 'RADON TriTech ZB',
13221323
vendor: 'Bosch',
13231324
description: 'Wireless motion detector',
1324-
fromZigbee: [fz.temperature, fz.battery, fz.ias_occupancy_alarm_1, fz.illuminance],
1325+
fromZigbee: [fz.temperature, fz.battery, fz.ias_occupancy_alarm_1],
13251326
toZigbee: [],
13261327
meta: {battery: {voltageToPercentage: {min: 2500, max: 3000}}},
13271328
configure: async (device, coordinatorEndpoint) => {
13281329
const endpoint = device.getEndpoint(1);
1329-
await reporting.bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement', 'genPowerCfg', 'msIlluminanceMeasurement']);
1330+
await reporting.bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement', 'genPowerCfg']);
13301331
await reporting.temperature(endpoint);
13311332
await reporting.batteryVoltage(endpoint);
1332-
await reporting.illuminance(endpoint);
13331333
},
1334-
exposes: [e.temperature(), e.battery(), e.occupancy(), e.battery_low(), e.tamper(), e.illuminance()],
1334+
exposes: [e.temperature(), e.battery(), e.occupancy(), e.battery_low(), e.tamper()],
1335+
extend: [m.illuminance()],
13351336
},
13361337
{
13371338
zigbeeModel: ['ISW-ZPR1-WP13'],

src/devices/ctm.ts

+8-28
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import tz from '../converters/toZigbee';
55
import * as constants from '../lib/constants';
66
import * as exposes from '../lib/exposes';
77
import {battery, identify, light, temperature} from '../lib/modernExtend';
8+
import * as m from '../lib/modernExtend';
89
import * as reporting from '../lib/reporting';
910
import {DefinitionWithExtend, Fz, KeyValue, Tz} from '../lib/types';
1011
import * as utils from '../lib/utils';
@@ -1255,17 +1256,15 @@ const definitions: DefinitionWithExtend[] = [
12551256
model: 'MBD-S',
12561257
vendor: 'CTM Lyng',
12571258
description: 'MBD-S, motion detector with 16A relay',
1258-
fromZigbee: [fz.illuminance, fz.occupancy, fzLocal.ctm_mbd_device_enabled, fzLocal.ctm_relay_state],
1259+
fromZigbee: [fz.occupancy, fzLocal.ctm_mbd_device_enabled, fzLocal.ctm_relay_state],
12591260
toZigbee: [tzLocal.ctm_mbd_device_enabled, tzLocal.ctm_relay_state],
12601261
meta: {disableDefaultResponse: true},
12611262
ota: true,
12621263
configure: async (device, coordinatorEndpoint) => {
12631264
const endpoint = device.getEndpoint(1);
1264-
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'msIlluminanceMeasurement', 'msOccupancySensing']);
1265+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'msOccupancySensing']);
12651266
await endpoint.read('genOnOff', ['onOff']);
12661267
await reporting.onOff(endpoint);
1267-
await endpoint.read('msIlluminanceMeasurement', ['measuredValue']);
1268-
await reporting.illuminance(endpoint);
12691268
await endpoint.read('msOccupancySensing', ['occupancy']);
12701269
await reporting.occupancy(endpoint);
12711270
// Relay State
@@ -1283,37 +1282,20 @@ const definitions: DefinitionWithExtend[] = [
12831282
{manufacturerCode: Zcl.ManufacturerCode.DATEK_WIRELESS_AS},
12841283
);
12851284
},
1286-
exposes: [
1287-
e.switch(),
1288-
e.illuminance(),
1289-
e.occupancy(),
1290-
e.binary('device_enabled', ea.ALL, 'ON', 'OFF').withDescription('Turn the device on or off'),
1291-
],
1285+
exposes: [e.switch(), e.occupancy(), e.binary('device_enabled', ea.ALL, 'ON', 'OFF').withDescription('Turn the device on or off')],
1286+
extend: [m.illuminance()],
12921287
},
12931288
{
12941289
zigbeeModel: ['MBD Dim'],
12951290
model: 'CTM_MBD_Dim',
12961291
vendor: 'CTM Lyng',
12971292
description: 'MBD Dim, motion detector with dimmer',
1298-
fromZigbee: [
1299-
fz.illuminance,
1300-
fz.occupancy,
1301-
fzLocal.ctm_mbd_device_enabled,
1302-
fzLocal.ctm_relay_state,
1303-
fz.brightness,
1304-
fz.lighting_ballast_configuration,
1305-
],
1293+
fromZigbee: [fz.occupancy, fzLocal.ctm_mbd_device_enabled, fzLocal.ctm_relay_state, fz.brightness, fz.lighting_ballast_configuration],
13061294
toZigbee: [tzLocal.ctm_mbd_device_enabled, tzLocal.ctm_relay_state, tzLocal.ctm_mbd_brightness, tz.ballast_config],
13071295
meta: {disableDefaultResponse: true},
13081296
configure: async (device, coordinatorEndpoint) => {
13091297
const endpoint = device.getEndpoint(1);
1310-
await reporting.bind(endpoint, coordinatorEndpoint, [
1311-
'genOnOff',
1312-
'genLevelCtrl',
1313-
'lightingBallastCfg',
1314-
'msIlluminanceMeasurement',
1315-
'msOccupancySensing',
1316-
]);
1298+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'lightingBallastCfg', 'msOccupancySensing']);
13171299
await endpoint.read('genOnOff', ['onOff']);
13181300
await reporting.onOff(endpoint);
13191301
await endpoint.read('genLevelCtrl', ['currentLevel']);
@@ -1343,8 +1325,6 @@ const definitions: DefinitionWithExtend[] = [
13431325
reportableChange: null,
13441326
},
13451327
]);
1346-
await endpoint.read('msIlluminanceMeasurement', ['measuredValue']);
1347-
await reporting.illuminance(endpoint);
13481328
await endpoint.read('msOccupancySensing', ['occupancy']);
13491329
await reporting.occupancy(endpoint);
13501330
// Relay State
@@ -1364,7 +1344,6 @@ const definitions: DefinitionWithExtend[] = [
13641344
},
13651345
exposes: [
13661346
e.light_brightness(),
1367-
e.illuminance(),
13681347
e.occupancy(),
13691348
e.binary('device_enabled', ea.ALL, 'ON', 'OFF').withDescription('Turn the device on or off'),
13701349
e.numeric('ballast_minimum_level', ea.ALL).withValueMin(10).withValueMax(97).withDescription('Specifies the minimum brightness value'),
@@ -1375,6 +1354,7 @@ const definitions: DefinitionWithExtend[] = [
13751354
.withValueMax(97)
13761355
.withDescription('Specifies the initialisation light level. Can not be set lower than "ballast_minimum_level"'),
13771356
],
1357+
extend: [m.illuminance()],
13781358
},
13791359
{
13801360
fingerprint: [{modelID: 'DIMMER', manufacturerName: 'NorLum Dim OP'}],

0 commit comments

Comments
 (0)