Skip to content

Commit

Permalink
modbus_tcp: Add phase switch.
Browse files Browse the repository at this point in the history
  • Loading branch information
rtrbt committed Oct 31, 2024
1 parent c622fb2 commit 67144fc
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 21 deletions.
12 changes: 11 additions & 1 deletion software/src/modules/modbus_tcp/modbus_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ def str_(len_):
(f32_block(85), 'meter_values'),
]),

RegisterBlock('phase_switch_input_regs', 'input', 3100, 4, [
(u32(), "phases_connected"),
(u32(), "external_control_state"),
]),

RegisterBlock('nfc_input_regs', 'input', 4000, 12, [
(str_(20), "tag_id"),
(u32(), "tag_id_age"),
Expand All @@ -213,12 +218,17 @@ def str_(len_):
(u32(), "trigger_reset"),
]),

RegisterBlock('phase_switch_holding_regs', 'holding', 3100, 2, [
(u32(), "phases_wanted"),
]),


RegisterBlock('discrete_inputs', 'discrete', 0, 6, [
(bit(), "evse"),
(bit(), "meter"),
(bit(), "meter_phases"),
(bit(), "meter_all_values"),
(bit(), "cp_disconnect"),
(bit(), "phase_switch"),
(bit(), "nfc"),
]),

Expand Down
22 changes: 22 additions & 0 deletions software/src/modules/modbus_tcp/modbus_tcp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,10 @@ ModbusTcp::TwoRegs ModbusTcp::getWarpInputRegister(uint16_t reg, void *ctx_ptr)
}
break;
//2100... handled below

case 3100: REQUIRE(phase_switch); val.u = power_manager.get_is_3phase() ? 3 : 1; break;
case 3102: REQUIRE(phase_switch); val.u = cache->power_manager_state->get("external_control")->asUint(); break;

