Merge branch 'dev-herf' into dev
This commit is contained in:
commit
103207cead
@ -75,3 +75,6 @@ Generated using: `git log --date=short --pretty=format:"* %h%x09%ad%x09%s" | gre
|
||||
| TSUN TSOL-M350 | NRF24L01+ | 1 | 1 | 1 |
|
||||
| TSUN TSOL-M800 | NRF24L01+ | 2 | 2 | 1 |
|
||||
| TSUN TSOL-M1600 | NRF24L01+ | 4 | 2 | 1 |
|
||||
| E-Star HERF-800 | NRF24L01+ | 2 | 2 | 1 |
|
||||
| E-Star HERF-1600 | NRF24L01+ | 4 | 2 | 1 |
|
||||
| E-Star HERF-1800 | NRF24L01+ | 4 | 2 | 1 |
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2022-2023 Thomas Basler and others
|
||||
* Copyright (C) 2022-2024 Thomas Basler and others
|
||||
*/
|
||||
#include "Hoymiles.h"
|
||||
#include "Utils.h"
|
||||
#include "inverters/HERF_2CH.h"
|
||||
#include "inverters/HERF_4CH.h"
|
||||
#include "inverters/HMS_1CH.h"
|
||||
#include "inverters/HMS_1CHv2.h"
|
||||
#include "inverters/HMS_2CH.h"
|
||||
@ -168,6 +170,10 @@ std::shared_ptr<InverterAbstract> HoymilesClass::addInverter(const char* name, c
|
||||
i = std::make_shared<HM_2CH>(_radioNrf.get(), serial);
|
||||
} else if (HM_1CH::isValidSerial(serial)) {
|
||||
i = std::make_shared<HM_1CH>(_radioNrf.get(), serial);
|
||||
} else if (HERF_2CH::isValidSerial(serial)) {
|
||||
i = std::make_shared<HERF_2CH>(_radioNrf.get(), serial);
|
||||
} else if (HERF_4CH::isValidSerial(serial)) {
|
||||
i = std::make_shared<HERF_4CH>(_radioNrf.get(), serial);
|
||||
}
|
||||
|
||||
if (i) {
|
||||
@ -271,4 +277,4 @@ void HoymilesClass::setMessageOutput(Print* output)
|
||||
Print* HoymilesClass::getMessageOutput()
|
||||
{
|
||||
return _messageOutput;
|
||||
}
|
||||
}
|
||||
|
||||
62
lib/Hoymiles/src/inverters/HERF_2CH.cpp
Normal file
62
lib/Hoymiles/src/inverters/HERF_2CH.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2022-2024 Thomas Basler and others
|
||||
*/
|
||||
#include "HERF_2CH.h"
|
||||
|
||||
static const byteAssign_t byteAssignment[] = {
|
||||
{ TYPE_DC, CH0, FLD_UDC, UNIT_V, 2, 2, 10, false, 1 },
|
||||
{ TYPE_DC, CH0, FLD_IDC, UNIT_A, 6, 2, 100, false, 2 },
|
||||
{ TYPE_DC, CH0, FLD_PDC, UNIT_W, 10, 2, 10, false, 1 },
|
||||
{ TYPE_DC, CH0, FLD_YD, UNIT_WH, 22, 2, 1, false, 0 },
|
||||
{ TYPE_DC, CH0, FLD_YT, UNIT_KWH, 14, 4, 1000, false, 3 },
|
||||
{ TYPE_DC, CH0, FLD_IRR, UNIT_PCT, CALC_CH_IRR, CH0, CMD_CALC, false, 3 },
|
||||
|
||||
{ TYPE_DC, CH1, FLD_UDC, UNIT_V, 4, 2, 10, false, 1 },
|
||||
{ TYPE_DC, CH1, FLD_IDC, UNIT_A, 8, 2, 100, false, 2 },
|
||||
{ TYPE_DC, CH1, FLD_PDC, UNIT_W, 12, 2, 10, false, 1 },
|
||||
{ TYPE_DC, CH1, FLD_YD, UNIT_WH, 24, 2, 1, false, 0 },
|
||||
{ TYPE_DC, CH1, FLD_YT, UNIT_KWH, 18, 4, 1000, false, 3 },
|
||||
{ TYPE_DC, CH1, FLD_IRR, UNIT_PCT, CALC_CH_IRR, CH1, CMD_CALC, false, 3 },
|
||||
|
||||
{ TYPE_AC, CH0, FLD_UAC, UNIT_V, 26, 2, 10, false, 1 },
|
||||
{ TYPE_AC, CH0, FLD_IAC, UNIT_A, 34, 2, 100, false, 2 },
|
||||
{ TYPE_AC, CH0, FLD_PAC, UNIT_W, 30, 2, 10, false, 1 },
|
||||
{ TYPE_AC, CH0, FLD_Q, UNIT_VAR, 32, 2, 10, false, 1 },
|
||||
{ TYPE_AC, CH0, FLD_F, UNIT_HZ, 28, 2, 100, false, 2 },
|
||||
{ TYPE_AC, CH0, FLD_PF, UNIT_NONE, 36, 2, 1000, false, 3 },
|
||||
|
||||
{ TYPE_INV, CH0, FLD_T, UNIT_C, 38, 2, 10, true, 1 },
|
||||
{ TYPE_INV, CH0, FLD_EVT_LOG, UNIT_NONE, 40, 2, 1, false, 0 },
|
||||
|
||||
{ TYPE_INV, CH0, FLD_YD, UNIT_WH, CALC_TOTAL_YD, 0, CMD_CALC, false, 0 },
|
||||
{ TYPE_INV, CH0, FLD_YT, UNIT_KWH, CALC_TOTAL_YT, 0, CMD_CALC, false, 3 },
|
||||
{ TYPE_INV, CH0, FLD_PDC, UNIT_W, CALC_TOTAL_PDC, 0, CMD_CALC, false, 1 },
|
||||
{ TYPE_INV, CH0, FLD_EFF, UNIT_PCT, CALC_TOTAL_EFF, 0, CMD_CALC, false, 3 }
|
||||
};
|
||||
|
||||
HERF_2CH::HERF_2CH(HoymilesRadio* radio, const uint64_t serial)
|
||||
: HM_Abstract(radio, serial) {};
|
||||
|
||||
bool HERF_2CH::isValidSerial(const uint64_t serial)
|
||||
{
|
||||
// serial >= 0x282100000000 && serial <= 0x282199999999
|
||||
uint16_t preSerial = (serial >> 32) & 0xffff;
|
||||
return preSerial == 0x2821;
|
||||
}
|
||||
|
||||
String HERF_2CH::typeName() const
|
||||
{
|
||||
return "HERF-800-2T";
|
||||
}
|
||||
|
||||
const byteAssign_t* HERF_2CH::getByteAssignment() const
|
||||
{
|
||||
return byteAssignment;
|
||||
}
|
||||
|
||||
uint8_t HERF_2CH::getByteAssignmentSize() const
|
||||
{
|
||||
return sizeof(byteAssignment) / sizeof(byteAssignment[0]);
|
||||
}
|
||||
13
lib/Hoymiles/src/inverters/HERF_2CH.h
Normal file
13
lib/Hoymiles/src/inverters/HERF_2CH.h
Normal file
@ -0,0 +1,13 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include "HM_Abstract.h"
|
||||
|
||||
class HERF_2CH : public HM_Abstract {
|
||||
public:
|
||||
explicit HERF_2CH(HoymilesRadio* radio, const uint64_t serial);
|
||||
static bool isValidSerial(const uint64_t serial);
|
||||
String typeName() const;
|
||||
const byteAssign_t* getByteAssignment() const;
|
||||
uint8_t getByteAssignmentSize() const;
|
||||
};
|
||||
20
lib/Hoymiles/src/inverters/HERF_4CH.cpp
Normal file
20
lib/Hoymiles/src/inverters/HERF_4CH.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2022-2024 Thomas Basler and others
|
||||
*/
|
||||
#include "HERF_4CH.h"
|
||||
|
||||
HERF_4CH::HERF_4CH(HoymilesRadio* radio, const uint64_t serial)
|
||||
: HM_4CH(radio, serial) {};
|
||||
|
||||
bool HERF_4CH::isValidSerial(const uint64_t serial)
|
||||
{
|
||||
// serial >= 0x280100000000 && serial <= 0x280199999999
|
||||
uint16_t preSerial = (serial >> 32) & 0xffff;
|
||||
return preSerial == 0x2801;
|
||||
}
|
||||
|
||||
String HERF_4CH::typeName() const
|
||||
{
|
||||
return "HERF-1600/1800-4T";
|
||||
}
|
||||
11
lib/Hoymiles/src/inverters/HERF_4CH.h
Normal file
11
lib/Hoymiles/src/inverters/HERF_4CH.h
Normal file
@ -0,0 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include "HM_4CH.h"
|
||||
|
||||
class HERF_4CH : public HM_4CH {
|
||||
public:
|
||||
explicit HERF_4CH(HoymilesRadio* radio, const uint64_t serial);
|
||||
static bool isValidSerial(const uint64_t serial);
|
||||
String typeName() const;
|
||||
};
|
||||
@ -11,3 +11,5 @@
|
||||
| HMS_4CH | HMS-1600/1800/2000-4T | 1164 |
|
||||
| HMT_4CH | HMT-1600/1800/2000-4T | 1361 |
|
||||
| HMT_6CH | HMT-1800/2250-6T | 1382 |
|
||||
| HERF_2CH | HERF 800 | 2821 |
|
||||
| HERF_4CH | HERF 1800 | 2801 |
|
||||
|
||||
@ -52,7 +52,11 @@ const devInfo_t devInfo[] = {
|
||||
{ { 0x10, 0x32, 0x71, ALL }, 2000, "HMT-2000-4T" }, // 0
|
||||
|
||||
{ { 0x10, 0x33, 0x11, ALL }, 1800, "HMT-1800-6T" }, // 01
|
||||
{ { 0x10, 0x33, 0x31, ALL }, 2250, "HMT-2250-6T" } // 01
|
||||
{ { 0x10, 0x33, 0x31, ALL }, 2250, "HMT-2250-6T" }, // 01
|
||||
|
||||
{ { 0xF1, 0x01, 0x14, ALL }, 800, "HERF-800" }, // 00
|
||||
{ { 0xF1, 0x01, 0x24, ALL }, 1600, "HERF-1600" }, // 00
|
||||
{ { 0xF1, 0x01, 0x22, ALL }, 1800, "HERF-1800" }, // 00
|
||||
};
|
||||
|
||||
DevInfoParser::DevInfoParser()
|
||||
|
||||
@ -129,7 +129,10 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
|
||||
return;
|
||||
}
|
||||
|
||||
if (root["serial"].as<uint64_t>() == 0) {
|
||||
// Interpret the string as a hex value and convert it to uint64_t
|
||||
const uint64_t serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
||||
|
||||
if (serial == 0) {
|
||||
retMsg["message"] = "Serial cannot be zero!";
|
||||
retMsg["code"] = WebApiError::DtuSerialZero;
|
||||
response->setLength();
|
||||
@ -185,8 +188,7 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
|
||||
|
||||
CONFIG_T& config = Configuration.get();
|
||||
|
||||
// Interpret the string as a hex value and convert it to uint64_t
|
||||
config.Dtu.Serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
||||
config.Dtu.Serial = serial;
|
||||
config.Dtu.PollInterval = root["pollinterval"].as<uint32_t>();
|
||||
config.Dtu.Nrf.PaLevel = root["nrf_palevel"].as<uint8_t>();
|
||||
config.Dtu.Cmt.PaLevel = root["cmt_palevel"].as<int8_t>();
|
||||
|
||||
@ -129,7 +129,10 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request)
|
||||
return;
|
||||
}
|
||||
|
||||
if (root["serial"].as<uint64_t>() == 0) {
|
||||
// Interpret the string as a hex value and convert it to uint64_t
|
||||
const uint64_t serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
||||
|
||||
if (serial == 0) {
|
||||
retMsg["message"] = "Serial must be a number > 0!";
|
||||
retMsg["code"] = WebApiError::InverterSerialZero;
|
||||
response->setLength();
|
||||
@ -158,7 +161,7 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
// Interpret the string as a hex value and convert it to uint64_t
|
||||
inverter->Serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
||||
inverter->Serial = serial;
|
||||
|
||||
strncpy(inverter->Name, root["name"].as<String>().c_str(), INV_MAX_NAME_STRLEN);
|
||||
|
||||
@ -233,7 +236,10 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
|
||||
return;
|
||||
}
|
||||
|
||||
if (root["serial"].as<uint64_t>() == 0) {
|
||||
// Interpret the string as a hex value and convert it to uint64_t
|
||||
const uint64_t serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
||||
|
||||
if (serial == 0) {
|
||||
retMsg["message"] = "Serial must be a number > 0!";
|
||||
retMsg["code"] = WebApiError::InverterSerialZero;
|
||||
response->setLength();
|
||||
@ -261,7 +267,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
|
||||
|
||||
INVERTER_CONFIG_T& inverter = Configuration.get().Inverter[root["id"].as<uint8_t>()];
|
||||
|
||||
uint64_t new_serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
||||
uint64_t new_serial = serial;
|
||||
uint64_t old_serial = inverter.Serial;
|
||||
|
||||
// Interpret the string as a hex value and convert it to uint64_t
|
||||
|
||||
@ -100,7 +100,10 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request)
|
||||
return;
|
||||
}
|
||||
|
||||
if (root["serial"].as<uint64_t>() == 0) {
|
||||
// Interpret the string as a hex value and convert it to uint64_t
|
||||
const uint64_t serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
||||
|
||||
if (serial == 0) {
|
||||
retMsg["message"] = "Serial must be a number > 0!";
|
||||
retMsg["code"] = WebApiError::LimitSerialZero;
|
||||
response->setLength();
|
||||
@ -129,7 +132,6 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request)
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
||||
uint16_t limit = root["limit_value"].as<uint16_t>();
|
||||
PowerLimitControlType type = root["limit_type"].as<PowerLimitControlType>();
|
||||
|
||||
|
||||
@ -93,7 +93,10 @@ void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request)
|
||||
return;
|
||||
}
|
||||
|
||||
if (root["serial"].as<uint64_t>() == 0) {
|
||||
// Interpret the string as a hex value and convert it to uint64_t
|
||||
const uint64_t serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
||||
|
||||
if (serial == 0) {
|
||||
retMsg["message"] = "Serial must be a number > 0!";
|
||||
retMsg["code"] = WebApiError::PowerSerialZero;
|
||||
response->setLength();
|
||||
@ -101,7 +104,6 @@ void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request)
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
|
||||
auto inv = Hoymiles.getInverterBySerial(serial);
|
||||
if (inv == nullptr) {
|
||||
retMsg["message"] = "Invalid inverter specified!";
|
||||
|
||||
114
webapp/src/components/InputSerial.vue
Normal file
114
webapp/src/components/InputSerial.vue
Normal file
@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<input v-model="inputSerial" type="text" :id="id" :required="required" class="form-control" :class="inputClass" />
|
||||
<BootstrapAlert show :variant="formatShow" v-if="formatHint">{{ formatHint }}</BootstrapAlert>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import BootstrapAlert from './BootstrapAlert.vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
const chars32 = '0123456789ABCDEFGHJKLMNPRSTUVWXY';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
BootstrapAlert,
|
||||
},
|
||||
props: {
|
||||
'modelValue': { type: [String, Number], required: true },
|
||||
'id': String,
|
||||
'inputClass': String,
|
||||
'required': Boolean,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inputSerial: "",
|
||||
formatHint: "",
|
||||
formatShow: "info",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
model: {
|
||||
get(): any {
|
||||
return this.modelValue;
|
||||
},
|
||||
set(value: any) {
|
||||
this.$emit('update:modelValue', value);
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
modelValue: function (val) {
|
||||
this.inputSerial = val;
|
||||
},
|
||||
inputSerial: function (val) {
|
||||
const serial = val.toString().toUpperCase(); // Convert to lowercase for case-insensitivity
|
||||
|
||||
if (serial == "") {
|
||||
this.formatHint = "";
|
||||
this.model = "";
|
||||
return;
|
||||
}
|
||||
|
||||
this.formatShow = "info";
|
||||
|
||||
// Contains only numbers
|
||||
if (/^[\d]{12}$/.test(serial)) {
|
||||
this.model = serial;
|
||||
this.formatHint = this.$t('inputserial.format_hoymiles');
|
||||
}
|
||||
|
||||
// Contains numbers and hex characters but at least one number
|
||||
else if (/^(?=.*\d)[\dA-F]{12}$/.test(serial)) {
|
||||
this.model = serial;
|
||||
this.formatHint = this.$t('inputserial.format_converted');
|
||||
}
|
||||
|
||||
// Has format: xxxxxxxxx-xxx
|
||||
else if (/^((A01)|(A11)|(A21))[\dA-HJ-NR-YP]{6}-[\dA-HJ-NP-Z]{3}$/.test(serial)) {
|
||||
if (this.checkHerfChecksum(serial)) {
|
||||
this.model = this.convertHerfToHoy(serial);
|
||||
this.$nextTick(() => {
|
||||
this.formatHint = this.$t('inputserial.format_herf_valid', { serial: this.model });
|
||||
});
|
||||
|
||||
} else {
|
||||
this.formatHint = this.$t('inputserial.format_herf_invalid');
|
||||
this.formatShow = "danger";
|
||||
}
|
||||
|
||||
// Any other format
|
||||
} else {
|
||||
this.formatHint = this.$t('inputserial.format_unknown');
|
||||
this.formatShow = "danger";
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
checkHerfChecksum(sn: string) {
|
||||
const chars64 = 'HMFLGW5XC301234567899Z67YRT2S8ABCDEFGHJKDVEJ4KQPUALMNPRSTUVWXYNB';
|
||||
|
||||
const checksum = sn.substring(sn.indexOf("-") + 1);
|
||||
const serial = sn.substring(0, sn.indexOf("-"));
|
||||
|
||||
const first_char = '1';
|
||||
const i = chars32.indexOf(first_char)
|
||||
const sum1: number = Array.from(serial).reduce((sum, c) => sum + c.charCodeAt(0), 0) & 31;
|
||||
const sum2: number = Array.from(serial).reduce((sum, c) => sum + chars32.indexOf(c), 0) & 31;
|
||||
const ext = first_char + chars64[sum1 + i] + chars64[sum2 + i];
|
||||
|
||||
return checksum == ext;
|
||||
},
|
||||
convertHerfToHoy(sn: string) {
|
||||
let sn_int: bigint = 0n;
|
||||
|
||||
for (let i = 0; i < 9; i++) {
|
||||
const pos: bigint = BigInt(chars32.indexOf(sn[i].toUpperCase()));
|
||||
const shift: bigint = BigInt(42 - 5 * i - (i <= 2 ? 0 : 2));
|
||||
sn_int |= (pos << shift);
|
||||
}
|
||||
|
||||
return sn_int.toString(16);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@ -618,5 +618,12 @@
|
||||
"Name": "Name",
|
||||
"ValueSelected": "Ausgewählt",
|
||||
"ValueActive": "Aktiv"
|
||||
},
|
||||
"inputserial": {
|
||||
"format_hoymiles": "Hoymiles Seriennummerformat",
|
||||
"format_converted": "Bereits konvertierte Seriennummer",
|
||||
"format_herf_valid": "E-Star HERF Format (wird konvertiert gespeichert): {serial}",
|
||||
"format_herf_invalid": "E-Star HERF Format: Ungültige Prüfsumme",
|
||||
"format_unknown": "Unbekanntes Format"
|
||||
}
|
||||
}
|
||||
|
||||
@ -619,5 +619,12 @@
|
||||
"Number": "Number",
|
||||
"ValueSelected": "Selected",
|
||||
"ValueActive": "Active"
|
||||
},
|
||||
"inputserial": {
|
||||
"format_hoymiles": "Hoymiles serial number format",
|
||||
"format_converted": "Already converted serial number",
|
||||
"format_herf_valid": "E-Star HERF format (will be saved converted): {serial}",
|
||||
"format_herf_invalid": "E-Star HERF format: Invalid checksum",
|
||||
"format_unknown": "Unknown format"
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,5 +618,12 @@
|
||||
"Name": "Nom",
|
||||
"ValueSelected": "Sélectionné",
|
||||
"ValueActive": "Activé"
|
||||
},
|
||||
"inputserial": {
|
||||
"format_hoymiles": "Hoymiles serial number format",
|
||||
"format_converted": "Already converted serial number",
|
||||
"format_herf_valid": "E-Star HERF format (will be saved converted): {serial}",
|
||||
"format_herf_invalid": "E-Star HERF format: Invalid checksum",
|
||||
"format_unknown": "Unknown format"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
export interface DevInfoStatus {
|
||||
serial: number;
|
||||
serial: string;
|
||||
valid_data: boolean;
|
||||
fw_bootloader_version: number;
|
||||
fw_build_version: number;
|
||||
@ -8,4 +8,4 @@ export interface DevInfoStatus {
|
||||
hw_version: number;
|
||||
hw_model_name: string;
|
||||
max_power: number;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ export interface InverterChannel {
|
||||
|
||||
export interface Inverter {
|
||||
id: string;
|
||||
serial: number;
|
||||
serial: string;
|
||||
name: string;
|
||||
type: string;
|
||||
order: number;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
export interface LimitConfig {
|
||||
serial: number;
|
||||
serial: string;
|
||||
limit_value: number;
|
||||
limit_type: number;
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ export interface InverterStatistics {
|
||||
}
|
||||
|
||||
export interface Inverter {
|
||||
serial: number;
|
||||
serial: string;
|
||||
name: string;
|
||||
order: number;
|
||||
data_age: number;
|
||||
@ -53,4 +53,4 @@ export interface LiveData {
|
||||
inverters: Inverter[];
|
||||
total: Total;
|
||||
hints: Hints;
|
||||
}
|
||||
}
|
||||
|
||||
@ -346,7 +346,7 @@ export default defineComponent({
|
||||
showAlertLimit: false,
|
||||
|
||||
powerSettingView: {} as bootstrap.Modal,
|
||||
powerSettingSerial: 0,
|
||||
powerSettingSerial: "",
|
||||
powerSettingLoading: true,
|
||||
alertMessagePower: "",
|
||||
alertTypePower: "info",
|
||||
@ -515,7 +515,7 @@ export default defineComponent({
|
||||
this.heartInterval && clearTimeout(this.heartInterval);
|
||||
this.isFirstFetchAfterConnect = true;
|
||||
},
|
||||
onShowEventlog(serial: number) {
|
||||
onShowEventlog(serial: string) {
|
||||
this.eventLogLoading = true;
|
||||
fetch("/api/eventlog/status?inv=" + serial + "&locale=" + this.$i18n.locale, { headers: authHeader() })
|
||||
.then((response) => handleResponse(response, this.$emitter, this.$router))
|
||||
@ -526,7 +526,7 @@ export default defineComponent({
|
||||
|
||||
this.eventLogView.show();
|
||||
},
|
||||
onShowDevInfo(serial: number) {
|
||||
onShowDevInfo(serial: string) {
|
||||
this.devInfoLoading = true;
|
||||
fetch("/api/devinfo/status?inv=" + serial, { headers: authHeader() })
|
||||
.then((response) => handleResponse(response, this.$emitter, this.$router))
|
||||
@ -538,7 +538,7 @@ export default defineComponent({
|
||||
|
||||
this.devInfoView.show();
|
||||
},
|
||||
onShowGridProfile(serial: number) {
|
||||
onShowGridProfile(serial: string) {
|
||||
this.gridProfileLoading = true;
|
||||
fetch("/api/gridprofile/status?inv=" + serial, { headers: authHeader() })
|
||||
.then((response) => handleResponse(response, this.$emitter, this.$router))
|
||||
@ -555,9 +555,9 @@ export default defineComponent({
|
||||
|
||||
this.gridProfileView.show();
|
||||
},
|
||||
onShowLimitSettings(serial: number) {
|
||||
onShowLimitSettings(serial: string) {
|
||||
this.showAlertLimit = false;
|
||||
this.targetLimitList.serial = 0;
|
||||
this.targetLimitList.serial = "";
|
||||
this.targetLimitList.limit_value = 0;
|
||||
this.targetLimitType = 1;
|
||||
this.targetLimitTypeText = this.$t('home.Relative');
|
||||
@ -611,9 +611,9 @@ export default defineComponent({
|
||||
this.targetLimitType = type;
|
||||
},
|
||||
|
||||
onShowPowerSettings(serial: number) {
|
||||
onShowPowerSettings(serial: string) {
|
||||
this.showAlertPower = false;
|
||||
this.powerSettingSerial = 0;
|
||||
this.powerSettingSerial = "";
|
||||
this.powerSettingLoading = true;
|
||||
fetch("/api/power/status", { headers: authHeader() })
|
||||
.then((response) => handleResponse(response, this.$emitter, this.$router))
|
||||
|
||||
@ -8,8 +8,7 @@
|
||||
<form class="form-inline" v-on:submit.prevent="onSubmit">
|
||||
<div class="form-group">
|
||||
<label>{{ $t('inverteradmin.Serial') }}</label>
|
||||
<input v-model="newInverterData.serial" type="number" class="form-control ml-sm-2 mr-sm-4 my-2"
|
||||
required />
|
||||
<InputSerial v-model="newInverterData.serial" inputClass="ml-sm-2 mr-sm-4 my-2" required />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ $t('inverteradmin.Name') }}</label>
|
||||
@ -91,7 +90,7 @@
|
||||
<label for="inverter-serial" class="col-form-label">
|
||||
{{ $t('inverteradmin.InverterSerial') }}
|
||||
</label>
|
||||
<input v-model="selectedInverterData.serial" type="number" id="inverter-serial" class="form-control" />
|
||||
<InputSerial v-model="selectedInverterData.serial" id="inverter-serial" />
|
||||
<label for="inverter-name" class="col-form-label">{{ $t('inverteradmin.InverterName') }}
|
||||
<BIconInfoCircle v-tooltip :title="$t('inverteradmin.InverterNameHint')" />
|
||||
</label>
|
||||
@ -207,6 +206,7 @@ import BasePage from '@/components/BasePage.vue';
|
||||
import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
||||
import CardElement from '@/components/CardElement.vue';
|
||||
import InputElement from '@/components/InputElement.vue';
|
||||
import InputSerial from '@/components/InputSerial.vue';
|
||||
import ModalDialog from '@/components/ModalDialog.vue';
|
||||
import type { Inverter } from '@/types/InverterConfig';
|
||||
import { authHeader, handleResponse } from '@/utils/authentication';
|
||||
@ -235,6 +235,7 @@ export default defineComponent({
|
||||
BootstrapAlert,
|
||||
CardElement,
|
||||
InputElement,
|
||||
InputSerial,
|
||||
ModalDialog,
|
||||
BIconInfoCircle,
|
||||
BIconPencil,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user