Support MeterDiv involvement in Watt calculation.

This commit is contained in:
Victor Chang
2024-06-13 23:55:03 -07:00
parent 5ac97c9e90
commit b47be0769f
2 changed files with 22 additions and 10 deletions

View File

@@ -102,7 +102,7 @@ Blank cells have never been seen to be anything other than zero. Some cells have
<tr> <th>12</th> <td colspan=1></td><td colspan=1 align="center">0x01</td><td colspan=2></td></tr> <tr> <th>12</th> <td colspan=1></td><td colspan=1 align="center">0x01</td><td colspan=2></td></tr>
<tr> <th>16</th> <td colspan=1 align="center">0x25</td><td colspan=3 align="center">ExportWh~</td></tr> <tr> <th>16</th> <td colspan=1 align="center">0x25</td><td colspan=3 align="center">ExportWh~</td></tr>
<tr> <th>20</th> <td colspan=1 align="center">~ExportWh</td><td colspan=2></td><td colspan=1 align="center">0x01</td></tr> <tr> <th>20</th> <td colspan=1 align="center">~ExportWh</td><td colspan=2></td><td colspan=1 align="center">0x01</td></tr>
<tr> <th>24</th> <td colspan=1 align="center">0x03</td><td colspan=1></td><td colspan=1 align="center">0x22</td><td colspan=1 align="center">0x01</td></tr> <tr> <th>24</th> <td colspan=1 align="center">0x03</td><td colspan=1></td><td colspan=1 align="center">0x22</td><td colspan=1 align="center">MeterDiv</td></tr>
<tr> <th>28</th> <td colspan=2></td><td colspan=1 align="center">0x02</td><td colspan=1 align="center">0x03</td></tr> <tr> <th>28</th> <td colspan=2></td><td colspan=1 align="center">0x02</td><td colspan=1 align="center">0x03</td></tr>
<tr> <th>32</th> <td colspan=1></td><td colspan=1 align="center">0x22</td><td colspan=2 align="center">EnergyCostUnit</td></tr> <tr> <th>32</th> <td colspan=1></td><td colspan=1 align="center">0x22</td><td colspan=2 align="center">EnergyCostUnit</td></tr>
<tr> <th>36</th> <td colspan=1></td><td colspan=1></td><td colspan=1 align="center">0x04</td><td colspan=1></td></tr> <tr> <th>36</th> <td colspan=1></td><td colspan=1></td><td colspan=1 align="center">0x04</td><td colspan=1></td></tr>
@@ -123,20 +123,26 @@ Bytes 17 to 20, (32 bit int, probably unsigned, LSB)
Cumulative watt-hours sent to the grid. Unknown when the value resets, but probably never resets since ESP32 never sends a clock sync to the MGM111 so it likely just rolls over. Cumulative watt-hours sent to the grid. Unknown when the value resets, but probably never resets since ESP32 never sends a clock sync to the MGM111 so it likely just rolls over.
#### PowerVal #### MeterDiv
Bytes 41 and 43 (24 bit signed int, LSB) Byte 27
The power being sent or consumed at this moment. This is in watts for me but I know in the V2 payload that there is a `MeterDiv`, which means `PowerVal` might be a multiplication of the real wattage. If V7 also has this behavior then `MeterDiv` must have a value of 1 in my readings. So, `MeterDiv` might be byte 2, 13, 23, or 27. Used in conjunction with `EnergyCostUnit` and `PowerVal` to calculate the actual wattage.
#### EnergyCostUnit(?) #### EnergyCostUnit
Bytes 34 and 35 LSB Bytes 34 and 35 LSB
Usually `0xE803`, which is `0x03E8` = `1000`. Continuing the V2 theorization that this is the number of watt-hour units per "cost unit". Usually `0xE803`, which is `0x03E8` = `1000`. Continuing the V2 theorization that this is the number of watt-hour units per "cost unit".
Since people are typically charged per kWh, this value is typically 1000. Since people are typically charged per kWh, this value is typically 1000.
This value is not currently used in the code. #### PowerVal
Bytes 41 and 43 (24 bit signed int, LSB)
The power being sent or consumed at this moment. The actual wattage is calculated with the formula:
`Watts = PowerVal * MeterDiv / (EnergyCostUnit / 1000)`
#### Incrementor #### Incrementor

