zigbee-herdsman-converters 14.0.459 → 14.0.462
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/converters/fromZigbee.js +32 -19
- package/converters/toZigbee.js +48 -7
- package/devices/awox.js +1 -1
- package/devices/danfoss.js +32 -2
- package/devices/enocean.js +2 -1
- package/devices/envilar.js +12 -0
- package/devices/evn.js +17 -12
- package/devices/keen_home.js +1 -1
- package/devices/lidl.js +9 -0
- package/devices/niko.js +20 -7
- package/devices/orvibo.js +7 -0
- package/devices/philips.js +18 -0
- package/devices/spotmau.js +33 -0
- package/devices/tuya.js +32 -4
- package/devices/xiaomi.js +9 -7
- package/devices/xinghuoyuan.js +11 -0
- package/lib/constants.js +14 -0
- package/lib/tuya.js +1 -1
- package/lib/xiaomi.js +13 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -3392,6 +3392,23 @@ const converters = {
|
|
|
3392
3392
|
if (msg.data.hasOwnProperty('danfossLoadEstimate')) {
|
|
3393
3393
|
result[postfixWithEndpointName('load_estimate', msg, model)] = msg.data['danfossLoadEstimate'];
|
|
3394
3394
|
}
|
|
3395
|
+
if (msg.data.hasOwnProperty('danfossPreheatStatus')) {
|
|
3396
|
+
result[postfixWithEndpointName('preheat_status', msg, model)] = (msg.data['danfossPreheatStatus'] === 1);
|
|
3397
|
+
}
|
|
3398
|
+
if (msg.data.hasOwnProperty('danfossAdaptionRunStatus')) {
|
|
3399
|
+
result[postfixWithEndpointName('adaptation_run_status', msg, model)] =
|
|
3400
|
+
constants.danfossAdaptionRunStatus[msg.data['danfossAdaptionRunStatus']];
|
|
3401
|
+
}
|
|
3402
|
+
if (msg.data.hasOwnProperty('danfossAdaptionRunSettings')) {
|
|
3403
|
+
result[postfixWithEndpointName('adaptation_run_settings', msg, model)] = (msg.data['danfossAdaptionRunSettings'] === 1);
|
|
3404
|
+
}
|
|
3405
|
+
if (msg.data.hasOwnProperty('danfossAdaptionRunControl')) {
|
|
3406
|
+
result[postfixWithEndpointName('adaptation_run_control', msg, model)] =
|
|
3407
|
+
constants.danfossAdaptionRunControl[msg.data['danfossAdaptionRunControl']];
|
|
3408
|
+
}
|
|
3409
|
+
if (msg.data.hasOwnProperty('danfossRegulationSetpointOffset')) {
|
|
3410
|
+
result[postfixWithEndpointName('regulation_setpoint_offset', msg, model)] = msg.data['danfossRegulationSetpointOffset'];
|
|
3411
|
+
}
|
|
3395
3412
|
// Danfoss Icon Converters
|
|
3396
3413
|
if (msg.data.hasOwnProperty('danfossRoomStatusCode')) {
|
|
3397
3414
|
result[postfixWithEndpointName('room_status_code', msg, model)] =
|
|
@@ -4806,6 +4823,7 @@ const converters = {
|
|
|
4806
4823
|
0x1e: 'press_1_and_4', 0x1f: 'release_1_and_4', 0x1c: 'press_2_and_3', 0x1d: 'release_2_and_3', 0x1a: 'press_2_and_4',
|
|
4807
4824
|
0x1b: 'release_2_and_4', 0x16: 'press_3_and_4', 0x17: 'release_3_and_4', 0x10: 'press_energy_bar',
|
|
4808
4825
|
0x11: 'release_energy_bar', 0x0: 'press_or_release_all',
|
|
4826
|
+
0x50: 'lock', 0x51: 'unlock', 0x52: 'half_open', 0x53: 'tilt',
|
|
4809
4827
|
};
|
|
4810
4828
|
|
|
4811
4829
|
if (!lookup.hasOwnProperty(commandID)) {
|
|
@@ -5662,38 +5680,33 @@ const converters = {
|
|
|
5662
5680
|
type: ['attributeReport', 'readResponse'],
|
|
5663
5681
|
options: [exposes.options.invert_cover()],
|
|
5664
5682
|
convert: (model, msg, publish, options, meta) => {
|
|
5665
|
-
let running = false;
|
|
5666
|
-
|
|
5667
5683
|
if (model.model === 'ZNCLDJ12LM' && msg.type === 'attributeReport' && [0, 2].includes(msg.data['presentValue'])) {
|
|
5668
5684
|
// Incorrect reports from the device, ignore (re-read by onEvent of ZNCLDJ12LM)
|
|
5669
5685
|
// https://github.com/Koenkk/zigbee-herdsman-converters/pull/1427#issuecomment-663862724
|
|
5670
5686
|
return;
|
|
5671
5687
|
}
|
|
5672
5688
|
|
|
5673
|
-
if (msg.data['61440']) {
|
|
5674
|
-
const value = msg.data['61440'];
|
|
5675
|
-
// 63025664 comes from https://github.com/Koenkk/zigbee2mqtt/issues/5155#issuecomment-753344248
|
|
5676
|
-
running = value !== 0 && value !== 63025664;
|
|
5677
|
-
}
|
|
5678
|
-
|
|
5679
5689
|
let position = precisionRound(msg.data['presentValue'], 2);
|
|
5680
5690
|
position = options.invert_cover ? 100 - position : position;
|
|
5681
|
-
return {position
|
|
5691
|
+
return {position};
|
|
5682
5692
|
},
|
|
5683
5693
|
},
|
|
5684
|
-
|
|
5685
|
-
cluster: '
|
|
5694
|
+
xiaomi_curtain_position_tilt: {
|
|
5695
|
+
cluster: 'closuresWindowCovering',
|
|
5686
5696
|
type: ['attributeReport', 'readResponse'],
|
|
5697
|
+
options: [exposes.options.invert_cover()],
|
|
5687
5698
|
convert: (model, msg, publish, options, meta) => {
|
|
5688
|
-
const
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5699
|
+
const result = {};
|
|
5700
|
+
const invert = model.meta && model.meta.coverInverted ? !options.invert_cover : options.invert_cover;
|
|
5701
|
+
if (msg.data.hasOwnProperty('currentPositionLiftPercentage') && msg.data['currentPositionLiftPercentage'] <= 100) {
|
|
5702
|
+
const value = msg.data['currentPositionLiftPercentage'];
|
|
5703
|
+
result[postfixWithEndpointName('position', msg, model)] = invert ? 100 - value : value;
|
|
5704
|
+
}
|
|
5705
|
+
if (msg.data.hasOwnProperty('currentPositionTiltPercentage') && msg.data['currentPositionTiltPercentage'] <= 100) {
|
|
5706
|
+
const value = msg.data['currentPositionTiltPercentage'];
|
|
5707
|
+
result[postfixWithEndpointName('tilt', msg, model)] = invert ? 100 - value : value;
|
|
5696
5708
|
}
|
|
5709
|
+
return result;
|
|
5697
5710
|
},
|
|
5698
5711
|
},
|
|
5699
5712
|
xiaomi_curtain_acn002_position: {
|
package/converters/toZigbee.js
CHANGED
|
@@ -2438,18 +2438,12 @@ const converters = {
|
|
|
2438
2438
|
} else {
|
|
2439
2439
|
await entity.command('closuresWindowCovering', 'stop', {}, utils.getOptions(meta.mapped, entity));
|
|
2440
2440
|
}
|
|
2441
|
-
|
|
2442
|
-
// Xiaomi curtain does not send position update on stop, request this.
|
|
2443
|
-
await entity.read('genAnalogOutput', [0x0055]);
|
|
2444
2441
|
} else {
|
|
2445
2442
|
const lookup = {'open': 100, 'close': 0, 'on': 100, 'off': 0};
|
|
2446
2443
|
|
|
2447
2444
|
value = typeof value === 'string' ? value.toLowerCase() : value;
|
|
2448
2445
|
value = lookup.hasOwnProperty(value) ? lookup[value] : value;
|
|
2449
|
-
|
|
2450
|
-
if (key === 'position') {
|
|
2451
|
-
value = meta.options.invert_cover ? 100 - value : value;
|
|
2452
|
-
}
|
|
2446
|
+
value = meta.options.invert_cover ? 100 - value : value;
|
|
2453
2447
|
|
|
2454
2448
|
const payload = {0x0055: {value, type: 0x39}};
|
|
2455
2449
|
await entity.write('genAnalogOutput', payload);
|
|
@@ -2854,6 +2848,53 @@ const converters = {
|
|
|
2854
2848
|
await entity.read('hvacThermostat', ['danfossLoadEstimate'], manufacturerOptions.danfoss);
|
|
2855
2849
|
},
|
|
2856
2850
|
},
|
|
2851
|
+
danfoss_preheat_status: {
|
|
2852
|
+
key: ['preheat_status'],
|
|
2853
|
+
convertGet: async (entity, key, meta) => {
|
|
2854
|
+
await entity.read('hvacThermostat', ['danfossPreheatStatus'], manufacturerOptions.danfoss);
|
|
2855
|
+
},
|
|
2856
|
+
},
|
|
2857
|
+
danfoss_adaptation_status: {
|
|
2858
|
+
key: ['adaptation_run_status'],
|
|
2859
|
+
convertGet: async (entity, key, meta) => {
|
|
2860
|
+
await entity.read('hvacThermostat', ['danfossAdaptionRunStatus'], manufacturerOptions.danfoss);
|
|
2861
|
+
},
|
|
2862
|
+
},
|
|
2863
|
+
danfoss_adaptation_settings: {
|
|
2864
|
+
key: ['adaptation_run_settings'],
|
|
2865
|
+
convertSet: async (entity, key, value, meta) => {
|
|
2866
|
+
await entity.write('hvacThermostat', {'danfossAdaptionRunSettings': value}, manufacturerOptions.danfoss);
|
|
2867
|
+
return {readAfterWriteTime: 200, state: {'adaptation_run_settings': value}};
|
|
2868
|
+
},
|
|
2869
|
+
|
|
2870
|
+
convertGet: async (entity, key, meta) => {
|
|
2871
|
+
await entity.read('hvacThermostat', ['danfossAdaptionRunSettings'], manufacturerOptions.danfoss);
|
|
2872
|
+
},
|
|
2873
|
+
},
|
|
2874
|
+
danfoss_adaptation_control: {
|
|
2875
|
+
key: ['adaptation_run_control'],
|
|
2876
|
+
convertSet: async (entity, key, value, meta) => {
|
|
2877
|
+
const payload = {'danfossAdaptionRunControl': utils.getKey(constants.danfossAdaptionRunControl, value, value, Number)};
|
|
2878
|
+
await entity.write('hvacThermostat', payload, manufacturerOptions.danfoss);
|
|
2879
|
+
return {readAfterWriteTime: 250, state: {'adaptation_run_control': value}};
|
|
2880
|
+
},
|
|
2881
|
+
|
|
2882
|
+
convertGet: async (entity, key, meta) => {
|
|
2883
|
+
await entity.read('hvacThermostat', ['danfossAdaptionRunControl'], manufacturerOptions.danfoss);
|
|
2884
|
+
},
|
|
2885
|
+
},
|
|
2886
|
+
danfoss_regulation_setpoint_offset: {
|
|
2887
|
+
key: ['regulation_setpoint_offset'],
|
|
2888
|
+
convertSet: async (entity, key, value, meta) => {
|
|
2889
|
+
const payload = {'danfossRegulationSetpointOffset': value};
|
|
2890
|
+
await entity.write('hvacThermostat', payload, manufacturerOptions.danfoss);
|
|
2891
|
+
return {readAfterWriteTime: 250, state: {'regulation_setpoint_offset': value}};
|
|
2892
|
+
},
|
|
2893
|
+
|
|
2894
|
+
convertGet: async (entity, key, meta) => {
|
|
2895
|
+
await entity.read('hvacThermostat', ['danfossRegulationSetpointOffset'], manufacturerOptions.danfoss);
|
|
2896
|
+
},
|
|
2897
|
+
},
|
|
2857
2898
|
danfoss_output_status: {
|
|
2858
2899
|
key: ['output_status'],
|
|
2859
2900
|
convertGet: async (entity, key, meta) => {
|
package/devices/awox.js
CHANGED
|
@@ -183,7 +183,7 @@ module.exports = [
|
|
|
183
183
|
model: '33943/33944/33946',
|
|
184
184
|
vendor: 'AwoX',
|
|
185
185
|
description: 'LED RGB & brightness',
|
|
186
|
-
extend: extend.light_onoff_brightness_colortemp_color(),
|
|
186
|
+
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370], supportsHS: true}),
|
|
187
187
|
},
|
|
188
188
|
{
|
|
189
189
|
fingerprint: [
|
package/devices/danfoss.js
CHANGED
|
@@ -24,7 +24,8 @@ module.exports = [
|
|
|
24
24
|
tz.danfoss_viewing_direction, tz.danfoss_external_measured_room_sensor, tz.danfoss_radiator_covered,
|
|
25
25
|
tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tz.danfoss_load_balancing_enable, tz.danfoss_load_room_mean,
|
|
26
26
|
tz.thermostat_weekly_schedule, tz.thermostat_clear_weekly_schedule, tz.thermostat_programming_operation_mode,
|
|
27
|
-
tz.danfoss_window_open_feature
|
|
27
|
+
tz.danfoss_window_open_feature, tz.danfoss_preheat_status, tz.danfoss_adaptation_status, tz.danfoss_adaptation_settings,
|
|
28
|
+
tz.danfoss_adaptation_control, tz.danfoss_regulation_setpoint_offset],
|
|
28
29
|
exposes: [e.battery(), e.keypad_lockout(), e.programming_operation_mode(),
|
|
29
30
|
exposes.binary('mounted_mode_active', ea.STATE_GET, true, false)
|
|
30
31
|
.withDescription('Is the unit in mounting mode. This is set to `false` for mounted (already on ' +
|
|
@@ -78,7 +79,19 @@ module.exports = [
|
|
|
78
79
|
.withDescription('Mean radiator load for room calculated by gateway for load balancing purposes (-8000=undefined)')
|
|
79
80
|
.withValueMin(-8000).withValueMax(2000),
|
|
80
81
|
exposes.numeric('load_estimate', ea.STATE_GET)
|
|
81
|
-
.withDescription('Load estimate on this radiator')
|
|
82
|
+
.withDescription('Load estimate on this radiator'),
|
|
83
|
+
exposes.binary('preheat_status', ea.STATE_GET, true, false)
|
|
84
|
+
.withDescription('Specific for pre-heat running in Zigbee Weekly Schedule mode'),
|
|
85
|
+
exposes.enum('adaptation_run_status', ea.STATE_GET, ['none', 'in_progress', 'found', 'lost'])
|
|
86
|
+
.withDescription('Status of adaptation run: None (before first run), In Progress, Valve Characteristic Found, ' +
|
|
87
|
+
'Valve Characteristic Lost'),
|
|
88
|
+
exposes.binary('adaptation_run_settings', ea.ALL, true, false)
|
|
89
|
+
.withDescription('Automatic adaptation run enabled (the one during the night)'),
|
|
90
|
+
exposes.enum('adaptation_run_control', ea.ALL, ['initate_adaptation', 'cancel_adaptation'])
|
|
91
|
+
.withDescription('Adaptation run control: Initiate Adaptation Run or Cancel Adaptation Run'),
|
|
92
|
+
exposes.numeric('regulation_setpoint_offset', ea.ALL)
|
|
93
|
+
.withDescription('Regulation SetPoint Offset in range -2.5°C to 2.5°C in steps of 0.1°C. Value 2.5°C = 25.')
|
|
94
|
+
.withValueMin(-25).withValueMax(25)],
|
|
82
95
|
ota: ota.zigbeeOTA,
|
|
83
96
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
84
97
|
const endpoint = device.getEndpoint(1);
|
|
@@ -117,6 +130,20 @@ module.exports = [
|
|
|
117
130
|
reportableChange: 1,
|
|
118
131
|
}], options);
|
|
119
132
|
|
|
133
|
+
await endpoint.configureReporting('hvacThermostat', [{
|
|
134
|
+
attribute: 'danfossPreheatStatus',
|
|
135
|
+
minimumReportInterval: constants.repInterval.MINUTE,
|
|
136
|
+
maximumReportInterval: constants.repInterval.MAX,
|
|
137
|
+
reportableChange: 1,
|
|
138
|
+
}], options);
|
|
139
|
+
|
|
140
|
+
await endpoint.configureReporting('hvacThermostat', [{
|
|
141
|
+
attribute: 'danfossAdaptionRunStatus',
|
|
142
|
+
minimumReportInterval: constants.repInterval.MINUTE,
|
|
143
|
+
maximumReportInterval: constants.repInterval.HOUR,
|
|
144
|
+
reportableChange: 1,
|
|
145
|
+
}], options);
|
|
146
|
+
|
|
120
147
|
try {
|
|
121
148
|
await endpoint.read('hvacThermostat', [
|
|
122
149
|
'danfossWindowOpenFeatureEnable',
|
|
@@ -131,6 +158,9 @@ module.exports = [
|
|
|
131
158
|
'danfossRadiatorCovered',
|
|
132
159
|
'danfossLoadBalancingEnable',
|
|
133
160
|
'danfossLoadRoomMean',
|
|
161
|
+
'danfossAdaptionRunControl',
|
|
162
|
+
'danfossAdaptionRunSettings',
|
|
163
|
+
'danfossRegulationSetpointOffset',
|
|
134
164
|
], options);
|
|
135
165
|
} catch (e) {
|
|
136
166
|
/* not supported by all https://github.com/Koenkk/zigbee2mqtt/issues/11872 */
|
package/devices/enocean.js
CHANGED
|
@@ -28,7 +28,8 @@ module.exports = [
|
|
|
28
28
|
exposes: [e.action(['press_1', 'release_1', 'press_2', 'release_2', 'press_3', 'release_3', 'press_4', 'release_4',
|
|
29
29
|
'press_1_and_2', 'release_1_and_2', 'press_1_and_3', 'release_1_and_3', 'press_1_and_4', 'release_1_and_4',
|
|
30
30
|
'press_2_and_3', 'release_2_and_3', 'press_2_and_4', 'release_2_and_4', 'press_3_and_4', 'release_3_and_4',
|
|
31
|
-
'press_energy_bar', 'release_energy_bar', 'press_or_release_all'
|
|
31
|
+
'press_energy_bar', 'release_energy_bar', 'press_or_release_all',
|
|
32
|
+
'lock', 'unlock', 'half_open', 'tilt'])],
|
|
32
33
|
whiteLabel: [
|
|
33
34
|
{vendor: 'Easyfit by EnOcean', description: 'Wall switch for Zigbee', model: 'EWSxZ'},
|
|
34
35
|
{vendor: 'Trio2sys', description: 'Zigbee Green Power complete switch', model: '20020002'},
|
package/devices/envilar.js
CHANGED
|
@@ -2,8 +2,20 @@ const reporting = require('../lib/reporting');
|
|
|
2
2
|
const extend = require('../lib/extend');
|
|
3
3
|
const exposes = require('../lib/exposes');
|
|
4
4
|
const e = exposes.presets;
|
|
5
|
+
const fz = require('../converters/fromZigbee');
|
|
5
6
|
|
|
6
7
|
module.exports = [
|
|
8
|
+
{
|
|
9
|
+
zigbeeModel: ['ZGR904-S'],
|
|
10
|
+
model: 'ZGR904-S',
|
|
11
|
+
vendor: 'Envilar',
|
|
12
|
+
description: 'Envilar touchlink remote',
|
|
13
|
+
meta: {battery: {dontDividePercentage: true}},
|
|
14
|
+
fromZigbee: [fz.command_recall, fz.command_on, fz.command_off, fz.command_move, fz.command_stop, fz.battery],
|
|
15
|
+
toZigbee: [],
|
|
16
|
+
exposes: [e.battery(),
|
|
17
|
+
e.action(['recall_1', 'recall_2', 'on', 'off', 'brightness_stop', 'brightness_move_up', 'brightness_move_down'])],
|
|
18
|
+
},
|
|
7
19
|
{
|
|
8
20
|
zigbeeModel: ['ZG102-BOX-UNIDIM'],
|
|
9
21
|
model: 'ZG102-BOX-UNIDIM',
|
package/devices/evn.js
CHANGED
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
const exposes = require('../lib/exposes');
|
|
2
|
+
const extend = require('../lib/extend');
|
|
2
3
|
const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
|
|
3
|
-
const reporting = require('../lib/reporting');
|
|
4
4
|
const e = exposes.presets;
|
|
5
5
|
|
|
6
6
|
module.exports = [
|
|
7
7
|
{
|
|
8
|
-
zigbeeModel: ['
|
|
8
|
+
zigbeeModel: ['ZBHS4RGBW'],
|
|
9
9
|
model: 'ZBHS4RGBW',
|
|
10
10
|
vendor: 'EVN',
|
|
11
11
|
description: 'Zigbee 4 channel RGBW remote control',
|
|
12
|
-
fromZigbee: [fz.battery, fz.
|
|
13
|
-
fz.
|
|
14
|
-
exposes: [e.battery(), e.action([
|
|
15
|
-
'
|
|
16
|
-
'
|
|
12
|
+
fromZigbee: [fz.battery, fz.command_move_to_color, fz.command_move_to_color_temp, fz.command_move_hue,
|
|
13
|
+
fz.command_step, fz.command_stop, fz.command_move, fz.command_recall, fz.command_on, fz.command_off],
|
|
14
|
+
exposes: [e.battery(), e.action([
|
|
15
|
+
'color_move', 'color_temperature_move', 'brightness_step_up', 'brightness_step_down',
|
|
16
|
+
'brightness_move_up', 'brightness_move_down', 'brightness_stop',
|
|
17
|
+
'hue_move', 'hue_stop', 'recall_*', 'on', 'off'])],
|
|
17
18
|
toZigbee: [],
|
|
18
19
|
meta: {multiEndpoint: true, battery: {dontDividePercentage: true}},
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']);
|
|
22
|
-
await reporting.batteryVoltage(endpoint);
|
|
23
|
-
await reporting.batteryPercentageRemaining(endpoint);
|
|
20
|
+
endpoint: (device) => {
|
|
21
|
+
return {ep1: 1, ep2: 2, ep3: 3, ep4: 4};
|
|
24
22
|
},
|
|
25
23
|
},
|
|
24
|
+
{
|
|
25
|
+
zigbeeModel: ['ZB24100VS'],
|
|
26
|
+
model: 'ZB24100VS',
|
|
27
|
+
vendor: 'EVN',
|
|
28
|
+
description: 'Zigbee multicolor controller with power supply',
|
|
29
|
+
extend: extend.light_onoff_brightness_colortemp_color({supportsHS: true, colorTempRange: [160, 450]}),
|
|
30
|
+
},
|
|
26
31
|
];
|
package/devices/keen_home.js
CHANGED
|
@@ -22,7 +22,7 @@ module.exports = [
|
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
zigbeeModel: ['SV01-410-MP-1.0', 'SV01-410-MP-1.1', 'SV01-410-MP-1.4', 'SV01-410-MP-1.5', 'SV01-412-MP-1.0',
|
|
25
|
-
'SV01-412-MP-1.4', 'SV01-610-MP-1.0', 'SV01-610-MP-1.1', 'SV01-612-MP-1.0', 'SV01-610-MP-1.4'],
|
|
25
|
+
'SV01-412-MP-1.1', 'SV01-412-MP-1.4', 'SV01-610-MP-1.0', 'SV01-610-MP-1.1', 'SV01-612-MP-1.0', 'SV01-610-MP-1.4'],
|
|
26
26
|
model: 'SV01',
|
|
27
27
|
vendor: 'Keen Home',
|
|
28
28
|
description: 'Smart vent',
|
package/devices/lidl.js
CHANGED
|
@@ -378,6 +378,15 @@ module.exports = [
|
|
|
378
378
|
await reporting.onOff(endpoint);
|
|
379
379
|
},
|
|
380
380
|
},
|
|
381
|
+
{
|
|
382
|
+
fingerprint: [{modelID: 'TS004F', manufacturerName: '_TZ3000_rco1yzb1'}],
|
|
383
|
+
model: 'HG08164',
|
|
384
|
+
vendor: 'Lidl',
|
|
385
|
+
description: 'Silvercrest smart button',
|
|
386
|
+
fromZigbee: [fz.command_on, fz.command_off, fz.command_step, fz.command_stop, fz.battery],
|
|
387
|
+
toZigbee: [],
|
|
388
|
+
exposes: [e.action(['on', 'off', 'brightness_stop', 'brightness_step_up', 'brightness_step_down']), e.battery()],
|
|
389
|
+
},
|
|
381
390
|
{
|
|
382
391
|
fingerprint: [{modelID: 'TS0211', manufacturerName: '_TZ1800_ladpngdx'}],
|
|
383
392
|
model: 'HG06668',
|
package/devices/niko.js
CHANGED
|
@@ -11,17 +11,30 @@ module.exports = [
|
|
|
11
11
|
model: '170-33505',
|
|
12
12
|
vendor: 'Niko',
|
|
13
13
|
description: 'Connected socket outlet',
|
|
14
|
-
fromZigbee: [fz.on_off, fz.electrical_measurement],
|
|
15
|
-
toZigbee: [tz.on_off, tz.electrical_measurement_power],
|
|
14
|
+
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering],
|
|
15
|
+
toZigbee: [tz.on_off, tz.electrical_measurement_power, tz.currentsummdelivered],
|
|
16
16
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
17
17
|
const endpoint = device.getEndpoint(1);
|
|
18
|
-
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement']);
|
|
19
|
-
await reporting.
|
|
18
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
|
|
19
|
+
await reporting.onOff(endpoint);
|
|
20
|
+
|
|
21
|
+
// NOTE: we read them individually, acFrequency* is not supported
|
|
22
|
+
// so we cannot use readEletricalMeasurementMultiplierDivisors
|
|
23
|
+
await endpoint.read('haElectricalMeasurement', ['acPowerMultiplier', 'acPowerDivisor']);
|
|
20
24
|
await reporting.activePower(endpoint, {min: 5, max: 3600, change: 1000});
|
|
25
|
+
await endpoint.read('haElectricalMeasurement', ['acCurrentDivisor', 'acPowerMultiplier', 'acPowerDivisor']);
|
|
21
26
|
await reporting.rmsCurrent(endpoint, {min: 5, max: 3600, change: 100});
|
|
27
|
+
await endpoint.read('haElectricalMeasurement', ['acVoltageMultiplier', 'acVoltageDivisor', 'acCurrentMultiplier']);
|
|
22
28
|
await reporting.rmsVoltage(endpoint, {min: 5, max: 3600, change: 100});
|
|
29
|
+
|
|
30
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
31
|
+
await reporting.currentSummDelivered(endpoint, {min: 60, change: 1});
|
|
23
32
|
},
|
|
24
|
-
exposes: [
|
|
33
|
+
exposes: [
|
|
34
|
+
e.switch(),
|
|
35
|
+
e.power().withAccess(ea.STATE_GET), e.current(), e.voltage(),
|
|
36
|
+
e.energy().withAccess(ea.STATE_GET),
|
|
37
|
+
],
|
|
25
38
|
},
|
|
26
39
|
{
|
|
27
40
|
zigbeeModel: ['Smart plug Zigbee PE'],
|
|
@@ -29,7 +42,7 @@ module.exports = [
|
|
|
29
42
|
vendor: 'Niko',
|
|
30
43
|
description: 'Smart plug with earthing pin',
|
|
31
44
|
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.power_on_behavior],
|
|
32
|
-
toZigbee: [tz.on_off, tz.power_on_behavior, tz.electrical_measurement_power],
|
|
45
|
+
toZigbee: [tz.on_off, tz.power_on_behavior, tz.electrical_measurement_power, tz.currentsummdelivered],
|
|
33
46
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
34
47
|
const endpoint = device.getEndpoint(1);
|
|
35
48
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
|
|
@@ -41,7 +54,7 @@ module.exports = [
|
|
|
41
54
|
await reporting.currentSummDelivered(endpoint, {min: 60, change: 1});
|
|
42
55
|
},
|
|
43
56
|
exposes: [
|
|
44
|
-
e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(),
|
|
57
|
+
e.switch(), e.power().withAccess(ea.STATE_GET), e.energy().withAccess(ea.STATE_GET),
|
|
45
58
|
exposes.enum('power_on_behavior', ea.ALL, ['off', 'previous', 'on'])
|
|
46
59
|
.withDescription('Controls the behaviour when the device is powered on'),
|
|
47
60
|
],
|
package/devices/orvibo.js
CHANGED
|
@@ -6,6 +6,13 @@ const extend = require('../lib/extend');
|
|
|
6
6
|
const e = exposes.presets;
|
|
7
7
|
|
|
8
8
|
module.exports = [
|
|
9
|
+
{
|
|
10
|
+
zigbeeModel: ['ORVIBO Socket'],
|
|
11
|
+
model: 'OR-ZB-S010-3C',
|
|
12
|
+
vendor: 'ORVIBO',
|
|
13
|
+
description: 'Smart Socket',
|
|
14
|
+
extend: extend.switch(),
|
|
15
|
+
},
|
|
9
16
|
{
|
|
10
17
|
zigbeeModel: ['3c4e4fc81ed442efaf69353effcdfc5f', '51725b7bcba945c8a595b325127461e9'],
|
|
11
18
|
model: 'CR11S8UZ',
|
package/devices/philips.js
CHANGED
|
@@ -1513,6 +1513,15 @@ module.exports = [
|
|
|
1513
1513
|
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 500]}),
|
|
1514
1514
|
ota: ota.zigbeeOTA,
|
|
1515
1515
|
},
|
|
1516
|
+
{
|
|
1517
|
+
zigbeeModel: ['4023331P6'],
|
|
1518
|
+
model: '4023331P6',
|
|
1519
|
+
vendor: 'Philips',
|
|
1520
|
+
description: 'Hue white ambiance Amaze',
|
|
1521
|
+
meta: {turnsOffAtBrightness1: true},
|
|
1522
|
+
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 500]}),
|
|
1523
|
+
ota: ota.zigbeeOTA,
|
|
1524
|
+
},
|
|
1516
1525
|
{
|
|
1517
1526
|
zigbeeModel: ['929003054801'],
|
|
1518
1527
|
model: '929003054801',
|
|
@@ -2732,6 +2741,15 @@ module.exports = [
|
|
|
2732
2741
|
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
2733
2742
|
ota: ota.zigbeeOTA,
|
|
2734
2743
|
},
|
|
2744
|
+
{
|
|
2745
|
+
zigbeeModel: ['1746530P7'],
|
|
2746
|
+
model: '1746530P7',
|
|
2747
|
+
vendor: 'Philips',
|
|
2748
|
+
description: 'Hue White and color ambiance Daylo outdoor wall lamp',
|
|
2749
|
+
meta: {turnsOffAtBrightness1: true},
|
|
2750
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
2751
|
+
ota: ota.zigbeeOTA,
|
|
2752
|
+
},
|
|
2735
2753
|
{
|
|
2736
2754
|
zigbeeModel: ['1746547P7'],
|
|
2737
2755
|
model: '1746547P7',
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const exposes = require('../lib/exposes');
|
|
2
|
+
const reporting = require('../lib/reporting');
|
|
3
|
+
const extend = require('../lib/extend');
|
|
4
|
+
const e = exposes.presets;
|
|
5
|
+
|
|
6
|
+
module.exports = [
|
|
7
|
+
{
|
|
8
|
+
zigbeeModel: ['1719SP-PS1-02'],
|
|
9
|
+
model: 'SP-PS1-02',
|
|
10
|
+
vendor: 'Spotmau',
|
|
11
|
+
description: 'Smart wall switch - 1 gang',
|
|
12
|
+
extend: extend.switch(),
|
|
13
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
14
|
+
await reporting.bind(device.getEndpoint(16), coordinatorEndpoint, ['genOnOff', 'genBasic']);
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
zigbeeModel: ['1719SP-PS2-02'],
|
|
19
|
+
model: 'SP-PS2-02',
|
|
20
|
+
vendor: 'Spotmau',
|
|
21
|
+
description: 'Smart wall switch - 2 gang',
|
|
22
|
+
extend: extend.switch(),
|
|
23
|
+
exposes: [e.switch().withEndpoint('left'), e.switch().withEndpoint('right')],
|
|
24
|
+
endpoint: (device) => {
|
|
25
|
+
return {'left': 16, 'right': 17};
|
|
26
|
+
},
|
|
27
|
+
meta: {multiEndpoint: true},
|
|
28
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
29
|
+
await reporting.bind(device.getEndpoint(16), coordinatorEndpoint, ['genOnOff', 'genBasic']);
|
|
30
|
+
await reporting.bind(device.getEndpoint(17), coordinatorEndpoint, ['genOnOff', 'genBasic']);
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
];
|
package/devices/tuya.js
CHANGED
|
@@ -53,6 +53,29 @@ const fzLocal = {
|
|
|
53
53
|
return fz.battery.convert(model, msg, publish, options, meta);
|
|
54
54
|
},
|
|
55
55
|
},
|
|
56
|
+
TS0222: {
|
|
57
|
+
cluster: 'manuSpecificTuya',
|
|
58
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
59
|
+
convert: (model, msg, publish, options, meta) => {
|
|
60
|
+
const result = {};
|
|
61
|
+
for (const dpValue of msg.data.dpValues) {
|
|
62
|
+
const dp = dpValue.dp;
|
|
63
|
+
const value = tuya.getDataValue(dpValue);
|
|
64
|
+
switch (dp) {
|
|
65
|
+
case 2:
|
|
66
|
+
result.illuminance = value;
|
|
67
|
+
result.illuminance_lux = value;
|
|
68
|
+
break;
|
|
69
|
+
case 4:
|
|
70
|
+
result.battery = value;
|
|
71
|
+
break;
|
|
72
|
+
default:
|
|
73
|
+
meta.logger.warn(`zigbee-herdsman-converters:TS0222 Unrecognized DP #${dp} with data ${JSON.stringify(dpValue)}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
77
|
+
},
|
|
78
|
+
},
|
|
56
79
|
};
|
|
57
80
|
|
|
58
81
|
module.exports = [
|
|
@@ -97,13 +120,14 @@ module.exports = [
|
|
|
97
120
|
description: 'Door sensor',
|
|
98
121
|
fromZigbee: [fz.ias_contact_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_contact_alarm_1_report],
|
|
99
122
|
toZigbee: [],
|
|
100
|
-
exposes: [e.contact(), e.battery_low(), e.tamper(), e.battery()],
|
|
123
|
+
exposes: [e.contact(), e.battery_low(), e.tamper(), e.battery(), e.battery_voltage()],
|
|
101
124
|
whiteLabel: [{vendor: 'CR Smart Home', model: 'TS0203'}],
|
|
102
125
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
103
126
|
try {
|
|
104
127
|
const endpoint = device.getEndpoint(1);
|
|
105
128
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
106
129
|
await reporting.batteryPercentageRemaining(endpoint);
|
|
130
|
+
await reporting.batteryVoltage(endpoint);
|
|
107
131
|
} catch (error) {/* Fails for some*/}
|
|
108
132
|
},
|
|
109
133
|
},
|
|
@@ -1273,7 +1297,7 @@ module.exports = [
|
|
|
1273
1297
|
description: 'Smart plug (with power monitoring)',
|
|
1274
1298
|
vendor: 'TuYa',
|
|
1275
1299
|
whiteLabel: [{vendor: 'LELLKI', model: 'TS011F_plug'}, {vendor: 'NEO', model: 'NAS-WR01B'},
|
|
1276
|
-
{vendor: 'BlitzWolf', model: 'BW-SHP15'}],
|
|
1300
|
+
{vendor: 'BlitzWolf', model: 'BW-SHP15'}, {vendor: 'Nous', model: 'A1Z'}],
|
|
1277
1301
|
ota: ota.zigbeeOTA,
|
|
1278
1302
|
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, fz.tuya_switch_power_outage_memory,
|
|
1279
1303
|
fz.ts011f_plug_indicator_mode, fz.ts011f_plug_child_mode],
|
|
@@ -1647,7 +1671,7 @@ module.exports = [
|
|
|
1647
1671
|
},
|
|
1648
1672
|
},
|
|
1649
1673
|
{
|
|
1650
|
-
zigbeeModel: ['HY0017'],
|
|
1674
|
+
zigbeeModel: ['HY0017', '005f0c3'],
|
|
1651
1675
|
model: 'U86KCJ-ZP',
|
|
1652
1676
|
vendor: 'TuYa',
|
|
1653
1677
|
description: 'Smart 6 key scene wall switch',
|
|
@@ -1803,9 +1827,13 @@ module.exports = [
|
|
|
1803
1827
|
model: 'TS0222',
|
|
1804
1828
|
vendor: 'TuYa',
|
|
1805
1829
|
description: 'Light intensity sensor',
|
|
1806
|
-
fromZigbee: [fz.battery, fz.illuminance],
|
|
1830
|
+
fromZigbee: [fz.battery, fz.illuminance, fzLocal.TS0222],
|
|
1807
1831
|
toZigbee: [],
|
|
1808
1832
|
exposes: [e.battery(), e.illuminance(), e.illuminance_lux()],
|
|
1833
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1834
|
+
const endpoint = device.getEndpoint(1);
|
|
1835
|
+
await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
|
|
1836
|
+
},
|
|
1809
1837
|
},
|
|
1810
1838
|
{
|
|
1811
1839
|
fingerprint: [{modelID: 'TS0210', manufacturerName: '_TYZB01_3zv6oleo'},
|
package/devices/xiaomi.js
CHANGED
|
@@ -1236,11 +1236,13 @@ module.exports = [
|
|
|
1236
1236
|
model: 'ZNCLDJ11LM',
|
|
1237
1237
|
description: 'Aqara curtain motor',
|
|
1238
1238
|
vendor: 'Xiaomi',
|
|
1239
|
-
fromZigbee: [fz.
|
|
1239
|
+
fromZigbee: [fz.xiaomi_basic, fz.xiaomi_curtain_position, fz.xiaomi_curtain_position_tilt],
|
|
1240
1240
|
toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_options],
|
|
1241
1241
|
exposes: [e.cover_position().setAccess('state', ea.ALL),
|
|
1242
1242
|
exposes.binary('running', ea.STATE, true, false)
|
|
1243
|
-
.withDescription('Whether the motor is moving or not')
|
|
1243
|
+
.withDescription('Whether the motor is moving or not'),
|
|
1244
|
+
exposes.enum('motor_state', ea.STATE, ['stopped', 'opening', 'closing'])
|
|
1245
|
+
.withDescription('Motor state')],
|
|
1244
1246
|
ota: ota.zigbeeOTA,
|
|
1245
1247
|
},
|
|
1246
1248
|
{
|
|
@@ -1248,7 +1250,7 @@ module.exports = [
|
|
|
1248
1250
|
model: 'SRSC-M01',
|
|
1249
1251
|
description: 'Aqara roller shade motor',
|
|
1250
1252
|
vendor: 'Xiaomi',
|
|
1251
|
-
fromZigbee: [fz.
|
|
1253
|
+
fromZigbee: [fz.xiaomi_basic, fz.xiaomi_curtain_position, fz.xiaomi_curtain_position_tilt],
|
|
1252
1254
|
toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_options],
|
|
1253
1255
|
exposes: [e.cover_position().setAccess('state', ea.ALL),
|
|
1254
1256
|
exposes.binary('running', ea.STATE, true, false)
|
|
@@ -1259,8 +1261,8 @@ module.exports = [
|
|
|
1259
1261
|
zigbeeModel: ['lumi.curtain.hagl04'],
|
|
1260
1262
|
model: 'ZNCLDJ12LM',
|
|
1261
1263
|
vendor: 'Xiaomi',
|
|
1262
|
-
description: 'Aqara B1 curtain motor
|
|
1263
|
-
fromZigbee: [fz.
|
|
1264
|
+
description: 'Aqara B1 curtain motor',
|
|
1265
|
+
fromZigbee: [fz.xiaomi_basic, fz.xiaomi_curtain_position, fz.battery, fz.xiaomi_curtain_position_tilt],
|
|
1264
1266
|
toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_options],
|
|
1265
1267
|
onEvent: async (type, data, device) => {
|
|
1266
1268
|
// The position (genAnalogOutput.presentValue) reported via an attribute contains an invaid value
|
|
@@ -1284,8 +1286,8 @@ module.exports = [
|
|
|
1284
1286
|
model: 'ZNJLBL01LM',
|
|
1285
1287
|
description: 'Aqara roller shade companion E1',
|
|
1286
1288
|
vendor: 'Xiaomi',
|
|
1287
|
-
fromZigbee: [fz.xiaomi_curtain_acn002_position, fz.xiaomi_curtain_acn002_status, fz.
|
|
1288
|
-
fz.aqara_opple],
|
|
1289
|
+
fromZigbee: [fz.xiaomi_curtain_acn002_position, fz.xiaomi_curtain_acn002_status, fz.xiaomi_curtain_position_tilt,
|
|
1290
|
+
fz.ignore_basic_report, fz.aqara_opple],
|
|
1289
1291
|
toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_acn002_battery, tz.xiaomi_curtain_acn002_charging_status],
|
|
1290
1292
|
exposes: [e.cover_position().setAccess('state', ea.ALL), e.battery().withAccess(ea.STATE_GET),
|
|
1291
1293
|
exposes.binary('charging_status', ea.STATE_GET, true, false)
|
package/lib/constants.js
CHANGED
|
@@ -97,6 +97,18 @@ const temperatureDisplayMode = {
|
|
|
97
97
|
1: 'fahrenheit',
|
|
98
98
|
};
|
|
99
99
|
|
|
100
|
+
const danfossAdaptationRunStatus= {
|
|
101
|
+
0: 'none',
|
|
102
|
+
1: 'in_progress',
|
|
103
|
+
2: 'found',
|
|
104
|
+
4: 'lost',
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const danfossAdaptationRunControl = {
|
|
108
|
+
1: 'initate_adaptation',
|
|
109
|
+
2: 'cancel_adaptation',
|
|
110
|
+
};
|
|
111
|
+
|
|
100
112
|
const danfossWindowOpen = {
|
|
101
113
|
0: 'quarantine',
|
|
102
114
|
1: 'closed',
|
|
@@ -267,6 +279,8 @@ module.exports = {
|
|
|
267
279
|
dayOfWeek,
|
|
268
280
|
fanMode,
|
|
269
281
|
temperatureDisplayMode,
|
|
282
|
+
danfossAdaptationRunControl,
|
|
283
|
+
danfossAdaptationRunStatus,
|
|
270
284
|
danfossWindowOpen,
|
|
271
285
|
danfossRoomStatusCode,
|
|
272
286
|
danfossOutputStatus,
|
package/lib/tuya.js
CHANGED
|
@@ -164,7 +164,7 @@ function convertStringToHexArray(value) {
|
|
|
164
164
|
// Default is 100 = open, 0 = closed; Devices listed here will use 0 = open, 100 = closed instead
|
|
165
165
|
// Use manufacturerName to identify device!
|
|
166
166
|
// Dont' invert _TZE200_cowvfni3: https://github.com/Koenkk/zigbee2mqtt/issues/6043
|
|
167
|
-
const coverPositionInvert = ['_TZE200_wmcdj3aq', '_TZE200_nogaemzt', '_TZE200_xuzcvlku', '_TZE200_xaabybja'];
|
|
167
|
+
const coverPositionInvert = ['_TZE200_wmcdj3aq', '_TZE200_nogaemzt', '_TZE200_xuzcvlku', '_TZE200_xaabybja', '_TZE200_rmymn92d'];
|
|
168
168
|
|
|
169
169
|
// Gets a boolean indicating whether the cover by this manufacturerName needs reversed positions
|
|
170
170
|
function isCoverInverted(manufacturerName) {
|
package/lib/xiaomi.js
CHANGED
|
@@ -408,6 +408,19 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
408
408
|
case '550':
|
|
409
409
|
payload.button_switch_mode = value === 1 ? 'relay_and_usb' : 'relay';
|
|
410
410
|
break;
|
|
411
|
+
case '1025':
|
|
412
|
+
payload.options = {...payload.options, // next values update only when curtain finished initial setup and knows current position
|
|
413
|
+
reverse_direction: value[2] == '\u0001',
|
|
414
|
+
hand_open: value[5] == '\u0000',
|
|
415
|
+
};
|
|
416
|
+
break;
|
|
417
|
+
case '1028':
|
|
418
|
+
payload = {...payload,
|
|
419
|
+
motor_state: (options.invert_cover ? {0: 'stopped', 1: 'closing', 2: 'opening'} :
|
|
420
|
+
{0: 'stopped', 1: 'opening', 2: 'closing'})[value],
|
|
421
|
+
running: !!value,
|
|
422
|
+
};
|
|
423
|
+
break;
|
|
411
424
|
case '1033':
|
|
412
425
|
if (['ZNJLBL01LM'].includes(model.model)) {
|
|
413
426
|
payload.charging_status = value === 1;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zigbee-herdsman-converters",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.462",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "zigbee-herdsman-converters",
|
|
9
|
-
"version": "14.0.
|
|
9
|
+
"version": "14.0.462",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"axios": "^0.26.1",
|