//4000... handled below
case 4010: REQUIRE(nfc); {
fillTagCache(ctx->tag);
Expand Down Expand Up @@ -652,6 +656,7 @@ void ModbusTcp::getWarpInputRegisters(uint16_t start_address, uint16_t data_coun
FILL_FEATURE_CACHE(meter_all_values)
FILL_FEATURE_CACHE(charge_tracker)
FILL_FEATURE_CACHE(nfc)
FILL_FEATURE_CACHE(phase_switch)

int i = 0;
while (i < data_count) {
Expand Down Expand Up @@ -696,6 +701,9 @@ ModbusTcp::TwoRegs ModbusTcp::getWarpHoldingRegister(uint16_t reg) {
case 1006: REQUIRE(evse); val.u = cache->evse_indicator_led->get("duration")->asUint(); break;

case 2000: REQUIRE(meter); val.u = 0; break;

case 3100: REQUIRE(phase_switch); val.u = cache->power_manager_external_control->get("phases_wanted")->asUint(); break;

default: val.u = 0xAAAAAAAA; break;
}
return val;
Expand Down Expand Up @@ -747,6 +755,7 @@ void ModbusTcp::getWarpDiscreteInputs(uint16_t start_address, uint16_t data_coun
case 1: result = cache->has_feature_meter; break;
case 2: result = cache->has_feature_meter_phases; break;
case 3: result = cache->has_feature_meter_all_values; break;
case 4: result = cache->has_feature_phase_switch; break;
case 5: result = cache->has_feature_nfc; break;

case 2100: REQUIRE(meter_phases); result = cache->meter_phases->get("phases_connected")->get(0)->asBool(); break;
Expand Down Expand Up @@ -825,6 +834,7 @@ void ModbusTcp::setWarpCoils(uint16_t start_address, uint16_t data_count, uint8_
void ModbusTcp::setWarpHoldingRegisters(uint16_t start_address, uint16_t data_count, uint16_t *data_values) {
FILL_FEATURE_CACHE(evse)
FILL_FEATURE_CACHE(meter)
FILL_FEATURE_CACHE(phase_switch)

if (!cache->has_feature_evse || !cache->evse_slots->get(CHARGING_SLOT_MODBUS_TCP)->get("active")->asBool())
return;
Expand Down Expand Up @@ -877,6 +887,16 @@ void ModbusTcp::setWarpHoldingRegisters(uint16_t start_address, uint16_t data_co
// 1006 handled above.

case 2000: REQUIRE(meter); if (val.u == 0x3E12E5E7) api.callCommand("meter/reset", {}); break;
case 3100: REQUIRE(phase_switch); {
if (cache->power_manager_state->get("external_control")->asUint() == 0) {
String err = api.callCommand("power_manager/external_control_update", Config::ConfUpdateObject{{
{"phases_wanted", val.u}
}});
if (err != "") {
logger.printfln("Failed to switch phases: %s", err.c_str());
}
}
} break;
default: val.u = 0xAAAAAAAA; break;
}

Expand Down Expand Up @@ -955,6 +975,8 @@ void ModbusTcp::fillCache() {
cache->meter_values = api.getState("meter/values");
cache->meter_phases = api.getState("meter/phases");
cache->meter_all_values = api.getState("meter/all_values");
cache->power_manager_state = api.getState("power_manager/state");
cache->power_manager_external_control = api.getState("power_manager/external_control");
}

void ModbusTcp::register_events() {
Expand Down
3 changes: 3 additions & 0 deletions software/src/modules/modbus_tcp/modbus_tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,16 @@ class ModbusTcp final : public IModule
const Config *meter_values;
const Config *meter_phases;
const Config *meter_all_values;
const Config *power_manager_state;
const Config *power_manager_external_control;

bool has_feature_evse;
bool has_feature_meter;
bool has_feature_meter_phases;
bool has_feature_meter_all_values;
bool has_feature_charge_tracker;
bool has_feature_nfc;
bool has_feature_phase_switch;
};

union TwoRegs {
Expand Down
34 changes: 24 additions & 10 deletions software/web/src/modules/modbus_tcp/translation_de.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,25 @@ let x = {
<td>Siehe <a href="https://docs.warp-charger.com/docs/mqtt_http/api_reference/meter/#meter_all_values_any">API-Dokumentation</a></td>
</tr>
<tr>
<td>3000</td>
<td>CP-Unterbrechung</td>
<td>3100</td>
<td>Verbundene Phasen</td>
<td>uint32</td>
<td>cp_disc</td>
<td>Noch nicht implementiert!</td>
<td>phase_switch</td>
<td>Gibt an wie viele Phasen mit dem Fahrzeug verbunden sind (1 oder 3).</td>
</tr>
<tr>
<td>3102</td>
<td>Zustand der Phasenumschaltung</td>
<td>uint32</td>
<td>phase_switch</td>
<td>Aktueller Zustand der Phasenumschaltung:
<ul>
<li>0: Phasenumschaltung ist bereit für Kommandos.</li>
<li>1: Phasenumschaltung ist über die Einstellungen deaktiviert.</li>
<li>2: Phasenumschaltung ist aktiviert aber aktuell nicht verfügbar.</li>
<li>3: Phasenumschaltung wird gerade durchgeführt; ankommende Kommandos werden ignoriert.</li>
</ul>
</td>
</tr>
<tr>
<td>4000 bis 4009</td>
Expand Down Expand Up @@ -294,11 +308,11 @@ let x = {
<td>Setzt den relativen Energiewert zurück (Input Register 2006). Passwort: 0x3E12E5E7</td>
</tr>
<tr>
<td>3000</td>
<td>CP-Trennung auslösen</td>
<td>3100</td>
<td>Phasenumschaltung auslösen</td>
<td>uint32</td>
<td>cp_disc</td>
<td>Noch nicht implementiert!</td>
<td>phase_switch</td>
<td>1 für einphasiges Laden. 3 für dreiphasiges Laden.</td>
</tr>
</tbody>
<thead>
Expand Down Expand Up @@ -339,10 +353,10 @@ let x = {
</tr>
<tr>
<td>4</td>
<td>Feature "cp_disc" verfügbar</td>
<td>Feature "phase_switch" verfügbar</td>
<td>bool</td>
<td>---</td>
<td>Noch nicht implementiert!</td>
<td>Hardware und Konfiguration erlauben eine Phasenumschaltung-</td>
</tr>
<tr>
<td>5</td>
Expand Down
34 changes: 24 additions & 10 deletions software/web/src/modules/modbus_tcp/translation_en.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,25 @@ let x = {
<td>See <a href="https://docs.warp-charger.com/docs/mqtt_http/api_reference/meter/#meter_all_values_any">API Documentation</a></td>
</tr>
<tr>
<td>3000</td>
<td>CP-State</td>
<td>3100</td>
<td>Phases connected</td>
<td>uint32</td>
<td>cp_disc</td>
<td>Not implemented yet!</td>
<td>phase_switch</td>
<td>The number of phases connected to the vehicle</td>
</tr>
<tr>
<td>3102</td>
<td>Phase switch state</td>
<td>uint32</td>
<td>phase_switch</td>
<td>The current state of the phase switch control:
<ul>
<li>0: Ready to switch phases.</li>
<li>1: Phase switch disabled in settings.</li>
<li>2: Phase switch enabled, but currently not available.</li>
<li>3: Currently switching phases. Commands will be ignored.</li>
</ul>
</td>
</tr>
<tr>
<td>4000 to 4009</td>
Expand Down Expand Up @@ -292,11 +306,11 @@ let x = {
<td>Resets the relative energy value (input register 2006). Password: 0x3E12E5E7</td>
</tr>
<tr>
<td>3000</td>
<td>Trigger CP disconnect</td>
<td>3100</td>
<td>Trigger phase switch</td>
<td>uint32</td>
<td>cp_disc</td>
<td>Not implemented yet!</td>
<td>phase_switch</td>
<td>1 for single-phase charging. 3 for three-phase charging.</td>
</tr>
</tbody>
<thead>
Expand Down Expand Up @@ -337,10 +351,10 @@ let x = {
</tr>
<tr>
<td>4</td>
<td>Feature "cp_disc" available</td>
<td>Feature "phase_switch" available</td>
<td>bool</td>
<td>---</td>
<td>Not implemented yet!</td>
<td>Hardware and configuration support switching between single- and three-phase charging.</td>
</tr>
<tr>
<td>5</td>
Expand Down

0 comments on commit 67144fc

Please sign in to comment.