@@ -52,6 +52,74 @@ type Extender = [string[], ExtenderGenerator];
52
52
53
53
type DefinitionWithZigbeeModel = DefinitionWithExtend & { zigbeeModel : string [ ] } ;
54
54
55
+ // If generator will have endpoint argument - generator implementation
56
+ // should not provide it if only the first device endpoint is passed in.
57
+ // If multiple endpoints provided(maybe including the first device endpoint) -
58
+ // they all should be passed as an argument, where possible, to be explicit.
59
+ const INPUT_EXTENDERS : Extender [ ] = [
60
+ [
61
+ [ "msTemperatureMeasurement" ] ,
62
+ async ( d , eps ) => [ new ExtendGenerator ( { extend : m . temperature , args : maybeEndpointArgs ( d , eps ) , source : "temperature" } ) ] ,
63
+ ] ,
64
+ [ [ "msPressureMeasurement" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . pressure , args : maybeEndpointArgs ( d , eps ) , source : "pressure" } ) ] ] ,
65
+ [ [ "msRelativeHumidity" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . humidity , args : maybeEndpointArgs ( d , eps ) , source : "humidity" } ) ] ] ,
66
+ [ [ "msCO2" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . co2 , args : maybeEndpointArgs ( d , eps ) , source : "co2" } ) ] ] ,
67
+ [ [ "genPowerCfg" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . battery , source : "battery" } ) ] ] ,
68
+ [ [ "genOnOff" , "genLevelCtrl" , "lightingColorCtrl" ] , extenderOnOffLight ] ,
69
+ [ [ "seMetering" , "haElectricalMeasurement" ] , extenderElectricityMeter ] ,
70
+ [ [ "closuresDoorLock" ] , extenderLock ] ,
71
+ [
72
+ [ "msIlluminanceMeasurement" ] ,
73
+ async ( d , eps ) => [ new ExtendGenerator ( { extend : m . illuminance , args : maybeEndpointArgs ( d , eps ) , source : "illuminance" } ) ] ,
74
+ ] ,
75
+ [ [ "msOccupancySensing" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . occupancy , source : "occupancy" } ) ] ] ,
76
+ [
77
+ [ "ssIasZone" ] ,
78
+ async ( d , eps ) => [
79
+ new ExtendGenerator ( {
80
+ extend : m . iasZoneAlarm ,
81
+ args : {
82
+ zoneType : "generic" ,
83
+ zoneAttributes : [ "alarm_1" , "alarm_2" , "tamper" , "battery_low" ] ,
84
+ } ,
85
+ source : "iasZoneAlarm" ,
86
+ } ) ,
87
+ ] ,
88
+ ] ,
89
+ [ [ "ssIasWd" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . iasWarning , source : "iasWarning" } ) ] ] ,
90
+ [
91
+ [ "genDeviceTempCfg" ] ,
92
+ async ( d , eps ) => [ new ExtendGenerator ( { extend : m . deviceTemperature , args : maybeEndpointArgs ( d , eps ) , source : "deviceTemperature" } ) ] ,
93
+ ] ,
94
+ [ [ "pm25Measurement" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . pm25 , args : maybeEndpointArgs ( d , eps ) , source : "pm25" } ) ] ] ,
95
+ [ [ "msFlowMeasurement" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . flow , args : maybeEndpointArgs ( d , eps ) , source : "flow" } ) ] ] ,
96
+ [ [ "msSoilMoisture" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . soilMoisture , args : maybeEndpointArgs ( d , eps ) , source : "soilMoisture" } ) ] ] ,
97
+ [
98
+ [ "closuresWindowCovering" ] ,
99
+ async ( d , eps ) => [ new ExtendGenerator ( { extend : m . windowCovering , args : { controls : [ "lift" , "tilt" ] } , source : "windowCovering" } ) ] ,
100
+ ] ,
101
+ [ [ "genBinaryInput" ] , extenderBinaryInput ] ,
102
+ [ [ "genBinaryOutput" ] , extenderBinaryOutput ] ,
103
+ ] ;
104
+
105
+ const OUTPUT_EXTENDERS : Extender [ ] = [
106
+ [ [ "genOnOff" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . commandsOnOff , args : maybeEndpointArgs ( d , eps ) , source : "commandsOnOff" } ) ] ] ,
107
+ [
108
+ [ "genLevelCtrl" ] ,
109
+ async ( d , eps ) => [ new ExtendGenerator ( { extend : m . commandsLevelCtrl , args : maybeEndpointArgs ( d , eps ) , source : "commandsLevelCtrl" } ) ] ,
110
+ ] ,
111
+ [
112
+ [ "lightingColorCtrl" ] ,
113
+ async ( d , eps ) => [ new ExtendGenerator ( { extend : m . commandsColorCtrl , args : maybeEndpointArgs ( d , eps ) , source : "commandsColorCtrl" } ) ] ,
114
+ ] ,
115
+ [
116
+ [ "closuresWindowCovering" ] ,
117
+ async ( d , eps ) => [
118
+ new ExtendGenerator ( { extend : m . commandsWindowCovering , args : maybeEndpointArgs ( d , eps ) , source : "commandsWindowCovering" } ) ,
119
+ ] ,
120
+ ] ,
121
+ ] ;
122
+
55
123
function generateSource ( definition : DefinitionWithZigbeeModel , generatedExtend : GeneratedExtend [ ] ) : string {
56
124
const imports = [ ...new Set ( generatedExtend . map ( ( e ) => e . lib ?? "modernExtend" ) ) ] ;
57
125
const importsStr = imports . map ( ( e ) => `const ${ e === "modernExtend" ? "m" : e } = require('zigbee-herdsman-converters/lib/${ e } ');` ) . join ( "\n" ) ;
@@ -69,7 +137,23 @@ const definition = {
69
137
module.exports = definition;` ;
70
138
}
71
139
140
+ function generateGreenPowerSource ( definition : DefinitionWithExtend , ieeeAddr : string ) : string {
141
+ return `import {genericGreenPower} from 'zigbee-herdsman-converters/lib/modernExtend';
142
+
143
+ export default {
144
+ fingerprint: [{modelID: '${ definition . model } ', ieeeAddr: new RegExp('^${ ieeeAddr } $')}],
145
+ model: '${ definition . model } ',
146
+ vendor: '${ definition . vendor } ',
147
+ description: 'Automatically generated definition for Green Power',
148
+ extend: [genericGreenPower()],
149
+ };` ;
150
+ }
151
+
72
152
export async function generateDefinition ( device : Zh . Device ) : Promise < { externalDefinitionSource : string ; definition : DefinitionWithExtend } > {
153
+ if ( device . type === "GreenPower" ) {
154
+ return generateGreenPowerDefinition ( device ) ;
155
+ }
156
+
73
157
// Map cluster to all endpoints that have this cluster.
74
158
const mapClusters = ( endpoint : ZHModels . Endpoint , clusters : Cluster [ ] , clusterMap : Map < string , ZHModels . Endpoint [ ] > ) => {
75
159
for ( const cluster of clusters ) {
@@ -82,8 +166,8 @@ export async function generateDefinition(device: Zh.Device): Promise<{externalDe
82
166
}
83
167
} ;
84
168
85
- const knownInputClusters = inputExtenders . flatMap ( ( ext ) => ext [ 0 ] ) ;
86
- const knownOutputClusters = outputExtenders . flatMap ( ( ext ) => ext [ 0 ] ) ;
169
+ const knownInputClusters = INPUT_EXTENDERS . flatMap ( ( ext ) => ext [ 0 ] ) ;
170
+ const knownOutputClusters = OUTPUT_EXTENDERS . flatMap ( ( ext ) => ext [ 0 ] ) ;
87
171
88
172
const inputClusterMap = new Map < string , ZHModels . Endpoint [ ] > ( ) ;
89
173
const outputClusterMap = new Map < string , ZHModels . Endpoint [ ] > ( ) ;
@@ -110,11 +194,11 @@ export async function generateDefinition(device: Zh.Device): Promise<{externalDe
110
194
} ;
111
195
112
196
for ( const [ cluster , endpoints ] of inputClusterMap ) {
113
- await addGenerators ( cluster , endpoints , inputExtenders ) ;
197
+ await addGenerators ( cluster , endpoints , INPUT_EXTENDERS ) ;
114
198
}
115
199
116
200
for ( const [ cluster , endpoints ] of outputClusterMap ) {
117
- await addGenerators ( cluster , endpoints , outputExtenders ) ;
201
+ await addGenerators ( cluster , endpoints , OUTPUT_EXTENDERS ) ;
118
202
}
119
203
120
204
const extenders = generatedExtend . map ( ( e ) => e . getExtend ( ) ) ;
@@ -158,6 +242,20 @@ export async function generateDefinition(device: Zh.Device): Promise<{externalDe
158
242
return { externalDefinitionSource, definition} ;
159
243
}
160
244
245
+ export function generateGreenPowerDefinition ( device : Zh . Device ) : { externalDefinitionSource : string ; definition : DefinitionWithExtend } {
246
+ const definition : DefinitionWithExtend = {
247
+ fingerprint : [ { modelID : device . modelID , ieeeAddr : new RegExp ( `^${ device . ieeeAddr } $` ) } ] ,
248
+ model : device . modelID ?? "" ,
249
+ vendor : device . manufacturerName ?? "" ,
250
+ description : "Automatically generated definition for Green Power" ,
251
+ extend : [ m . genericGreenPower ( ) ] ,
252
+ generated : true ,
253
+ } ;
254
+
255
+ const externalDefinitionSource = generateGreenPowerSource ( definition , device . ieeeAddr ) ;
256
+ return { externalDefinitionSource, definition} ;
257
+ }
258
+
161
259
function stringifyEps ( endpoints : ZHModels . Endpoint [ ] ) : string [ ] {
162
260
return endpoints . map ( ( e ) => e . ID . toString ( ) ) ;
163
261
}
@@ -179,74 +277,6 @@ function maybeEndpointArgs<T>(device: Zh.Device, endpoints: Zh.Endpoint[], toExt
179
277
return { endpointNames : stringifyEps ( endpoints ) , ...toExtend } ;
180
278
}
181
279
182
- // If generator will have endpoint argument - generator implementation
183
- // should not provide it if only the first device endpoint is passed in.
184
- // If multiple endpoints provided(maybe including the first device endpoint) -
185
- // they all should be passed as an argument, where possible, to be explicit.
186
- const inputExtenders : Extender [ ] = [
187
- [
188
- [ "msTemperatureMeasurement" ] ,
189
- async ( d , eps ) => [ new ExtendGenerator ( { extend : m . temperature , args : maybeEndpointArgs ( d , eps ) , source : "temperature" } ) ] ,
190
- ] ,
191
- [ [ "msPressureMeasurement" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . pressure , args : maybeEndpointArgs ( d , eps ) , source : "pressure" } ) ] ] ,
192
- [ [ "msRelativeHumidity" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . humidity , args : maybeEndpointArgs ( d , eps ) , source : "humidity" } ) ] ] ,
193
- [ [ "msCO2" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . co2 , args : maybeEndpointArgs ( d , eps ) , source : "co2" } ) ] ] ,
194
- [ [ "genPowerCfg" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . battery , source : "battery" } ) ] ] ,
195
- [ [ "genOnOff" , "genLevelCtrl" , "lightingColorCtrl" ] , extenderOnOffLight ] ,
196
- [ [ "seMetering" , "haElectricalMeasurement" ] , extenderElectricityMeter ] ,
197
- [ [ "closuresDoorLock" ] , extenderLock ] ,
198
- [
199
- [ "msIlluminanceMeasurement" ] ,
200
- async ( d , eps ) => [ new ExtendGenerator ( { extend : m . illuminance , args : maybeEndpointArgs ( d , eps ) , source : "illuminance" } ) ] ,
201
- ] ,
202
- [ [ "msOccupancySensing" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . occupancy , source : "occupancy" } ) ] ] ,
203
- [
204
- [ "ssIasZone" ] ,
205
- async ( d , eps ) => [
206
- new ExtendGenerator ( {
207
- extend : m . iasZoneAlarm ,
208
- args : {
209
- zoneType : "generic" ,
210
- zoneAttributes : [ "alarm_1" , "alarm_2" , "tamper" , "battery_low" ] ,
211
- } ,
212
- source : "iasZoneAlarm" ,
213
- } ) ,
214
- ] ,
215
- ] ,
216
- [ [ "ssIasWd" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . iasWarning , source : "iasWarning" } ) ] ] ,
217
- [
218
- [ "genDeviceTempCfg" ] ,
219
- async ( d , eps ) => [ new ExtendGenerator ( { extend : m . deviceTemperature , args : maybeEndpointArgs ( d , eps ) , source : "deviceTemperature" } ) ] ,
220
- ] ,
221
- [ [ "pm25Measurement" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . pm25 , args : maybeEndpointArgs ( d , eps ) , source : "pm25" } ) ] ] ,
222
- [ [ "msFlowMeasurement" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . flow , args : maybeEndpointArgs ( d , eps ) , source : "flow" } ) ] ] ,
223
- [ [ "msSoilMoisture" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . soilMoisture , args : maybeEndpointArgs ( d , eps ) , source : "soilMoisture" } ) ] ] ,
224
- [
225
- [ "closuresWindowCovering" ] ,
226
- async ( d , eps ) => [ new ExtendGenerator ( { extend : m . windowCovering , args : { controls : [ "lift" , "tilt" ] } , source : "windowCovering" } ) ] ,
227
- ] ,
228
- [ [ "genBinaryInput" ] , extenderBinaryInput ] ,
229
- [ [ "genBinaryOutput" ] , extenderBinaryOutput ] ,
230
- ] ;
231
-
232
- const outputExtenders : Extender [ ] = [
233
- [ [ "genOnOff" ] , async ( d , eps ) => [ new ExtendGenerator ( { extend : m . commandsOnOff , args : maybeEndpointArgs ( d , eps ) , source : "commandsOnOff" } ) ] ] ,
234
- [
235
- [ "genLevelCtrl" ] ,
236
- async ( d , eps ) => [ new ExtendGenerator ( { extend : m . commandsLevelCtrl , args : maybeEndpointArgs ( d , eps ) , source : "commandsLevelCtrl" } ) ] ,
237
- ] ,
238
- [
239
- [ "lightingColorCtrl" ] ,
240
- async ( d , eps ) => [ new ExtendGenerator ( { extend : m . commandsColorCtrl , args : maybeEndpointArgs ( d , eps ) , source : "commandsColorCtrl" } ) ] ,
241
- ] ,
242
- [
243
- [ "closuresWindowCovering" ] ,
244
- async ( d , eps ) => [
245
- new ExtendGenerator ( { extend : m . commandsWindowCovering , args : maybeEndpointArgs ( d , eps ) , source : "commandsWindowCovering" } ) ,
246
- ] ,
247
- ] ,
248
- ] ;
249
-
250
280
async function extenderLock ( device : Zh . Device , endpoints : Zh . Endpoint [ ] ) : Promise < GeneratedExtend [ ] > {
251
281
// TODO: Support multiple endpoints
252
282
if ( endpoints . length > 1 ) {
0 commit comments