Allow configuration of the TX PA Level of the CMT2300A module

This commit is contained in:
Thomas Basler 2023-03-28 21:48:57 +02:00
parent bec9870347
commit 854fcdaeae
10 changed files with 104 additions and 52 deletions

View File

@ -4,7 +4,7 @@
#include <Arduino.h>
#define CONFIG_FILENAME "/config.json"
#define CONFIG_VERSION 0x00011800 // 0.1.24 // make sure to clean all after change
#define CONFIG_VERSION 0x00011900 // 0.1.24 // make sure to clean all after change
#define WIFI_MAX_SSID_STRLEN 32
#define WIFI_MAX_PASSWORD_STRLEN 64
@ -82,7 +82,8 @@ struct CONFIG_T {
uint64_t Dtu_Serial;
uint32_t Dtu_PollInterval;
uint8_t Dtu_PaLevel;
uint8_t Dtu_NrfPaLevel;
int8_t Dtu_CmtPaLevel;
bool Mqtt_Hass_Enabled;
bool Mqtt_Hass_Retain;

View File

@ -76,7 +76,8 @@
#define DTU_SERIAL 0x99978563412
#define DTU_POLL_INTERVAL 5
#define DTU_PA_LEVEL 0
#define DTU_NRF_PA_LEVEL 0
#define DTU_CMT_PA_LEVEL 0
#define MQTT_HASS_ENABLED false
#define MQTT_HASS_EXPIRE true

View File

@ -79,7 +79,8 @@ bool ConfigurationClass::write()
JsonObject dtu = doc.createNestedObject("dtu");
dtu["serial"] = config.Dtu_Serial;
dtu["poll_interval"] = config.Dtu_PollInterval;
dtu["pa_level"] = config.Dtu_PaLevel;
dtu["nrf_pa_level"] = config.Dtu_NrfPaLevel;
dtu["cmt_pa_level"] = config.Dtu_CmtPaLevel;
JsonObject security = doc.createNestedObject("security");
security["password"] = config.Security_Password;
@ -219,7 +220,8 @@ bool ConfigurationClass::read()
JsonObject dtu = doc["dtu"];
config.Dtu_Serial = dtu["serial"] | DTU_SERIAL;
config.Dtu_PollInterval = dtu["poll_interval"] | DTU_POLL_INTERVAL;
config.Dtu_PaLevel = dtu["pa_level"] | DTU_PA_LEVEL;
config.Dtu_NrfPaLevel = dtu["nrf_pa_level"] | DTU_NRF_PA_LEVEL;
config.Dtu_CmtPaLevel = dtu["cmt_pa_level"] | DTU_CMT_PA_LEVEL;
JsonObject security = doc["security"];
strlcpy(config.Security_Password, security["password"] | ACCESS_POINT_PASSWORD, sizeof(config.Security_Password));
@ -290,6 +292,11 @@ void ConfigurationClass::migrate()
config.Mqtt_PublishInterval = mqtt["publish_invterval"];
}
if (config.Cfg_Version < 0x00011900) {
JsonObject dtu = doc["dtu"];
config.Dtu_NrfPaLevel = dtu["pa_level"];
}
f.close();
config.Cfg_Version = CONFIG_VERSION;

View File

@ -37,7 +37,8 @@ void InverterSettingsClass::init()
}
MessageOutput.println(" Setting radio PA level... ");
Hoymiles.getRadioNrf()->setPALevel((rf24_pa_dbm_e)config.Dtu_PaLevel);
Hoymiles.getRadioNrf()->setPALevel((rf24_pa_dbm_e)config.Dtu_NrfPaLevel);
Hoymiles.getRadioCmt()->setPALevel(config.Dtu_CmtPaLevel);
MessageOutput.println(" Setting DTU serial... ");
Hoymiles.getRadioNrf()->setDtuSerial(config.Dtu_Serial);

View File

