homebridge-evn-smartmeter 1.1.0 → 1.1.2
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/dist/accessories/currentMonitorAccessory.d.ts +2 -2
- package/dist/accessories/currentMonitorAccessory.js +6 -6
- package/dist/accessories/energyMeterAccessory.d.ts +2 -1
- package/dist/accessories/energyMeterAccessory.js +9 -5
- package/dist/mqtt/mqttClient.js +19 -14
- package/dist/platform.js +37 -17
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import { EVNSmartmeterPlatform } from '../platform';
|
|
|
3
3
|
import { EVNMQTTClient } from '../mqtt/mqttClient';
|
|
4
4
|
/**
|
|
5
5
|
* Current Monitor Accessory
|
|
6
|
-
* Displays current and power factor as
|
|
6
|
+
* Displays current and power factor as temperature sensors (°C = Ampere or Power Factor)
|
|
7
7
|
*/
|
|
8
8
|
export declare class CurrentMonitorAccessory {
|
|
9
9
|
private platform;
|
|
@@ -13,7 +13,7 @@ export declare class CurrentMonitorAccessory {
|
|
|
13
13
|
private cachedValues;
|
|
14
14
|
constructor(platform: EVNSmartmeterPlatform, accessory: PlatformAccessory, mqttClient: EVNMQTTClient);
|
|
15
15
|
/**
|
|
16
|
-
* Create a
|
|
16
|
+
* Create a temperature sensor for a current/power factor measurement
|
|
17
17
|
*/
|
|
18
18
|
private createSensor;
|
|
19
19
|
/**
|
|
@@ -5,7 +5,7 @@ const topicParser_1 = require("../mqtt/topicParser");
|
|
|
5
5
|
const types_1 = require("../config/types");
|
|
6
6
|
/**
|
|
7
7
|
* Current Monitor Accessory
|
|
8
|
-
* Displays current and power factor as
|
|
8
|
+
* Displays current and power factor as temperature sensors (°C = Ampere or Power Factor)
|
|
9
9
|
*/
|
|
10
10
|
class CurrentMonitorAccessory {
|
|
11
11
|
constructor(platform, accessory, mqttClient) {
|
|
@@ -20,7 +20,7 @@ class CurrentMonitorAccessory {
|
|
|
20
20
|
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'EVN')
|
|
21
21
|
.setCharacteristic(this.platform.Characteristic.Model, 'Kaifa Smartmeter - Current Monitor')
|
|
22
22
|
.setCharacteristic(this.platform.Characteristic.SerialNumber, 'CUR-001');
|
|
23
|
-
// Create
|
|
23
|
+
// Create temperature sensors for current and power factor measurements
|
|
24
24
|
this.createSensor('Current L1 (A)', types_1.MeasurementType.StromL1);
|
|
25
25
|
this.createSensor('Current L2 (A)', types_1.MeasurementType.StromL2);
|
|
26
26
|
this.createSensor('Current L3 (A)', types_1.MeasurementType.StromL3);
|
|
@@ -29,13 +29,13 @@ class CurrentMonitorAccessory {
|
|
|
29
29
|
this.mqttClient.on('measurement', this.handleMeasurement.bind(this));
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
|
-
* Create a
|
|
32
|
+
* Create a temperature sensor for a current/power factor measurement
|
|
33
33
|
*/
|
|
34
34
|
createSensor(name, type) {
|
|
35
35
|
const service = this.accessory.getService(name) ||
|
|
36
|
-
this.accessory.addService(this.platform.Service.
|
|
36
|
+
this.accessory.addService(this.platform.Service.TemperatureSensor, name, type);
|
|
37
37
|
service
|
|
38
|
-
.getCharacteristic(this.platform.Characteristic.
|
|
38
|
+
.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
|
|
39
39
|
.setProps({
|
|
40
40
|
minValue: 0,
|
|
41
41
|
maxValue: 100,
|
|
@@ -81,7 +81,7 @@ class CurrentMonitorAccessory {
|
|
|
81
81
|
const service = this.services.find((s) => s.subtype === measurementType);
|
|
82
82
|
if (service) {
|
|
83
83
|
const displayValue = this.getValue(measurementType);
|
|
84
|
-
service.getCharacteristic(this.platform.Characteristic.
|
|
84
|
+
service.getCharacteristic(this.platform.Characteristic.CurrentTemperature).updateValue(displayValue);
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
}
|
|
@@ -3,7 +3,7 @@ import { EVNSmartmeterPlatform } from '../platform';
|
|
|
3
3
|
import { EVNMQTTClient } from '../mqtt/mqttClient';
|
|
4
4
|
/**
|
|
5
5
|
* Energy Meter Accessory
|
|
6
|
-
* Displays cumulative energy values as light sensors (Lux =
|
|
6
|
+
* Displays cumulative energy values as light sensors (Lux = kWh)
|
|
7
7
|
*/
|
|
8
8
|
export declare class EnergyMeterAccessory {
|
|
9
9
|
private platform;
|
|
@@ -18,6 +18,7 @@ export declare class EnergyMeterAccessory {
|
|
|
18
18
|
private createSensor;
|
|
19
19
|
/**
|
|
20
20
|
* Get the current value for a measurement type
|
|
21
|
+
* Converts Wh to kWh by dividing by 1000 and rounds to whole number for 5-digit display
|
|
21
22
|
*/
|
|
22
23
|
private getValue;
|
|
23
24
|
/**
|
|
@@ -5,7 +5,7 @@ const topicParser_1 = require("../mqtt/topicParser");
|
|
|
5
5
|
const types_1 = require("../config/types");
|
|
6
6
|
/**
|
|
7
7
|
* Energy Meter Accessory
|
|
8
|
-
* Displays cumulative energy values as light sensors (Lux =
|
|
8
|
+
* Displays cumulative energy values as light sensors (Lux = kWh)
|
|
9
9
|
*/
|
|
10
10
|
class EnergyMeterAccessory {
|
|
11
11
|
constructor(platform, accessory, mqttClient) {
|
|
@@ -21,8 +21,8 @@ class EnergyMeterAccessory {
|
|
|
21
21
|
.setCharacteristic(this.platform.Characteristic.Model, 'Kaifa Smartmeter - Energy Meter')
|
|
22
22
|
.setCharacteristic(this.platform.Characteristic.SerialNumber, 'ENR-001');
|
|
23
23
|
// Create light sensors for energy measurements
|
|
24
|
-
this.createSensor('Energy Consumed (
|
|
25
|
-
this.createSensor('Energy Fed (
|
|
24
|
+
this.createSensor('Energy Consumed (kWh)', types_1.MeasurementType.WirkenergieP);
|
|
25
|
+
this.createSensor('Energy Fed (kWh)', types_1.MeasurementType.WirkenergieN);
|
|
26
26
|
// Subscribe to MQTT measurements
|
|
27
27
|
this.mqttClient.on('measurement', this.handleMeasurement.bind(this));
|
|
28
28
|
}
|
|
@@ -44,11 +44,15 @@ class EnergyMeterAccessory {
|
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
46
|
* Get the current value for a measurement type
|
|
47
|
+
* Converts Wh to kWh by dividing by 1000 and rounds to whole number for 5-digit display
|
|
47
48
|
*/
|
|
48
49
|
getValue(type) {
|
|
49
|
-
const
|
|
50
|
+
const whValue = this.cachedValues.get(type) ?? 0.0001;
|
|
51
|
+
// Convert Wh to kWh (divide by 1000) and round to whole number
|
|
52
|
+
// Example: 20885211 Wh → 20885.211 kWh → 20885
|
|
53
|
+
const kWhValue = Math.round(whValue / 1000);
|
|
50
54
|
// LightSensor requires value > 0, use 0.0001 as minimum
|
|
51
|
-
return Math.max(0.0001,
|
|
55
|
+
return Math.max(0.0001, kWhValue);
|
|
52
56
|
}
|
|
53
57
|
/**
|
|
54
58
|
* Handle incoming MQTT measurement
|
package/dist/mqtt/mqttClient.js
CHANGED
|
@@ -30,20 +30,25 @@ class EVNMQTTClient extends events_1.EventEmitter {
|
|
|
30
30
|
* Connect to MQTT broker
|
|
31
31
|
*/
|
|
32
32
|
connect() {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
try {
|
|
34
|
+
const brokerUrl = `mqtt://${this.broker}:${this.port}`;
|
|
35
|
+
const options = {
|
|
36
|
+
username: this.username,
|
|
37
|
+
password: this.password,
|
|
38
|
+
reconnectPeriod: 1000, // Start reconnect attempts after 1 second
|
|
39
|
+
connectTimeout: 10000, // 10 second connection timeout
|
|
40
|
+
rejectUnauthorized: false,
|
|
41
|
+
};
|
|
42
|
+
this.client = mqtt_1.default.connect(brokerUrl, options);
|
|
43
|
+
this.client.on('connect', () => this.handleConnect());
|
|
44
|
+
this.client.on('message', (topic, message) => this.handleMessage(topic, message));
|
|
45
|
+
this.client.on('error', (error) => this.handleError(error));
|
|
46
|
+
this.client.on('offline', () => this.handleOffline());
|
|
47
|
+
this.client.on('reconnect', () => this.handleReconnect());
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
this.emit('error', new Error(`Failed to create MQTT client: ${error}`));
|
|
51
|
+
}
|
|
47
52
|
}
|
|
48
53
|
/**
|
|
49
54
|
* Disconnect from MQTT broker
|
package/dist/platform.js
CHANGED
|
@@ -25,6 +25,7 @@ class EVNSmartmeterPlatform {
|
|
|
25
25
|
// Validate configuration
|
|
26
26
|
if (!this.config.mqtt?.broker) {
|
|
27
27
|
this.log.error('MQTT broker not configured! Please configure mqtt.broker in config.json');
|
|
28
|
+
this.log.error('Plugin will not be initialized. Please add MQTT configuration to config.json');
|
|
28
29
|
return;
|
|
29
30
|
}
|
|
30
31
|
this.log.info('EVN Smartmeter platform loaded');
|
|
@@ -33,12 +34,22 @@ class EVNSmartmeterPlatform {
|
|
|
33
34
|
// in order to ensure they weren't added to homebridge already. This event can also be used
|
|
34
35
|
// to start discovery of new accessories.
|
|
35
36
|
this.api.on('didFinishLaunching', () => {
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
try {
|
|
38
|
+
this.log.info('Finished launching, initializing platform');
|
|
39
|
+
this.initializePlatform();
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
this.log.error('Failed to initialize platform:', error);
|
|
43
|
+
}
|
|
38
44
|
});
|
|
39
45
|
// Clean up on shutdown
|
|
40
46
|
this.api.on('shutdown', () => {
|
|
41
|
-
|
|
47
|
+
try {
|
|
48
|
+
this.cleanup();
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
this.log.error('Error during cleanup:', error);
|
|
52
|
+
}
|
|
42
53
|
});
|
|
43
54
|
}
|
|
44
55
|
/**
|
|
@@ -96,21 +107,30 @@ class EVNSmartmeterPlatform {
|
|
|
96
107
|
* Register an accessory with Homebridge
|
|
97
108
|
*/
|
|
98
109
|
registerAccessory(name, AccessoryClass) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
110
|
+
try {
|
|
111
|
+
if (!this.mqttClient) {
|
|
112
|
+
this.log.error(`Cannot register accessory ${name}: MQTT client not initialized`);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const uuid = this.api.hap.uuid.generate(name);
|
|
116
|
+
const existingAccessory = this.accessories.find((acc) => acc.UUID === uuid);
|
|
117
|
+
if (existingAccessory) {
|
|
118
|
+
// Accessory already exists, restore it
|
|
119
|
+
this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);
|
|
120
|
+
new AccessoryClass(this, existingAccessory, this.mqttClient);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// Create new accessory
|
|
124
|
+
this.log.info('Adding new accessory:', name);
|
|
125
|
+
const accessory = new this.api.platformAccessory(name, uuid);
|
|
126
|
+
new AccessoryClass(this, accessory, this.mqttClient);
|
|
127
|
+
// Register the accessory
|
|
128
|
+
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
|
|
129
|
+
this.accessories.push(accessory);
|
|
130
|
+
}
|
|
105
131
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
this.log.info('Adding new accessory:', name);
|
|
109
|
-
const accessory = new this.api.platformAccessory(name, uuid);
|
|
110
|
-
new AccessoryClass(this, accessory, this.mqttClient);
|
|
111
|
-
// Register the accessory
|
|
112
|
-
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
|
|
113
|
-
this.accessories.push(accessory);
|
|
132
|
+
catch (error) {
|
|
133
|
+
this.log.error(`Failed to register accessory ${name}:`, error);
|
|
114
134
|
}
|
|
115
135
|
}
|
|
116
136
|
/**
|
package/package.json
CHANGED