View File

@@ -82,7 +82,9 @@ class EmporiaVueUtility : public PollingComponent, public uart::UARTDevice {
uint32_t import_wh; // Payload Bytes 7 to 10 uint32_t import_wh; // Payload Bytes 7 to 10
byte unknown11[6]; // Payload Bytes 11 to 16 byte unknown11[6]; // Payload Bytes 11 to 16
uint32_t export_wh; // Payload Bytes 17 to 20 uint32_t export_wh; // Payload Bytes 17 to 20
byte unknown21[13]; // Payload Bytes 21 to 33 byte unknown21[6]; // Payload Bytes 21 to 26
uint8_t meter_div; // Payload Byte 27
byte unknown28[6]; // Payload Bytes 28 to 33
uint16_t cost_unit; // Payload Bytes 34 to 35 uint16_t cost_unit; // Payload Bytes 34 to 35
byte unknown36[4]; // Payload Bytes 36 to 39 byte unknown36[4]; // Payload Bytes 36 to 39
uint32_t watts; // Payload Bytes 40 to 43 : Starts with 0x2A, only use the uint32_t watts; // Payload Bytes 40 to 43 : Starts with 0x2A, only use the
@@ -351,13 +353,14 @@ class EmporiaVueUtility : public PollingComponent, public uart::UARTDevice {
} }
cost_unit = mr7->cost_unit; cost_unit = mr7->cost_unit;
watts = parse_meter_watts_v7(mr7->watts); watts = parse_meter_watts_v7(mr7);
watt_hours = parse_meter_watt_hours_v7(mr7); watt_hours = parse_meter_watt_hours_v7(mr7);
// Extra debugging of non-zero bytes, only on first packet or if // Extra debugging of non-zero bytes, only on first packet or if
// debug_ is true // debug_ is true
if ((debug_) || (last_meter_reading == 0)) { if ((debug_) || (last_meter_reading == 0)) {
ESP_LOGD(TAG, "Meter Cost Unit: %d", cost_unit); ESP_LOGD(TAG, "Meter Cost Unit: %d", cost_unit);
ESP_LOGD(TAG, "Meter Divisor: %d", mr7->meter_div);
ESP_LOGD(TAG, "Meter Energy Import Flags: %08x", mr7->import_wh); ESP_LOGD(TAG, "Meter Energy Import Flags: %08x", mr7->import_wh);
ESP_LOGD(TAG, "Meter Energy Export Flags: %08x", mr7->export_wh); ESP_LOGD(TAG, "Meter Energy Export Flags: %08x", mr7->export_wh);
ESP_LOGD(TAG, "Meter Power Flags: %08x", mr7->watts); ESP_LOGD(TAG, "Meter Power Flags: %08x", mr7->watts);
@@ -620,10 +623,13 @@ class EmporiaVueUtility : public PollingComponent, public uart::UARTDevice {
* *
* For MGM version 7 and 8 * For MGM version 7 and 8
*/ */
float parse_meter_watts_v7(int32_t watts) { float parse_meter_watts_v7(struct MeterReadingV7 *mr) {
// Read the instant watts value // Read the instant watts value
// (it's actually a 24-bit int) // (it's actually a 24-bit int)
watts >>= 8; int32_t watts_raw = mr->watts;
watts_raw >>= 8;
float watts = ((float)watts_raw * (float)mr->meter_div) /
((float)mr->cost_unit / 1000.0);
if ((watts >= WATTS_MAX) || (watts < WATTS_MIN)) { if ((watts >= WATTS_MAX) || (watts < WATTS_MIN)) {
ESP_LOGE(TAG, "Unreasonable watts value %d", watts); ESP_LOGE(TAG, "Unreasonable watts value %d", watts);