@ -38,9 +38,12 @@ void WebApiDtuClass::onDtuAdminGet(AsyncWebServerRequest* request)
snprintf(buffer, sizeof(buffer), "%0x%08x",
((uint32_t)((config.Dtu_Serial >> 32) & 0xFFFFFFFF)),
((uint32_t)(config.Dtu_Serial & 0xFFFFFFFF)));
root["dtu_serial"] = buffer;
root["dtu_pollinterval"] = config.Dtu_PollInterval;
root["dtu_palevel"] = config.Dtu_PaLevel;
root["serial"] = buffer;
root["pollinterval"] = config.Dtu_PollInterval;
root["nrf_enabled"] = Hoymiles.getRadioNrf()->isInitialized();
root["nrf_palevel"] = config.Dtu_NrfPaLevel;
root["cmt_enabled"] = Hoymiles.getRadioCmt()->isInitialized();
root["cmt_palevel"] = config.Dtu_CmtPaLevel;
response->setLength();
request->send(response);
@ -85,7 +88,7 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
return;
}
if (!(root.containsKey("dtu_serial") && root.containsKey("dtu_pollinterval") && root.containsKey("dtu_palevel"))) {
if (!(root.containsKey("serial") && root.containsKey("pollinterval") && root.containsKey("nrf_palevel") && root.containsKey("cmt_palevel"))) {
retMsg["message"] = "Values are missing!";
retMsg["code"] = WebApiError::GenericValueMissing;
response->setLength();
@ -93,7 +96,7 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
return;
}
if (root["dtu_serial"].as<uint64_t>() == 0) {
if (root["serial"].as<uint64_t>() == 0) {
retMsg["message"] = "Serial cannot be zero!";
retMsg["code"] = WebApiError::DtuSerialZero;
response->setLength();
@ -101,7 +104,7 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
return;
}
if (root["dtu_pollinterval"].as<uint32_t>() == 0) {
if (root["pollinterval"].as<uint32_t>() == 0) {
retMsg["message"] = "Poll interval must be greater zero!";
retMsg["code"] = WebApiError::DtuPollZero;
response->setLength();
@ -109,7 +112,7 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
return;
}
if (root["dtu_palevel"].as<uint8_t>() > 3) {
if (root["nrf_palevel"].as<uint8_t>() > 3) {
retMsg["message"] = "Invalid power level setting!";
retMsg["code"] = WebApiError::DtuInvalidPowerLevel;
response->setLength();
@ -117,12 +120,21 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
return;
}
if (root["cmt_palevel"].as<int8_t>() < -10 || root["cmt_palevel"].as<int8_t>() > 20) {
retMsg["message"] = F("Invalid power level setting!");
retMsg["code"] = WebApiError::DtuInvalidPowerLevel;
response->setLength();
request->send(response);
return;
}
CONFIG_T& config = Configuration.get();
// Interpret the string as a hex value and convert it to uint64_t
config.Dtu_Serial = strtoll(root["dtu_serial"].as<String>().c_str(), NULL, 16);
config.Dtu_PollInterval = root["dtu_pollinterval"].as<uint32_t>();
config.Dtu_PaLevel = root["dtu_palevel"].as<uint8_t>();
config.Dtu_Serial = strtoll(root["serial"].as<String>().c_str(), NULL, 16);
config.Dtu_PollInterval = root["pollinterval"].as<uint32_t>();
config.Dtu_NrfPaLevel = root["nrf_palevel"].as<uint8_t>();
config.Dtu_CmtPaLevel = root["cmt_palevel"].as<int8_t>();
Configuration.write();
retMsg["type"] = "success";
@ -132,7 +144,8 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
response->setLength();
request->send(response);
Hoymiles.getRadioNrf()->setPALevel((rf24_pa_dbm_e)config.Dtu_PaLevel);
Hoymiles.getRadioNrf()->setPALevel((rf24_pa_dbm_e)config.Dtu_NrfPaLevel);
Hoymiles.getRadioCmt()->setPALevel(config.Dtu_CmtPaLevel);
Hoymiles.getRadioNrf()->setDtuSerial(config.Dtu_Serial);
Hoymiles.getRadioCmt()->setDtuSerial(config.Dtu_Serial);
Hoymiles.setPollInterval(config.Dtu_PollInterval);

View File

@ -322,13 +322,15 @@
"SerialHint": "Sowohl der Wechselrichter als auch die DTU haben eine Seriennummer. Die DTU-Seriennummer wird beim ersten Start zufällig generiert und muss normalerweise nicht geändert werden.",
"PollInterval": "Abfrageintervall:",
"Seconds": "Sekunden",
"PaLevel": "Sendeleistung:",
"PaLevelHint": "Stellen Sie sicher, dass Ihre Stromversorgung stabil genug ist, bevor Sie die Sendeleistung erhöhen.",
"NrfPaLevel": "NRF24 Sendeleistung:",
"CmtPaLevel": "CMT2300A Sendeleistung:",
"NrfPaLevelHint": "Verwendet für HM-Wechselrichter. Stellen Sie sicher, dass Ihre Stromversorgung stabil genug ist, bevor Sie die Sendeleistung erhöhen.",
"CmtPaLevelHint": "Verwendet für HMS/HMT-Wechselrichter. Stellen Sie sicher, dass Ihre Stromversorgung stabil genug ist, bevor Sie die Sendeleistung erhöhen.",
"Save": "Speichern",
"Min": "Minimum (-18 dBm)",
"Low": "Niedrig (-12 dBm)",
"High": "Hoch (-6 dBm)",
"Max": "Maximum (0 dBm)"
"Min": "Minimum ({db} dBm)",
"Low": "Niedrig ({db} dBm)",
"High": "Hoch ({db} dBm)",
"Max": "Maximum ({db} dBm)"
},
"securityadmin": {
"SecuritySettings": "Sicherheitseinstellungen",

View File

@ -322,13 +322,15 @@
"SerialHint": "Both the inverter and the DTU have a serial number. The DTU serial number is randomly generated at the first start and does not normally need to be changed.",
"PollInterval": "Poll Interval:",
"Seconds": "Seconds",
"PaLevel": "PA Level:",
"PaLevelHint": "Make sure your power supply is stable enough before increasing the transmit power.",
"NrfPaLevel": "NRF24 Transmitting power:",
"CmtPaLevel": "CMT2300A Transmitting power:",
"NrfPaLevelHint": "Used for HM-Inverters. Make sure your power supply is stable enough before increasing the transmit power.",
"CmtPaLevelHint": "Used for HMS/HMT-Inverters. Make sure your power supply is stable enough before increasing the transmit power.",
"Save": "Save",
"Min": "Minimum (-18 dBm)",
"Low": "Low (-12 dBm)",
"High": "High (-6 dBm)",
"Max": "Maximum (0 dBm)"
"Min": "Minimum ({db} dBm)",
"Low": "Low ({db} dBm)",
"High": "High ({db} dBm)",
"Max": "Maximum ({db} dBm)"
},
"securityadmin": {
"SecuritySettings": "Security Settings",

View File

@ -322,13 +322,15 @@
"SerialHint": "L'onduleur et le DTU ont tous deux un numéro de série. Le numéro de série du DTU est généré de manière aléatoire lors du premier démarrage et ne doit normalement pas être modifié.",
"PollInterval": "Intervalle de sondage",
"Seconds": "Secondes",
"PaLevel": "Niveau de puissance d'émission",
"PaLevelHint": "Assurez-vous que votre alimentation est suffisamment stable avant d'augmenter la puissance d'émission.",
"NrfPaLevel": "NRF24 Niveau de puissance d'émission",
"CmtPaLevel": "CMT2300A Niveau de puissance d'émission",
"NrfPaLevelHint": "Used for HM-Inverters. Assurez-vous que votre alimentation est suffisamment stable avant d'augmenter la puissance d'émission.",
"CmtPaLevelHint": "Used for HMS/HMT-Inverters. Assurez-vous que votre alimentation est suffisamment stable avant d'augmenter la puissance d'émission.",
"Save": "Sauvegarder",
"Min": "Minimum (-18 dBm)",
"Low": "Bas (-12 dBm)",
"High": "Haut (-6 dBm)",
"Max": "Maximum (0 dBm)"
"Min": "Minimum ({db} dBm)",
"Low": "Bas ({db} dBm)",
"High": "Haut ({db} dBm)",
"Max": "Maximum ({db} dBm)"
},
"securityadmin": {
"SecuritySettings": "Paramètres de sécurité",

View File

@ -1,5 +1,8 @@
export interface DtuConfig {
dtu_serial: number;
dtu_pollinterval: number;
dtu_palevel: number;
serial: number;
pollinterval: number;
nrf_enabled: boolean;
nrf_palevel: number;
cmt_enabled: boolean;
cmt_palevel: number;
}

View File

@ -7,24 +7,38 @@
<form @submit="saveDtuConfig">
<CardElement :text="$t('dtuadmin.DtuConfiguration')" textVariant="text-bg-primary">
<InputElement :label="$t('dtuadmin.Serial')"
v-model="dtuConfigList.dtu_serial"
v-model="dtuConfigList.serial"
type="number" min="1" max="199999999999"
:tooltip="$t('dtuadmin.SerialHint')"/>
<InputElement :label="$t('dtuadmin.PollInterval')"
v-model="dtuConfigList.dtu_pollinterval"
v-model="dtuConfigList.pollinterval"
type="number" min="1" max="86400"
:postfix="$t('dtuadmin.Seconds')"/>
<div class="row mb-3">
<label for="inputTimezone" class="col-sm-2 col-form-label">
{{ $t('dtuadmin.PaLevel') }}
<BIconInfoCircle v-tooltip :title="$t('dtuadmin.PaLevelHint')" />
<div class="row mb-3" v-if="dtuConfigList.nrf_enabled">
<label for="inputNrfPaLevel" class="col-sm-2 col-form-label">
{{ $t('dtuadmin.NrfPaLevel') }}
<BIconInfoCircle v-tooltip :title="$t('dtuadmin.NrfPaLevelHint')" />
</label>
<div class="col-sm-10">
<select class="form-select" v-model="dtuConfigList.dtu_palevel">
<option v-for="palevel in palevelList" :key="palevel.key" :value="palevel.key">
{{ $t(`dtuadmin.` + palevel.value) }}
<select id="inputNrfPaLevel" class="form-select" v-model="dtuConfigList.nrf_palevel">
<option v-for="palevel in nrfpalevelList" :key="palevel.key" :value="palevel.key">
{{ $t(`dtuadmin.` + palevel.value, { db: palevel.db }) }}
</option>
</select>
</div>
</div>
<div class="row mb-3" v-if="dtuConfigList.cmt_enabled">
<label for="inputCmtPaLevel" class="col-sm-2 col-form-label">
{{ $t('dtuadmin.CmtPaLevel') }}
<BIconInfoCircle v-tooltip :title="$t('dtuadmin.CmtPaLevelHint')" />
</label>
<div class="col-sm-10">
<select id="inputCmtPaLevel" class="form-select" v-model="dtuConfigList.cmt_palevel">
<option v-for="palevel in cmtpalevelList" :key="palevel.key" :value="palevel.key">
{{ $t(`dtuadmin.` + palevel.value, { db: palevel.db }) }}
</option>
</select>
</div>
@ -57,11 +71,17 @@ export default defineComponent({
return {
dataLoading: true,
dtuConfigList: {} as DtuConfig,
palevelList: [
{ key: 0, value: 'Min' },
{ key: 1, value: 'Low' },
{ key: 2, value: 'High' },
{ key: 3, value: 'Max' },
nrfpalevelList: [
{ key: 0, value: 'Min', db: "-18" },
{ key: 1, value: 'Low', db: "-12" },
{ key: 2, value: 'High', db: "-6" },
{ key: 3, value: 'Max', db: "0" },
],
cmtpalevelList: [
{ key: 0, value: 'Min', db: "0" },
{ key: 13, value: 'Low', db: "13" },
{ key: 17, value: 'High', db: "17" },
{ key: 20, value: 'Max', db: "20" },
],
alertMessage: "",
alertType: "info",