handler: Wire in Postgres store
This commit is contained in:
parent
72b0a690a6
commit
baa8ba7479
|
@ -31,7 +31,7 @@ func main() {
|
|||
}
|
||||
|
||||
store := store.NewSQL(db)
|
||||
handler := handler.NewHandler(store)
|
||||
handler := handler.New(store)
|
||||
srv := http.Server{
|
||||
ReadTimeout: time.Second * 3,
|
||||
WriteTimeout: time.Second * 3,
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"git.netflux.io/rob/solar-toolkit/inverter"
|
||||
)
|
||||
|
||||
const timestampMinimumYear = 2022
|
||||
|
||||
type Store interface {
|
||||
InsertETRuntimeData(*inverter.ETRuntimeData) error
|
||||
}
|
||||
|
@ -14,8 +19,47 @@ type Handler struct {
|
|||
store Store
|
||||
}
|
||||
|
||||
func NewHandler(store Store) *Handler { return &Handler{store: store} }
|
||||
func New(store Store) *Handler { return &Handler{store: store} }
|
||||
|
||||
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
if r.URL.Path != "/gateway/et_runtime_data" {
|
||||
http.Error(w, "endpoint not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
log.Printf("could not read body: %v", err)
|
||||
http.Error(w, "unexpected error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
var runtimeData inverter.ETRuntimeData
|
||||
err = json.Unmarshal(body, &runtimeData)
|
||||
if err != nil {
|
||||
log.Printf("could not unmarshal body: %v", err)
|
||||
http.Error(w, "unexpected error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if runtimeData.Timestamp.Year() < timestampMinimumYear {
|
||||
log.Printf("invalid timestamp: %v", runtimeData.Timestamp)
|
||||
http.Error(w, "invalid data", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err = h.store.InsertETRuntimeData(&runtimeData); err != nil {
|
||||
log.Printf("error storing data: %v", err)
|
||||
http.Error(w, "unexpected error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("content-type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("OK\n"))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
package handler_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.netflux.io/rob/solar-toolkit/gateway/handler"
|
||||
"git.netflux.io/rob/solar-toolkit/inverter"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type store struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (s *store) InsertETRuntimeData(*inverter.ETRuntimeData) error {
|
||||
return s.err
|
||||
}
|
||||
|
||||
func TestHandler(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
httpMethod string
|
||||
path string
|
||||
body string
|
||||
storeErr error
|
||||
wantStatusCode int
|
||||
wantBody string
|
||||
}{
|
||||
{
|
||||
name: "method not allowed",
|
||||
httpMethod: http.MethodGet,
|
||||
path: "/gateway/et_runtime_data",
|
||||
wantStatusCode: http.StatusMethodNotAllowed,
|
||||
wantBody: "method not allowed\n",
|
||||
},
|
||||
{
|
||||
name: "method not allowed",
|
||||
httpMethod: http.MethodPost,
|
||||
path: "/gateway/foo",
|
||||
wantStatusCode: http.StatusNotFound,
|
||||
wantBody: "endpoint not found\n",
|
||||
},
|
||||
{
|
||||
name: "invalid payload",
|
||||
httpMethod: http.MethodPost,
|
||||
path: "/gateway/et_runtime_data",
|
||||
body: `{`,
|
||||
wantStatusCode: http.StatusInternalServerError,
|
||||
wantBody: "unexpected error\n",
|
||||
},
|
||||
{
|
||||
name: "invalid timestamp",
|
||||
httpMethod: http.MethodPost,
|
||||
path: "/gateway/et_runtime_data",
|
||||
body: `{"timestamp": "1970-01-01T00:00:00Z"}`,
|
||||
wantStatusCode: http.StatusBadRequest,
|
||||
wantBody: "invalid data\n",
|
||||
},
|
||||
{
|
||||
name: "store error",
|
||||
httpMethod: http.MethodPost,
|
||||
path: "/gateway/et_runtime_data",
|
||||
body: `{"timestamp": "2022-01-01T00:00:00Z"}`,
|
||||
storeErr: errors.New("boom"),
|
||||
wantStatusCode: http.StatusInternalServerError,
|
||||
wantBody: "unexpected error\n",
|
||||
},
|
||||
{
|
||||
name: "OK",
|
||||
httpMethod: http.MethodPost,
|
||||
path: "/gateway/et_runtime_data",
|
||||
body: `{"timestamp": "2022-01-01T00:00:00Z"}`,
|
||||
wantStatusCode: http.StatusOK,
|
||||
wantBody: "OK\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
mockStore := store{err: tc.storeErr}
|
||||
handler := handler.New(&mockStore)
|
||||
req := httptest.NewRequest(tc.httpMethod, tc.path, strings.NewReader(tc.body))
|
||||
rec := httptest.NewRecorder()
|
||||
handler.ServeHTTP(rec, req)
|
||||
resp := rec.Result()
|
||||
defer resp.Body.Close()
|
||||
|
||||
assert.Equal(t, tc.wantStatusCode, resp.StatusCode)
|
||||
|
||||
if tc.wantBody != "" {
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tc.wantBody, string(body))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
DROP TABLE et_runtime_data;
|
|
@ -0,0 +1,78 @@
|
|||
CREATE TABLE et_runtime_data (
|
||||
timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
pv1_voltage DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
pv1_current DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
pv1_power DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
pv2_voltage DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
pv2_current DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
pv2_power DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
pv_power DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
pv2_mode INT NOT NULL DEFAULT 0,
|
||||
pv1_mode INT NOT NULL DEFAULT 0,
|
||||
on_grid_l1_voltage DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
on_grid_l1_current DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
on_grid_l1_frequency DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
on_grid_l1_power DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
on_grid_l2_voltage DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
on_grid_l2_current DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
on_grid_l2_frequency DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
on_grid_l2_power DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
on_grid_l3_voltage DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
on_grid_l3_current DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
on_grid_l3_frequency DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
on_grid_l3_power DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
grid_mode INT NOT NULL DEFAULT 0,
|
||||
total_inverter_power DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
active_power DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
reactive_power DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
apparent_power DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
backup_l1_voltage DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
backup_l1_current DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
backup_l1_frequency DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
load_mode_l1 INT NOT NULL DEFAULT 0,
|
||||
backup_l1_power DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
backup_l2_voltage DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
backup_l2_current DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
backup_l2_frequency DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
load_mode_l2 INT NOT NULL DEFAULT 0,
|
||||
backup_l2_power DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
backup_l3_voltage DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
backup_l3_current DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
backup_l3_frequency DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
load_mode_l3 INT NOT NULL DEFAULT 0,
|
||||
backup_l3_power DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
load_l1 DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
load_l2 DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
load_l3 DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
backup_load DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
load DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
ups_load DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
temperature_air DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
temperature_module DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
temperature DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
bus_voltage DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
nbus_voltage DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
battery_voltage DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
battery_current DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
battery_mode INT NOT NULL DEFAULT 0,
|
||||
warning_code INT NOT NULL DEFAULT 0,
|
||||
safety_country_code INT NOT NULL DEFAULT 0,
|
||||
work_mode INT NOT NULL DEFAULT 0,
|
||||
operation_code INT NOT NULL DEFAULT 0,
|
||||
energy_generation_total DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
energy_generation_today DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
energy_export_total DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
energy_export_total_hours DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
energy_export_today DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
energy_import_total DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
energy_import_today DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
energy_load_total DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
energy_load_day DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
battery_charge_total DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
battery_charge_today DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
battery_discharge_total DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
battery_discharge_today DOUBLE PRECISION NOT NULL DEFAULT 0.0,
|
||||
house_consumption DOUBLE PRECISION NOT NULL DEFAULT 0.0
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX index_et_runtime_data_on_timestamp ON et_runtime_data (timestamp);
|
|
@ -1,6 +1,8 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.netflux.io/rob/solar-toolkit/inverter"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
@ -13,6 +15,12 @@ func NewSQL(db *sqlx.DB) *PostgresStore {
|
|||
return &PostgresStore{db: db}
|
||||
}
|
||||
|
||||
const insertSql = `INSERT INTO et_runtime_data (timestamp, pv1_voltage, pv1_current, pv1_power, pv2_voltage, pv2_current, pv2_power, pv_power, pv2_mode, pv1_mode, on_grid_l1_voltage, on_grid_l1_current, on_grid_l1_frequency, on_grid_l1_power, on_grid_l2_voltage, on_grid_l2_current, on_grid_l2_frequency, on_grid_l2_power, on_grid_l3_voltage, on_grid_l3_current, on_grid_l3_frequency, on_grid_l3_power, grid_mode, total_inverter_power, active_power, reactive_power, apparent_power, backup_l1_voltage, backup_l1_current, backup_l1_frequency, load_mode_l1, backup_l1_power, backup_l2_voltage, backup_l2_current, backup_l2_frequency, load_mode_l2, backup_l2_power, backup_l3_voltage, backup_l3_current, backup_l3_frequency, load_mode_l3, backup_l3_power, load_l1, load_l2, load_l3, backup_load, load, ups_load, temperature_air, temperature_module, temperature, bus_voltage, nbus_voltage, battery_voltage, battery_current, battery_mode, warning_code, safety_country_code, work_mode, operation_code, energy_generation_total, energy_generation_today, energy_export_total, energy_export_total_hours, energy_export_today, energy_import_total, energy_import_today, energy_load_total, energy_load_day, battery_charge_total, battery_charge_today, battery_discharge_total, battery_discharge_today, house_consumption) VALUES (:timestamp, :pv1_voltage, :pv1_current, :pv1_power, :pv2_voltage, :pv2_current, :pv2_power, :pv_power, :pv2_mode, :pv1_mode, :on_grid_l1_voltage, :on_grid_l1_current, :on_grid_l1_frequency, :on_grid_l1_power, :on_grid_l2_voltage, :on_grid_l2_current, :on_grid_l2_frequency, :on_grid_l2_power, :on_grid_l3_voltage, :on_grid_l3_current, :on_grid_l3_frequency, :on_grid_l3_power, :grid_mode, :total_inverter_power, :active_power, :reactive_power, :apparent_power, :backup_l1_voltage, :backup_l1_current, :backup_l1_frequency, :load_mode_l1, :backup_l1_power, :backup_l2_voltage, :backup_l2_current, :backup_l2_frequency, :load_mode_l2, :backup_l2_power, :backup_l3_voltage, :backup_l3_current, :backup_l3_frequency, :load_mode_l3, :backup_l3_power, :load_l1, :load_l2, :load_l3, :backup_load, :load, :ups_load, :temperature_air, :temperature_module, :temperature, :bus_voltage, :nbus_voltage, :battery_voltage, :battery_current, :battery_mode, :warning_code, :safety_country_code, :work_mode, :operation_code, :energy_generation_total, :energy_generation_today, :energy_export_total, :energy_export_total_hours, :energy_export_today, :energy_import_total, :energy_import_today, :energy_load_total, :energy_load_day, :battery_charge_total, :battery_charge_today, :battery_discharge_total, :battery_discharge_today, :house_consumption);`
|
||||
|
||||
func (s *PostgresStore) InsertETRuntimeData(runtimeData *inverter.ETRuntimeData) error {
|
||||
if _, err := s.db.NamedExec(insertSql, runtimeData); err != nil {
|
||||
return fmt.Errorf("error inserting data: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -58,81 +58,81 @@ type DeviceInfo struct {
|
|||
}
|
||||
|
||||
type ETRuntimeData struct {
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
PV1Voltage Voltage `json:"pv1_voltage"`
|
||||
PV1Current Current `json:"pv1_current"`
|
||||
PV1Power Power `json:"pv1_power"`
|
||||
PV2Voltage Voltage `json:"pv2_voltage"`
|
||||
PV2Current Current `json:"pv2_current"`
|
||||
PV2Power Power `json:"pv2_power"`
|
||||
PVPower Power `json:"pv_power"`
|
||||
PV2Mode byte `json:"pv2_mode"`
|
||||
PV1Mode byte `json:"pv1_mode"`
|
||||
OnGridL1Voltage Voltage `json:"on_grid_l1_voltage"`
|
||||
OnGridL1Current Current `json:"on_grid_l1_current"`
|
||||
OnGridL1Frequency Frequency `json:"on_grid_l1_frequency"`
|
||||
OnGridL1Power Power `json:"on_grid_l1_power"`
|
||||
OnGridL2Voltage Voltage `json:"on_grid_l2_voltage"`
|
||||
OnGridL2Current Current `json:"on_grid_l2_current"`
|
||||
OnGridL2Frequency Frequency `json:"on_grid_l2_frequency"`
|
||||
OnGridL2Power Power `json:"on_grid_l2_power"`
|
||||
OnGridL3Voltage Voltage `json:"on_grid_l3_voltage"`
|
||||
OnGridL3Current Current `json:"on_grid_l3_current"`
|
||||
OnGridL3Frequency Frequency `json:"on_grid_l3_frequency"`
|
||||
OnGridL3Power Power `json:"on_grid_l3_power"`
|
||||
GridMode int `json:"grid_mode"`
|
||||
TotalInverterPower Power `json:"total_inverter_power"`
|
||||
ActivePower Power `json:"active_power"`
|
||||
ReactivePower int `json:"reactive_power"`
|
||||
ApparentPower int `json:"apparent_power"`
|
||||
BackupL1Voltage Voltage `json:"backup_l1_voltage"`
|
||||
BackupL1Current Current `json:"backup_l1_current"`
|
||||
BackupL1Frequency Frequency `json:"backup_l1_frequency"`
|
||||
LoadModeL1 int `json:"load_mode_l1"`
|
||||
BackupL1Power Power `json:"backup_l1_power"`
|
||||
BackupL2Voltage Voltage `json:"backup_l2_voltage"`
|
||||
BackupL2Current Current `json:"backup_l2_current"`
|
||||
BackupL2Frequency Frequency `json:"backup_l2_frequency"`
|
||||
LoadModeL2 int `json:"load_mode_l2"`
|
||||
BackupL2Power Power `json:"backup_l2_power"`
|
||||
BackupL3Voltage Voltage `json:"backup_l3_voltage"`
|
||||
BackupL3Current Current `json:"backup_l3_current"`
|
||||
BackupL3Frequency Frequency `json:"backup_l3_frequency"`
|
||||
LoadModeL3 int `json:"load_mode_l3"`
|
||||
BackupL3Power Power `json:"backup_l3_power"`
|
||||
LoadL1 Power `json:"load_l1"`
|
||||
LoadL2 Power `json:"load_l2"`
|
||||
LoadL3 Power `json:"load_l3"`
|
||||
BackupLoad Power `json:"backup_load"`
|
||||
Load Power `json:"load"`
|
||||
UPSLoad int `json:"ups_load"`
|
||||
TemperatureAir Temp `json:"temperature_air"`
|
||||
TemperatureModule Temp `json:"temperature_module"`
|
||||
Temperature Temp `json:"temperature"`
|
||||
FunctionBit int `json:"-"`
|
||||
BusVoltage Voltage `json:"bus_voltage"`
|
||||
NBusVoltage Voltage `json:"nbus_voltage"`
|
||||
BatteryVoltage Voltage `json:"battery_voltage"`
|
||||
BatteryCurrent Current `json:"battery_current"`
|
||||
BatteryMode int `json:"battery_mode"`
|
||||
WarningCode int `json:"warning_code"`
|
||||
SafetyCountryCode int `json:"safety_country_code"`
|
||||
WorkMode int `json:"work_mode"`
|
||||
OperationCode int `json:"operation_code"`
|
||||
ErrorCodes int `json:"-"`
|
||||
EnergyGenerationTotal Energy `json:"energy_generation_total"`
|
||||
EnergyGenerationToday Energy `json:"energy_generation_today"`
|
||||
EnergyExportTotal Energy `json:"energy_export_total"`
|
||||
EnergyExportTotalHours int `json:"energy_export_total_hours"`
|
||||
EnergyExportToday Energy `json:"energy_export_today"`
|
||||
EnergyImportTotal Energy `json:"energy_import_total"`
|
||||
EnergyImportToday Energy `json:"energy_import_today"`
|
||||
EnergyLoadTotal Energy `json:"energy_load_total"`
|
||||
EnergyLoadDay Energy `json:"energy_load_day"`
|
||||
BatteryChargeTotal int `json:"battery_charge_total"`
|
||||
BatteryChargeToday int `json:"battery_charge_today"`
|
||||
BatteryDischargeTotal int `json:"battery_discharge_total"`
|
||||
BatteryDischargeToday int `json:"battery_discharge_today"`
|
||||
DiagStatusCode int `json:"-"`
|
||||
HouseConsumption Power `json:"house_consumption"`
|
||||
Timestamp time.Time `json:"timestamp" db:"timestamp"`
|
||||
PV1Voltage Voltage `json:"pv1_voltage" db:"pv1_voltage"`
|
||||
PV1Current Current `json:"pv1_current" db:"pv1_current"`
|
||||
PV1Power Power `json:"pv1_power" db:"pv1_power"`
|
||||
PV2Voltage Voltage `json:"pv2_voltage" db:"pv2_voltage"`
|
||||
PV2Current Current `json:"pv2_current" db:"pv2_current"`
|
||||
PV2Power Power `json:"pv2_power" db:"pv2_power"`
|
||||
PVPower Power `json:"pv_power" db:"pv_power"`
|
||||
PV2Mode byte `json:"pv2_mode" db:"pv2_mode"`
|
||||
PV1Mode byte `json:"pv1_mode" db:"pv1_mode"`
|
||||
OnGridL1Voltage Voltage `json:"on_grid_l1_voltage" db:"on_grid_l1_voltage"`
|
||||
OnGridL1Current Current `json:"on_grid_l1_current" db:"on_grid_l1_current"`
|
||||
OnGridL1Frequency Frequency `json:"on_grid_l1_frequency" db:"on_grid_l1_frequency"`
|
||||
OnGridL1Power Power `json:"on_grid_l1_power" db:"on_grid_l1_power"`
|
||||
OnGridL2Voltage Voltage `json:"on_grid_l2_voltage" db:"on_grid_l2_voltage"`
|
||||
OnGridL2Current Current `json:"on_grid_l2_current" db:"on_grid_l2_current"`
|
||||
OnGridL2Frequency Frequency `json:"on_grid_l2_frequency" db:"on_grid_l2_frequency"`
|
||||
OnGridL2Power Power `json:"on_grid_l2_power" db:"on_grid_l2_power"`
|
||||
OnGridL3Voltage Voltage `json:"on_grid_l3_voltage" db:"on_grid_l3_voltage"`
|
||||
OnGridL3Current Current `json:"on_grid_l3_current" db:"on_grid_l3_current"`
|
||||
OnGridL3Frequency Frequency `json:"on_grid_l3_frequency" db:"on_grid_l3_frequency"`
|
||||
OnGridL3Power Power `json:"on_grid_l3_power" db:"on_grid_l3_power"`
|
||||
GridMode int `json:"grid_mode" db:"grid_mode"`
|
||||
TotalInverterPower Power `json:"total_inverter_power" db:"total_inverter_power"`
|
||||
ActivePower Power `json:"active_power" db:"active_power"`
|
||||
ReactivePower int `json:"reactive_power" db:"reactive_power"`
|
||||
ApparentPower int `json:"apparent_power" db:"apparent_power"`
|
||||
BackupL1Voltage Voltage `json:"backup_l1_voltage" db:"backup_l1_voltage"`
|
||||
BackupL1Current Current `json:"backup_l1_current" db:"backup_l1_current"`
|
||||
BackupL1Frequency Frequency `json:"backup_l1_frequency" db:"backup_l1_frequency"`
|
||||
LoadModeL1 int `json:"load_mode_l1" db:"load_mode_l1"`
|
||||
BackupL1Power Power `json:"backup_l1_power" db:"backup_l1_power"`
|
||||
BackupL2Voltage Voltage `json:"backup_l2_voltage" db:"backup_l2_voltage"`
|
||||
BackupL2Current Current `json:"backup_l2_current" db:"backup_l2_current"`
|
||||
BackupL2Frequency Frequency `json:"backup_l2_frequency" db:"backup_l2_frequency"`
|
||||
LoadModeL2 int `json:"load_mode_l2" db:"load_mode_l2"`
|
||||
BackupL2Power Power `json:"backup_l2_power" db:"backup_l2_power"`
|
||||
BackupL3Voltage Voltage `json:"backup_l3_voltage" db:"backup_l3_voltage"`
|
||||
BackupL3Current Current `json:"backup_l3_current" db:"backup_l3_current"`
|
||||
BackupL3Frequency Frequency `json:"backup_l3_frequency" db:"backup_l3_frequency"`
|
||||
LoadModeL3 int `json:"load_mode_l3" db:"load_mode_l3"`
|
||||
BackupL3Power Power `json:"backup_l3_power" db:"backup_l3_power"`
|
||||
LoadL1 Power `json:"load_l1" db:"load_l1"`
|
||||
LoadL2 Power `json:"load_l2" db:"load_l2"`
|
||||
LoadL3 Power `json:"load_l3" db:"load_l3"`
|
||||
BackupLoad Power `json:"backup_load" db:"backup_load"`
|
||||
Load Power `json:"load" db:"load"`
|
||||
UPSLoad int `json:"ups_load" db:"ups_load"`
|
||||
TemperatureAir Temp `json:"temperature_air" db:"temperature_air"`
|
||||
TemperatureModule Temp `json:"temperature_module" db:"temperature_module"`
|
||||
Temperature Temp `json:"temperature" db:"temperature"`
|
||||
FunctionBit int `json:"-" db:"-"`
|
||||
BusVoltage Voltage `json:"bus_voltage" db:"bus_voltage"`
|
||||
NBusVoltage Voltage `json:"nbus_voltage" db:"nbus_voltage"`
|
||||
BatteryVoltage Voltage `json:"battery_voltage" db:"battery_voltage"`
|
||||
BatteryCurrent Current `json:"battery_current" db:"battery_current"`
|
||||
BatteryMode int `json:"battery_mode" db:"battery_mode"`
|
||||
WarningCode int `json:"warning_code" db:"warning_code"`
|
||||
SafetyCountryCode int `json:"safety_country_code" db:"safety_country_code"`
|
||||
WorkMode int `json:"work_mode" db:"work_mode"`
|
||||
OperationCode int `json:"operation_code" db:"operation_code"`
|
||||
ErrorCodes int `json:"-" db:"-"`
|
||||
EnergyGenerationTotal Energy `json:"energy_generation_total" db:"energy_generation_total"`
|
||||
EnergyGenerationToday Energy `json:"energy_generation_today" db:"energy_generation_today"`
|
||||
EnergyExportTotal Energy `json:"energy_export_total" db:"energy_export_total"`
|
||||
EnergyExportTotalHours int `json:"energy_export_total_hours" db:"energy_export_total_hours"`
|
||||
EnergyExportToday Energy `json:"energy_export_today" db:"energy_export_today"`
|
||||
EnergyImportTotal Energy `json:"energy_import_total" db:"energy_import_total"`
|
||||
EnergyImportToday Energy `json:"energy_import_today" db:"energy_import_today"`
|
||||
EnergyLoadTotal Energy `json:"energy_load_total" db:"energy_load_total"`
|
||||
EnergyLoadDay Energy `json:"energy_load_day" db:"energy_load_day"`
|
||||
BatteryChargeTotal int `json:"battery_charge_total" db:"battery_charge_total"`
|
||||
BatteryChargeToday int `json:"battery_charge_today" db:"battery_charge_today"`
|
||||
BatteryDischargeTotal int `json:"battery_discharge_total" db:"battery_discharge_total"`
|
||||
BatteryDischargeToday int `json:"battery_discharge_today" db:"battery_discharge_today"`
|
||||
DiagStatusCode int `json:"-" db:"-"`
|
||||
HouseConsumption Power `json:"house_consumption" db:"house_consumption"`
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue