diff --git a/src/WebApi_ws_live.cpp b/src/WebApi_ws_live.cpp
index e30ec313b..6ee77bfdb 100644
--- a/src/WebApi_ws_live.cpp
+++ b/src/WebApi_ws_live.cpp
@@ -302,6 +302,15 @@ void WebApiWsLiveClass::generateInverterChannelJsonResponse(JsonObject& root, st
addField(chanTypeObj, inv, t, c, FLD_PAC);
addField(chanTypeObj, inv, t, c, FLD_UAC);
addField(chanTypeObj, inv, t, c, FLD_IAC);
+ // Add HMT-specific 3-phase fields if available
+ if (t == TYPE_AC) {
+ addField(chanTypeObj, inv, t, c, FLD_UAC_1N);
+ addField(chanTypeObj, inv, t, c, FLD_UAC_2N);
+ addField(chanTypeObj, inv, t, c, FLD_UAC_3N);
+ addField(chanTypeObj, inv, t, c, FLD_IAC_1);
+ addField(chanTypeObj, inv, t, c, FLD_IAC_2);
+ addField(chanTypeObj, inv, t, c, FLD_IAC_3);
+ }
if (t == TYPE_INV) {
addField(chanTypeObj, inv, t, c, FLD_PDC, "Power DC");
} else {
diff --git a/webapp/src/components/InverterChannelInfo.vue b/webapp/src/components/InverterChannelInfo.vue
index b7ebc27ba..36d00342a 100644
--- a/webapp/src/components/InverterChannelInfo.vue
+++ b/webapp/src/components/InverterChannelInfo.vue
@@ -11,12 +11,17 @@
@@ -48,9 +53,10 @@ import { defineComponent, type PropType } from 'vue';
export default defineComponent({
props: {
- channelData: { type: Object as PropType
, required: true },
+ channelData: { type: Object as PropType>, required: true },
channelType: { type: String, required: true },
channelNumber: { type: Number, required: true },
+ phaseNumber: { type: Number, required: false },
},
});
diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json
index 44de8cc57..6b154c988 100644
--- a/webapp/src/locales/en.json
+++ b/webapp/src/locales/en.json
@@ -446,6 +446,7 @@
"inverterchannelinfo": {
"String": "String {num}",
"Phase": "Phase {num}",
+ "AC": "AC",
"General": "General"
},
"invertertotalinfo": {
diff --git a/webapp/src/types/LiveDataStatus.ts b/webapp/src/types/LiveDataStatus.ts
index 71da175a8..f702e05a2 100644
--- a/webapp/src/types/LiveDataStatus.ts
+++ b/webapp/src/types/LiveDataStatus.ts
@@ -19,6 +19,13 @@ export interface InverterStatistics {
ReactivePower?: ValueObject;
Efficiency?: ValueObject;
Irradiation?: ValueObject;
+ // 3-phase fields for HMT inverters
+ 'Voltage Ph1-N'?: ValueObject;
+ 'Voltage Ph2-N'?: ValueObject;
+ 'Voltage Ph3-N'?: ValueObject;
+ 'Current Ph1'?: ValueObject;
+ 'Current Ph2'?: ValueObject;
+ 'Current Ph3'?: ValueObject;
}
export interface RadioStatistics {
diff --git a/webapp/src/views/HomeView.vue b/webapp/src/views/HomeView.vue
index 69545f06e..61dc9610a 100644
--- a/webapp/src/views/HomeView.vue
+++ b/webapp/src/views/HomeView.vue
@@ -190,22 +190,15 @@
].reverse()"
>
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -528,7 +567,7 @@ import type { GridProfileRawdata } from '@/types/GridProfileRawdata';
import type { GridProfileStatus } from '@/types/GridProfileStatus';
import type { LimitConfig } from '@/types/LimitConfig';
import type { LimitStatus } from '@/types/LimitStatus';
-import type { Inverter, LiveData } from '@/types/LiveDataStatus';
+import type { Inverter, LiveData, InverterStatistics } from '@/types/LiveDataStatus';
import { authHeader, authUrl, handleResponse, isLoggedIn } from '@/utils/authentication';
import * as bootstrap from 'bootstrap';
import {
@@ -992,6 +1031,50 @@ export default defineComponent({
}
return this.$n(val_small / val_large, 'percent');
},
+ isThreePhaseInverter(inverter: Inverter): boolean {
+ // Check if the inverter has 3-phase specific fields
+ if (!inverter.AC || !inverter.AC[0]) {
+ return false;
+ }
+
+ const acData = inverter.AC[0];
+ // Look for 3-phase specific field names
+ const hasPhase1Voltage = !!acData['Voltage Ph1-N'];
+ const hasPhase2Voltage = !!acData['Voltage Ph2-N'];
+ const hasPhase3Voltage = !!acData['Voltage Ph3-N'];
+
+ return hasPhase1Voltage && hasPhase2Voltage && hasPhase3Voltage;
+ },
+ getPhaseDataWithPower(acData: InverterStatistics, phase: number): Partial {
+ // Extract data for a specific phase from the AC data with calculated power
+ const phaseData: Partial = {};
+
+ // Copy phase-specific voltage field
+ const voltageField = `Voltage Ph${phase}-N` as keyof InverterStatistics;
+ if (acData[voltageField]) {
+ phaseData.Voltage = acData[voltageField];
+ }
+
+ // Copy phase-specific current field
+ const currentField = `Current Ph${phase}` as keyof InverterStatistics;
+ if (acData[currentField]) {
+ phaseData.Current = acData[currentField];
+ }
+
+ // Calculate power for this phase: P = V * I * PowerFactor
+ if (phaseData.Voltage && phaseData.Current) {
+ const powerFactor = acData.PowerFactor?.v ?? 1; // Default to 1 if not available
+
+ phaseData.Power = {
+ v: phaseData.Voltage.v * phaseData.Current.v * powerFactor,
+ u: 'W',
+ d: 2,
+ max: 0,
+ };
+ }
+
+ return phaseData;
+ },
},
});