mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 09:49:32 +02:00
Merge pull request #1424 from jonny5532/feature/move-custom-bms-voltage-limits-to-settings
Make custom-BMS voltage limits configurable via settings
This commit is contained in:
commit
ce1f8955e9
19 changed files with 173 additions and 93 deletions
|
@ -171,6 +171,12 @@
|
|||
// 3000 = 300.0V, Target discharge voltage (Value can be tuned on the fly via webserver). Not used unless BATTERY_USE_VOLTAGE_LIMITS = true
|
||||
#define BATTERY_MAX_DISCHARGE_VOLTAGE 3000
|
||||
|
||||
/* Pack/cell voltage limits for custom-BMS batteries (RJXZS, Daly, etc.) */
|
||||
//#define MAX_CUSTOM_PACK_VOLTAGE_DV 5000 // 5000 = 500.0V , Maximum pack voltage in decivolts
|
||||
//#define MIN_CUSTOM_PACK_VOLTAGE_DV 2500 // 2500 = 250.0V , Minimum pack voltage in decivolts
|
||||
//#define MAX_CUSTOM_CELL_VOLTAGE_MV 4250 // 4250 = 4.250V , Maximum cell voltage in millivolts (4250 = 4.250V)
|
||||
//#define MIN_CUSTOM_CELL_VOLTAGE_MV 2650 // 2650 = 2.650V , Minimum cell voltage in millivolts (2650 = 2.650V)
|
||||
|
||||
/* LED settings. Optional customization for how the blinking pattern on the LED should behave.
|
||||
* CLASSIC - Slow up/down ramp. If CLASSIC, then a ramp up and ramp down will finish in LED_PERIOD_MS milliseconds
|
||||
* FLOW - Ramp up/down depending on flow of energy
|
||||
|
|
|
@ -312,3 +312,23 @@ void setup_battery() {
|
|||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* User-selected voltages used for custom-BMS batteries (RJXZS etc.) */
|
||||
#if defined(MAX_CUSTOM_PACK_VOLTAGE_DV) && defined(MIN_CUSTOM_PACK_VOLTAGE_DV) && \
|
||||
defined(MAX_CUSTOM_CELL_VOLTAGE_MV) && defined(MIN_CUSTOM_CELL_VOLTAGE_MV)
|
||||
// Use USER_SETTINGS.h values for cell/pack voltage defaults
|
||||
uint16_t user_selected_max_pack_voltage_default_dV = MAX_CUSTOM_PACK_VOLTAGE_DV;
|
||||
uint16_t user_selected_min_pack_voltage_default_dV = MIN_CUSTOM_PACK_VOLTAGE_DV;
|
||||
uint16_t user_selected_max_cell_voltage_default_mV = MAX_CUSTOM_CELL_VOLTAGE_MV;
|
||||
uint16_t user_selected_min_cell_voltage_default_mV = MIN_CUSTOM_CELL_VOLTAGE_MV;
|
||||
#else
|
||||
// Use 0V for user selected cell/pack voltage defaults (COMMON_IMAGE will replace with saved values from NVM)
|
||||
uint16_t user_selected_max_pack_voltage_default_dV = 0;
|
||||
uint16_t user_selected_min_pack_voltage_default_dV = 0;
|
||||
uint16_t user_selected_max_cell_voltage_default_mV = 0;
|
||||
uint16_t user_selected_min_cell_voltage_default_mV = 0;
|
||||
#endif
|
||||
uint16_t user_selected_max_pack_voltage_dV = user_selected_max_pack_voltage_default_dV;
|
||||
uint16_t user_selected_min_pack_voltage_dV = user_selected_min_pack_voltage_default_dV;
|
||||
uint16_t user_selected_max_cell_voltage_mV = user_selected_max_cell_voltage_default_mV;
|
||||
uint16_t user_selected_min_cell_voltage_mV = user_selected_min_cell_voltage_default_mV;
|
||||
|
|
|
@ -55,4 +55,9 @@ void setup_can_shunt();
|
|||
|
||||
void setup_battery(void);
|
||||
|
||||
extern uint16_t user_selected_max_pack_voltage_dV;
|
||||
extern uint16_t user_selected_min_pack_voltage_dV;
|
||||
extern uint16_t user_selected_max_cell_voltage_mV;
|
||||
extern uint16_t user_selected_min_cell_voltage_mV;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "CELLPOWER-BMS.h"
|
||||
#include "../battery/BATTERIES.h"
|
||||
#include "../communication/can/comm_can.h"
|
||||
#include "../datalayer/datalayer.h"
|
||||
#include "../datalayer/datalayer_extended.h" //For "More battery info" webpage
|
||||
|
@ -231,8 +232,8 @@ void CellPowerBms::setup(void) { // Performs one time setup at startup
|
|||
strncpy(datalayer.system.info.battery_protocol, Name, 63);
|
||||
datalayer.system.info.battery_protocol[63] = '\0';
|
||||
datalayer.system.status.battery_allows_contactor_closing = true;
|
||||
datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV;
|
||||
datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV;
|
||||
datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV;
|
||||
datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV;
|
||||
datalayer.battery.info.max_design_voltage_dV = user_selected_max_pack_voltage_dV;
|
||||
datalayer.battery.info.min_design_voltage_dV = user_selected_min_pack_voltage_dV;
|
||||
datalayer.battery.info.max_cell_voltage_mV = user_selected_max_cell_voltage_mV;
|
||||
datalayer.battery.info.min_cell_voltage_mV = user_selected_min_cell_voltage_mV;
|
||||
}
|
||||
|
|
|
@ -22,11 +22,6 @@ class CellPowerBms : public CanBattery {
|
|||
|
||||
private:
|
||||
CellpowerHtmlRenderer renderer;
|
||||
/* Tweak these according to your battery build */
|
||||
static const int MAX_PACK_VOLTAGE_DV = 5000; //5000 = 500.0V
|
||||
static const int MIN_PACK_VOLTAGE_DV = 1500;
|
||||
static const int MAX_CELL_VOLTAGE_MV = 4250; //Battery is put into emergency stop if one cell goes over this value
|
||||
static const int MIN_CELL_VOLTAGE_MV = 2700; //Battery is put into emergency stop if one cell goes below this value
|
||||
|
||||
unsigned long previousMillis1s = 0; // will store last time a 1s CAN Message was sent
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "DALY-BMS.h"
|
||||
#include <Arduino.h>
|
||||
#include <cstdint>
|
||||
#include "../battery/BATTERIES.h"
|
||||
#include "../datalayer/datalayer.h"
|
||||
#include "../devboard/hal/hal.h"
|
||||
#include "../devboard/utils/events.h"
|
||||
|
@ -67,10 +68,10 @@ void DalyBms::update_values() {
|
|||
void DalyBms::setup(void) { // Performs one time setup at startup
|
||||
strncpy(datalayer.system.info.battery_protocol, Name, 63);
|
||||
datalayer.system.info.battery_protocol[63] = '\0';
|
||||
datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV;
|
||||
datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV;
|
||||
datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV;
|
||||
datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV;
|
||||
datalayer.battery.info.max_design_voltage_dV = user_selected_max_pack_voltage_dV;
|
||||
datalayer.battery.info.min_design_voltage_dV = user_selected_min_pack_voltage_dV;
|
||||
datalayer.battery.info.max_cell_voltage_mV = user_selected_max_cell_voltage_mV;
|
||||
datalayer.battery.info.min_cell_voltage_mV = user_selected_min_cell_voltage_mV;
|
||||
datalayer.battery.info.total_capacity_Wh = BATTERY_WH_MAX;
|
||||
datalayer.system.status.battery_allows_contactor_closing = true;
|
||||
|
||||
|
|
|
@ -17,11 +17,6 @@ class DalyBms : public RS485Battery {
|
|||
|
||||
private:
|
||||
/* Tweak these according to your battery build */
|
||||
static const int CELL_COUNT = 14;
|
||||
static const int MAX_PACK_VOLTAGE_DV = 580; //580 = 58.0V
|
||||
static const int MIN_PACK_VOLTAGE_DV = 460; //480 = 48.0V
|
||||
static const int MAX_CELL_VOLTAGE_MV = 4200; //Battery is put into emergency stop if one cell goes over this value
|
||||
static const int MIN_CELL_VOLTAGE_MV = 3200; //Battery is put into emergency stop if one cell goes below this value
|
||||
static const int POWER_PER_PERCENT =
|
||||
50; // below 20% and above 80% limit power to 50W * SOC (i.e. 150W at 3%, 500W at 10%, ...)
|
||||
static const int POWER_PER_DEGREE_C = 60; // max power added/removed per degree above/below 0°C
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "ORION-BMS.h"
|
||||
#include "../battery/BATTERIES.h"
|
||||
#include "../communication/can/comm_can.h"
|
||||
#include "../datalayer/datalayer.h"
|
||||
#include "../devboard/utils/events.h"
|
||||
|
@ -115,9 +116,9 @@ void OrionBms::transmit_can(unsigned long currentMillis) {
|
|||
void OrionBms::setup(void) { // Performs one time setup at startup
|
||||
strncpy(datalayer.system.info.battery_protocol, Name, 63);
|
||||
datalayer.system.info.battery_protocol[63] = '\0';
|
||||
datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV;
|
||||
datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV;
|
||||
datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV;
|
||||
datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV;
|
||||
datalayer.battery.info.max_design_voltage_dV = user_selected_max_pack_voltage_dV;
|
||||
datalayer.battery.info.min_design_voltage_dV = user_selected_min_pack_voltage_dV;
|
||||
datalayer.battery.info.max_cell_voltage_mV = user_selected_max_cell_voltage_mV;
|
||||
datalayer.battery.info.min_cell_voltage_mV = user_selected_min_cell_voltage_mV;
|
||||
datalayer.system.status.battery_allows_contactor_closing = true;
|
||||
}
|
||||
|
|
|
@ -17,13 +17,6 @@ class OrionBms : public CanBattery {
|
|||
static constexpr const char* Name = "DIY battery with Orion BMS (Victron setting)";
|
||||
|
||||
private:
|
||||
/* Change the following to suit your battery */
|
||||
static const int MAX_PACK_VOLTAGE_DV = 5000; //5000 = 500.0V
|
||||
static const int MIN_PACK_VOLTAGE_DV = 1500;
|
||||
static const int MAX_CELL_VOLTAGE_MV = 4250; //Battery is put into emergency stop if one cell goes over this value
|
||||
static const int MIN_CELL_VOLTAGE_MV = 2700; //Battery is put into emergency stop if one cell goes below this value
|
||||
static const int MAX_CELL_DEVIATION_MV = 150;
|
||||
|
||||
uint16_t cellvoltages[MAX_AMOUNT_CELLS]; //array with all the cellvoltages
|
||||
uint16_t Maximum_Cell_Voltage = 3700;
|
||||
uint16_t Minimum_Cell_Voltage = 3700;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "PYLON-BATTERY.h"
|
||||
#include "../battery/BATTERIES.h"
|
||||
#include "../communication/can/comm_can.h"
|
||||
#include "../datalayer/datalayer.h"
|
||||
#include "../devboard/utils/events.h"
|
||||
|
@ -131,10 +132,10 @@ void PylonBattery::setup(void) { // Performs one time setup at startup
|
|||
strncpy(datalayer.system.info.battery_protocol, "Pylon compatible battery", 63);
|
||||
datalayer.system.info.battery_protocol[63] = '\0';
|
||||
datalayer_battery->info.number_of_cells = 2;
|
||||
datalayer_battery->info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV;
|
||||
datalayer_battery->info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV;
|
||||
datalayer_battery->info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV;
|
||||
datalayer_battery->info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV;
|
||||
datalayer_battery->info.max_design_voltage_dV = user_selected_max_pack_voltage_dV;
|
||||
datalayer_battery->info.min_design_voltage_dV = user_selected_min_pack_voltage_dV;
|
||||
datalayer_battery->info.max_cell_voltage_mV = user_selected_max_cell_voltage_mV;
|
||||
datalayer_battery->info.min_cell_voltage_mV = user_selected_min_cell_voltage_mV;
|
||||
|
||||
datalayer.battery2.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV;
|
||||
|
||||
|
|
|
@ -32,11 +32,6 @@ class PylonBattery : public CanBattery {
|
|||
static constexpr const char* Name = "Pylon compatible battery";
|
||||
|
||||
private:
|
||||
/* Change the following to suit your battery */
|
||||
static const int MAX_PACK_VOLTAGE_DV = 5000; //5000 = 500.0V
|
||||
static const int MIN_PACK_VOLTAGE_DV = 1500;
|
||||
static const int MAX_CELL_VOLTAGE_MV = 4250; //Battery is put into emergency stop if one cell goes over this value
|
||||
static const int MIN_CELL_VOLTAGE_MV = 2700; //Battery is put into emergency stop if one cell goes below this value
|
||||
static const int MAX_CELL_DEVIATION_MV = 150;
|
||||
|
||||
DATALAYER_BATTERY_TYPE* datalayer_battery;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "RJXZS-BMS.h"
|
||||
#include "../battery/BATTERIES.h"
|
||||
#include "../communication/can/comm_can.h"
|
||||
#include "../datalayer/datalayer.h"
|
||||
#include "../devboard/utils/events.h"
|
||||
|
@ -511,9 +512,9 @@ void RjxzsBms::transmit_can(unsigned long currentMillis) {
|
|||
void RjxzsBms::setup(void) { // Performs one time setup at startup
|
||||
strncpy(datalayer.system.info.battery_protocol, Name, 63);
|
||||
datalayer.system.info.battery_protocol[63] = '\0';
|
||||
datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV;
|
||||
datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV;
|
||||
datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV;
|
||||
datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV;
|
||||
datalayer.battery.info.max_design_voltage_dV = user_selected_max_pack_voltage_dV;
|
||||
datalayer.battery.info.min_design_voltage_dV = user_selected_min_pack_voltage_dV;
|
||||
datalayer.battery.info.max_cell_voltage_mV = user_selected_max_cell_voltage_mV;
|
||||
datalayer.battery.info.min_cell_voltage_mV = user_selected_min_cell_voltage_mV;
|
||||
datalayer.system.status.battery_allows_contactor_closing = true;
|
||||
}
|
||||
|
|
|
@ -20,11 +20,6 @@ class RjxzsBms : public CanBattery {
|
|||
|
||||
private:
|
||||
/* Tweak these according to your battery build */
|
||||
static const int MAX_PACK_VOLTAGE_DV = 5000; //5000 = 500.0V
|
||||
static const int MIN_PACK_VOLTAGE_DV = 1500;
|
||||
static const int MAX_CELL_VOLTAGE_MV = 4250; //Battery is put into emergency stop if one cell goes over this value
|
||||
static const int MIN_CELL_VOLTAGE_MV = 2700; //Battery is put into emergency stop if one cell goes below this value
|
||||
static const int MAX_CELL_DEVIATION_MV = 250;
|
||||
static const int MAX_DISCHARGE_POWER_ALLOWED_W = 5000;
|
||||
static const int MAX_CHARGE_POWER_ALLOWED_W = 5000;
|
||||
static const int MAX_CHARGE_POWER_WHEN_TOPBALANCING_W = 500;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "SIMPBMS-BATTERY.h"
|
||||
#include "../battery/BATTERIES.h"
|
||||
#include "../datalayer/datalayer.h"
|
||||
#include "../devboard/utils/events.h"
|
||||
|
||||
|
@ -93,9 +94,9 @@ void SimpBmsBattery::transmit_can(unsigned long currentMillis) {
|
|||
void SimpBmsBattery::setup(void) { // Performs one time setup at startup
|
||||
strncpy(datalayer.system.info.battery_protocol, Name, 63);
|
||||
datalayer.system.info.battery_protocol[63] = '\0';
|
||||
datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV;
|
||||
datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV;
|
||||
datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV;
|
||||
datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV;
|
||||
datalayer.battery.info.max_design_voltage_dV = user_selected_max_pack_voltage_dV;
|
||||
datalayer.battery.info.min_design_voltage_dV = user_selected_min_pack_voltage_dV;
|
||||
datalayer.battery.info.max_cell_voltage_mV = user_selected_max_cell_voltage_mV;
|
||||
datalayer.battery.info.min_cell_voltage_mV = user_selected_min_cell_voltage_mV;
|
||||
datalayer.system.status.battery_allows_contactor_closing = true;
|
||||
}
|
||||
|
|
|
@ -16,13 +16,6 @@ class SimpBmsBattery : public CanBattery {
|
|||
static constexpr const char* Name = "SIMPBMS battery";
|
||||
|
||||
private:
|
||||
/* DEFAULT VALUES BMS will send configured */
|
||||
static const int MAX_PACK_VOLTAGE_DV = 5000; //5000 = 500.0V
|
||||
static const int MIN_PACK_VOLTAGE_DV = 1500;
|
||||
static const int MAX_CELL_VOLTAGE_MV = 4250; //Battery is put into emergency stop if one cell goes over this value
|
||||
static const int MIN_CELL_VOLTAGE_MV = 2700; //Battery is put into emergency stop if one cell goes below this value
|
||||
static const int MAX_CELL_DEVIATION_MV = 500;
|
||||
|
||||
static const int SIMPBMS_MAX_CELLS = 128;
|
||||
|
||||
unsigned long previousMillis1000 = 0; // will store last time a 1s CAN Message was sent
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "comm_nvm.h"
|
||||
#include "../../battery/BATTERIES.h"
|
||||
#include "../../battery/Battery.h"
|
||||
#include "../../battery/Shunt.h"
|
||||
#include "../../charger/CanCharger.h"
|
||||
|
@ -91,6 +92,10 @@ void init_stored_settings() {
|
|||
user_selected_inverter_protocol = (InverterProtocolType)settings.getUInt("INVTYPE", (int)InverterProtocolType::None);
|
||||
user_selected_charger_type = (ChargerType)settings.getUInt("CHGTYPE", (int)ChargerType::None);
|
||||
user_selected_shunt_type = (ShuntType)settings.getUInt("SHUNTTYPE", (int)ShuntType::None);
|
||||
user_selected_max_pack_voltage_dV = settings.getUInt("BATTPVMAX", 0);
|
||||
user_selected_min_pack_voltage_dV = settings.getUInt("BATTPVMIN", 0);
|
||||
user_selected_max_cell_voltage_mV = settings.getUInt("BATTCVMAX", 0);
|
||||
user_selected_min_cell_voltage_mV = settings.getUInt("BATTCVMIN", 0);
|
||||
|
||||
auto readIf = [](const char* settingName) {
|
||||
auto batt1If = (comm_interface)settings.getUInt(settingName, (int)comm_interface::CanNative);
|
||||
|
|
|
@ -17,6 +17,9 @@ function reboot() {
|
|||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', '/reboot', true);
|
||||
xhr.send();
|
||||
setTimeout(function() {
|
||||
window.location = "/";
|
||||
}, 3000);
|
||||
}
|
||||
</script>
|
||||
)rawliteral"
|
||||
|
|
|
@ -306,6 +306,22 @@ String settings_processor(const String& var, BatteryEmulatorSettingsStore& setti
|
|||
}
|
||||
}
|
||||
|
||||
if (var == "BATTPVMAX") {
|
||||
return String(static_cast<float>(settings.getUInt("BATTPVMAX", 0)) / 10.0, 1);
|
||||
}
|
||||
|
||||
if (var == "BATTPVMIN") {
|
||||
return String(static_cast<float>(settings.getUInt("BATTPVMIN", 0)) / 10.0, 1);
|
||||
}
|
||||
|
||||
if (var == "BATTCVMAX") {
|
||||
return String(settings.getUInt("BATTCVMAX", 0));
|
||||
}
|
||||
|
||||
if (var == "BATTCVMIN") {
|
||||
return String(settings.getUInt("BATTCVMIN", 0));
|
||||
}
|
||||
|
||||
if (var == "BATTERY_WH_MAX") {
|
||||
return String(datalayer.battery.info.total_capacity_Wh);
|
||||
}
|
||||
|
@ -593,23 +609,13 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
|
||||
function goToMainPage() { window.location.href = '/'; }
|
||||
|
||||
function toggleMqtt() {
|
||||
var mqttEnabled = document.querySelector('input[name="MQTTENABLED"]').checked;
|
||||
document.querySelectorAll('.mqtt-settings').forEach(function (el) {
|
||||
el.style.display = mqttEnabled ? 'contents' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', toggleMqtt);
|
||||
|
||||
function toggleTopics() {
|
||||
var topicsEnabled = document.querySelector('input[name="MQTTTOPICS"]').checked;
|
||||
document.querySelectorAll('.mqtt-topics').forEach(function (el) {
|
||||
el.style.display = topicsEnabled ? 'contents' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', toggleTopics);
|
||||
document.querySelectorAll('select,input').forEach(function(sel) {
|
||||
function ch() {
|
||||
sel.closest('form').setAttribute('data-' + sel.name?.toLowerCase(), sel.type=='checkbox'?sel.checked:sel.value);
|
||||
}
|
||||
sel.addEventListener('change', ch);
|
||||
ch();
|
||||
});
|
||||
</script>
|
||||
)rawliteral"
|
||||
|
||||
|
@ -621,7 +627,7 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
cursor: pointer; border-radius: 10px; }
|
||||
button:hover { background-color: #3A4A52; }
|
||||
h4 { margin: 0.6em 0; line-height: 1.2; }
|
||||
select { max-width: 250px; }
|
||||
select, input { max-width: 250px; box-sizing: border-box; }
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
@ -641,6 +647,32 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
grid-column: span 2;
|
||||
}
|
||||
|
||||
form .if-battery, form .if-inverter, form .if-charger, form .if-shunt { display: contents; }
|
||||
form[data-battery="0"] .if-battery { display: none; }
|
||||
form[data-inverter="0"] .if-inverter { display: none; }
|
||||
form[data-charger="0"] .if-charger { display: none; }
|
||||
form[data-shunt="0"] .if-shunt { display: none; }
|
||||
|
||||
form .if-cbms { display: none; }
|
||||
form[data-battery="6"] .if-cbms, form[data-battery="11"] .if-cbms, form[data-battery="22"] .if-cbms, form[data-battery="23"] .if-cbms, form[data-battery="24"] .if-cbms, form[data-battery="31"] .if-cbms {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
form .if-dblbtr { display: none; }
|
||||
form[data-dblbtr="true"] .if-dblbtr {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
form .if-mqtt { display: none; }
|
||||
form[data-mqttenabled="true"] .if-mqtt {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
form .if-topics { display: none; }
|
||||
form[data-mqtttopics="true"] .if-topics {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
</style>
|
||||
)rawliteral"
|
||||
|
||||
|
@ -654,13 +686,13 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
|
||||
<div style='background-color: #404E47; padding: 10px; margin-bottom: 10px;border-radius: 50px; class="%COMMONIMAGEDIVCLASS%">
|
||||
<div style='max-width: 500px;'>
|
||||
<form action='saveSettings' method='post' style='display: grid; grid-template-columns: 1fr 2fr; gap: 10px;
|
||||
align-items: center;'>
|
||||
<form action='saveSettings' method='post' style='display: grid; grid-template-columns: 1fr 1.5fr; gap: 10px; align-items: center;'>
|
||||
|
||||
<label for='battery'>Battery: </label><select name='battery' if='battery'>
|
||||
%BATTTYPE%
|
||||
</select>
|
||||
|
||||
<div class="if-battery">
|
||||
<label for='BATTCOMM'>Battery comm I/F: </label><select name='BATTCOMM' id='BATTCOMM'>
|
||||
%BATTCOMM%
|
||||
</select>
|
||||
|
@ -668,30 +700,51 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
<label>Battery chemistry: </label><select name='BATTCHEM'>
|
||||
%BATTCHEM%
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="if-cbms">
|
||||
<label>Battery max design voltage (V): </label>
|
||||
<input name='BATTPVMAX' pattern="^[0-9]+(\.[0-9]+)?$" type='text' value='%BATTPVMAX%' />
|
||||
|
||||
<label>Battery min design voltage (V): </label>
|
||||
<input name='BATTPVMIN' pattern="^[0-9]+(\.[0-9]+)?$" type='text' value='%BATTPVMIN%' />
|
||||
|
||||
<label>Cell max design voltage (mV): </label>
|
||||
<input name='BATTCVMAX' pattern="^[0-9]+$" type='text' value='%BATTCVMAX%' />
|
||||
|
||||
<label>Cell min design voltage (mV): </label>
|
||||
<input name='BATTCVMIN' pattern="^[0-9]+$" type='text' value='%BATTCVMIN%' />
|
||||
</div>
|
||||
|
||||
<label>Inverter protocol: </label><select name='inverter'>
|
||||
%INVTYPE%
|
||||
</select>
|
||||
|
||||
<div class="if-inverter">
|
||||
<label>Inverter comm I/F: </label><select name='INVCOMM'>
|
||||
%INVCOMM%
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label>Charger: </label><select name='charger'>
|
||||
%CHGTYPE%
|
||||
</select>
|
||||
|
||||
<div class="if-charger">
|
||||
<label>Charger comm I/F: </label><select name='CHGCOMM'>
|
||||
%CHGCOMM%
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label>Shunt: </label><select name='SHUNT'>
|
||||
%SHUNTTYPE%
|
||||
</select>
|
||||
|
||||
<div class="if-shunt">
|
||||
<label>Shunt comm I/F: </label><select name='SHUNTCOMM'>
|
||||
%SHUNTCOMM%
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label>Equipment stop button: </label><select name='EQSTOP'>
|
||||
%EQSTOP%
|
||||
|
@ -700,15 +753,19 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
<label>Double battery: </label>
|
||||
<input type='checkbox' name='DBLBTR' value='on' style='margin-left: 0;' %DBLBTR% />
|
||||
|
||||
<div class="if-dblbtr">
|
||||
<label>Battery 2 comm I/F: </label><select name='BATT2COMM'>
|
||||
%BATT2COMM%
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label>Contactor control: </label>
|
||||
<input type='checkbox' name='CNTCTRL' value='on' style='margin-left: 0;' %CNTCTRL% />
|
||||
|
||||
<div class="if-dblbtr">
|
||||
<label>Contactor control double battery: </label>
|
||||
<input type='checkbox' name='CNTCTRLDBL' value='on' style='margin-left: 0;' %CNTCTRLDBL% />
|
||||
</div>
|
||||
|
||||
<label>PWM contactor control: </label>
|
||||
<input type='checkbox' name='PWMCNTCTRL' value='on' style='margin-left: 0;' %PWMCNTCTRL% />
|
||||
|
@ -726,26 +783,26 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
<input type='checkbox' name='WIFIAPENABLED' value='on' style='margin-left: 0;' %WIFIAPENABLED% />
|
||||
|
||||
<label>Custom hostname: </label>
|
||||
<input style='max-width: 250px;' type='text' name='HOSTNAME' value="%HOSTNAME%" />
|
||||
<input type='text' name='HOSTNAME' value="%HOSTNAME%" />
|
||||
|
||||
<label>Enable MQTT: </label>
|
||||
<input type='checkbox' name='MQTTENABLED' value='on' onchange='toggleMqtt()' style='margin-left: 0;' %MQTTENABLED% />
|
||||
<input type='checkbox' name='MQTTENABLED' value='on' style='margin-left: 0;' %MQTTENABLED% />
|
||||
|
||||
<div class='mqtt-settings'>
|
||||
<label>MQTT server: </label><input style='max-width: 250px;' type='text' name='MQTTSERVER' value="%MQTTSERVER%" />
|
||||
<label>MQTT port: </label><input style='max-width: 250px;' type='text' name='MQTTPORT' value="%MQTTPORT%" />
|
||||
<label>MQTT user: </label><input style='max-width: 250px;' type='text' name='MQTTUSER' value="%MQTTUSER%" />
|
||||
<label>MQTT password: </label><input style='max-width: 250px;' type='password' name='MQTTPASSWORD' value="%MQTTPASSWORD%" />
|
||||
<div class='if-mqtt'>
|
||||
<label>MQTT server: </label><input type='text' name='MQTTSERVER' value="%MQTTSERVER%" />
|
||||
<label>MQTT port: </label><input type='text' name='MQTTPORT' value="%MQTTPORT%" />
|
||||
<label>MQTT user: </label><input type='text' name='MQTTUSER' value="%MQTTUSER%" />
|
||||
<label>MQTT password: </label><input type='password' name='MQTTPASSWORD' value="%MQTTPASSWORD%" />
|
||||
|
||||
<label>Customized MQTT topics: </label>
|
||||
<input type='checkbox' name='MQTTTOPICS' value='on' onchange='toggleTopics()' style='margin-left: 0;' %MQTTTOPICS% />
|
||||
<input type='checkbox' name='MQTTTOPICS' value='on' style='margin-left: 0;' %MQTTTOPICS% />
|
||||
|
||||
<div class='mqtt-topics'>
|
||||
<div class='if-topics'>
|
||||
|
||||
<label>MQTT topic name: </label><input style='max-width: 250px;' type='text' name='MQTTTOPIC' value="%MQTTTOPIC%" />
|
||||
<label>Prefix for MQTT object ID: </label><input style='max-width: 250px;' type='text' name='MQTTOBJIDPREFIX' value="%MQTTOBJIDPREFIX%" />
|
||||
<label>HA device name: </label><input style='max-width: 250px;' type='text' name='MQTTDEVICENAME' value="%MQTTDEVICENAME%" />
|
||||
<label>HA device ID: </label><input style='max-width: 250px;' type='text' name='HADEVICEID' value="%HADEVICEID%" />
|
||||
<label>MQTT topic name: </label><input type='text' name='MQTTTOPIC' value="%MQTTTOPIC%" />
|
||||
<label>Prefix for MQTT object ID: </label><input type='text' name='MQTTOBJIDPREFIX' value="%MQTTOBJIDPREFIX%" />
|
||||
<label>HA device name: </label><input type='text' name='MQTTDEVICENAME' value="%MQTTDEVICENAME%" />
|
||||
<label>HA device ID: </label><input type='text' name='HADEVICEID' value="%HADEVICEID%" />
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -754,10 +811,10 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
|
||||
</div>
|
||||
|
||||
<div style='grid-column: span 2; text-align: center; padding-top: 10px;'><button "type='submit'>Save</button></div>
|
||||
<div style='grid-column: span 2; text-align: center; padding-top: 10px;'><button type='submit'>Save</button></div>
|
||||
|
||||
<div style='grid-column: span 2; text-align: center; padding-top: 10px;' class="%SAVEDCLASS%">
|
||||
<p>Settings saved. Reboot to take the settings into use.<p> <button onclick='askReboot()'>Reboot</button>
|
||||
<p>Settings saved. Reboot to take the settings into use.<p> <button type='button' onclick='askReboot()'>Reboot</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
|
|
@ -445,6 +445,18 @@ void init_webserver() {
|
|||
} else if (p->name() == "BATTCOMM") {
|
||||
auto type = static_cast<comm_interface>(atoi(p->value().c_str()));
|
||||
settings.saveUInt("BATTCOMM", (int)type);
|
||||
} else if (p->name() == "BATTPVMAX") {
|
||||
auto type = p->value().toFloat() * 10.0;
|
||||
settings.saveUInt("BATTPVMAX", (int)type);
|
||||
} else if (p->name() == "BATTPVMIN") {
|
||||
auto type = p->value().toFloat() * 10.0;
|
||||
settings.saveUInt("BATTPVMIN", (int)type);
|
||||
} else if (p->name() == "BATTCVMAX") {
|
||||
auto type = atoi(p->value().c_str());
|
||||
settings.saveUInt("BATTCVMAX", type);
|
||||
} else if (p->name() == "BATTCVMIN") {
|
||||
auto type = atoi(p->value().c_str());
|
||||
settings.saveUInt("BATTCVMIN", type);
|
||||
} else if (p->name() == "charger") {
|
||||
auto type = static_cast<ChargerType>(atoi(p->value().c_str()));
|
||||
settings.saveUInt("CHGTYPE", (int)type);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue