Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter

- CitrineOS core extracted (CSMS OCPP 2.0.1)
- OpenOCPP extracted (firmware OCPP 1.6J/2.0.1)
- ShapeShifter library installed (pip install -e)
- ShapeShifter specification extracted
- EVerest extracted

TODO updated with progress
This commit is contained in:
Eric F
2026-06-08 00:38:27 -04:00
parent 468cfeaa50
commit d398a6ced2
7326 changed files with 1177561 additions and 7 deletions

View File

@@ -0,0 +1,3 @@
add_subdirectory(messages)
add_subdirectory(io)
add_subdirectory(v20)

View File

@@ -0,0 +1,11 @@
include(Catch)
add_executable(test_timeout test_timeout.cpp)
target_link_libraries(test_timeout
PRIVATE
ieee2030::ieee2030
Catch2::Catch2WithMain
)
catch_discover_tests(test_timeout)

View File

@@ -0,0 +1,54 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest
#include <catch2/catch_test_macros.hpp>
#include <thread>
#include <ieee2030/common/io/time.hpp>
using namespace ieee2030;
SCENARIO("Testing timeout") {
GIVEN("Timeout not started") {
io::Timeout timeout;
WHEN("Check if timeout has not started") {
REQUIRE(timeout.timeout_reached() == std::nullopt);
}
}
GIVEN("Timeout 4 second started") {
io::Timeout timeout;
timeout.start(4);
WHEN("Check if timeout has started, but not reached") {
REQUIRE(timeout.timeout_reached() == false);
}
}
GIVEN("Timeout 1 second started") {
io::Timeout timeout;
timeout.start(1);
std::this_thread::sleep_for(std::chrono::seconds(1));
WHEN("Check if timeout has started and reached") {
REQUIRE(timeout.timeout_reached() == true);
}
}
GIVEN("Timeout 1 second started") {
io::Timeout timeout;
timeout.start(1);
WHEN("Check if reset is working") {
REQUIRE(timeout.timeout_reached() == false);
timeout.reset();
REQUIRE(timeout.timeout_reached() == std::nullopt);
}
}
}

View File

@@ -0,0 +1,21 @@
include(Catch)
add_executable(test_charger_messages charger_messages.cpp)
target_link_libraries(test_charger_messages
PRIVATE
ieee2030::ieee2030
Catch2::Catch2WithMain
)
catch_discover_tests(test_charger_messages)
add_executable(test_ev_messages ev_messages.cpp)
target_link_libraries(test_ev_messages
PRIVATE
ieee2030::ieee2030
Catch2::Catch2WithMain
)
catch_discover_tests(test_ev_messages)

View File

@@ -0,0 +1,98 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest
#include <catch2/catch_test_macros.hpp>
#include <ieee2030/common/messages/messages.hpp>
using namespace ieee2030;
SCENARIO("Charger 108 message") {
GIVEN("Create from payload") {
std::vector<uint8_t> payload = {1, 0x03, 0x20, 30, 0x03, 0x20, 0, 0};
auto charger_108 = messages::Charger108(payload);
THEN("Charger 108 should set correct!") {
REQUIRE(charger_108.identifier_welding_detection == 1);
REQUIRE(charger_108.available_voltage == 800.0);
REQUIRE(charger_108.available_current == 30.0);
REQUIRE(charger_108.threshold_voltage == 800.0);
}
}
GIVEN("Set payload with operator overload") {
auto charger_108 = messages::Charger108();
charger_108.identifier_welding_detection = 1;
charger_108.available_voltage = 400;
charger_108.available_current = 20;
charger_108.threshold_voltage = 250;
std::vector<uint8_t> payload = charger_108;
THEN("Charger108 payload should set correct!") {
REQUIRE(payload[0] == 0x01);
REQUIRE(payload[1] == 0x01);
REQUIRE(payload[2] == 0x90);
REQUIRE(payload[3] == 0x14);
REQUIRE(payload[4] == 0x00);
REQUIRE(payload[5] == 0xFA);
REQUIRE(payload[6] == 0x00);
REQUIRE(payload[7] == 0x00);
}
}
}
SCENARIO("Charger 109 message") {
GIVEN("Create from payload") {
std::vector<uint8_t> payload = {1, 0x01, 0xC2, 0xC8, 0, 0x05, 0xFF, 0x1E};
auto charger_109 = messages::Charger109(payload);
THEN("Charger 109 should set correct!") {
REQUIRE(charger_109.protocol == defs::ProtocolNumber::VERSION_1_X_X);
REQUIRE(charger_109.present_voltage == 450);
REQUIRE(charger_109.present_current == 200);
REQUIRE(charger_109.charger_status == true);
REQUIRE(charger_109.charger_malfunction == false);
REQUIRE(charger_109.connector_lock == true);
REQUIRE(charger_109.battery_incompatibility == false);
REQUIRE(charger_109.system_malfunction == false);
REQUIRE(charger_109.stop_control == false);
REQUIRE(charger_109.reamining_time_10s == 0xFF);
REQUIRE(charger_109.reamining_time_1min == 30);
}
}
GIVEN("Set payload with operator overload") {
auto charger_109 = messages::Charger109();
charger_109.protocol = defs::ProtocolNumber::VERSION_2_0;
charger_109.present_voltage = 450;
charger_109.present_current = 200;
charger_109.charger_status = true;
charger_109.charger_malfunction = false;
charger_109.connector_lock = true;
charger_109.battery_incompatibility = false;
charger_109.system_malfunction = false;
charger_109.stop_control = false;
charger_109.reamining_time_10s = 0xFF;
charger_109.reamining_time_1min = 30;
std::vector<uint8_t> payload = charger_109;
THEN("Charger109 payload should set correct!") {
REQUIRE(payload[0] == 0x02);
REQUIRE(payload[1] == 0x01);
REQUIRE(payload[2] == 0xC2);
REQUIRE(payload[3] == 0xC8);
REQUIRE(payload[4] == 0x00);
REQUIRE(payload[5] == 0x05);
REQUIRE(payload[6] == 0xFF);
REQUIRE(payload[7] == 0x1E);
}
}
}

View File

@@ -0,0 +1,74 @@
#include <catch2/catch_test_macros.hpp>
#include <ieee2030/common/messages/messages.hpp>
using namespace ieee2030;
SCENARIO("EV 100 message") {
GIVEN("Create from payload") {
std::vector<uint8_t> payload = {0x00, 0x00, 0x00, 0x00, 0x02, 0x26, 0x64, 0x00};
auto ev_100 = messages::EV100(payload);
THEN("EV 100 should set correct!") {
REQUIRE(ev_100.max_battery_voltage == 550);
REQUIRE(ev_100.charged_rate == 100);
}
}
GIVEN("Set payload with operator overload") {
auto ev_100 = messages::EV100();
ev_100.max_battery_voltage = 550;
std::vector<uint8_t> payload = ev_100;
THEN("EV 100 payload should set correct!") {
REQUIRE(payload[0] == 0x00);
REQUIRE(payload[1] == 0x00);
REQUIRE(payload[2] == 0x00);
REQUIRE(payload[3] == 0x00);
REQUIRE(payload[4] == 0x02);
REQUIRE(payload[5] == 0x26);
REQUIRE(payload[6] == 0x64);
REQUIRE(payload[7] == 0x00);
}
}
}
SCENARIO("EV 101 message") {
GIVEN("Create from payload") {
std::vector<uint8_t> payload = {0x00, 0x3C, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00};
auto ev_101 = messages::EV101(payload);
THEN("EV 101 should set correct!") {
REQUIRE(ev_101.max_charging_time_10s == 60);
REQUIRE(ev_101.max_charging_time_1min == 0x00);
REQUIRE(ev_101.estimated_charging_time_1min == 9);
REQUIRE(ev_101.total_capacity.has_value() == false);
}
}
GIVEN("Set payload with operator overload") {
auto ev_101 = messages::EV101();
ev_101.max_charging_time_10s = 60;
ev_101.max_charging_time_1min = 0x00;
ev_101.estimated_charging_time_1min = 9;
ev_101.total_capacity = 800;
std::vector<uint8_t> payload = ev_101;
THEN("EV 101 payload should set correct!") {
REQUIRE(payload[0] == 0x00);
REQUIRE(payload[1] == 0x3C);
REQUIRE(payload[2] == 0x00);
REQUIRE(payload[3] == 0x09);
REQUIRE(payload[4] == 0x00);
REQUIRE(payload[5] == 0x03);
REQUIRE(payload[6] == 0x20);
REQUIRE(payload[7] == 0x00);
}
}
}
SCENARIO("EV 102 message") {
}

View File

@@ -0,0 +1,11 @@
include(Catch)
add_executable(test_event_queue test_event_queue.cpp)
target_link_libraries(test_event_queue
PRIVATE
ieee2030::ieee2030
Catch2::Catch2WithMain
)
catch_discover_tests(test_event_queue)

View File

@@ -0,0 +1,68 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest
#include <catch2/catch_test_macros.hpp>
#include <ieee2030/charger/v20/control_event.hpp>
#include <ieee2030/common/v20/event_queue.hpp>
using namespace ieee2030;
SCENARIO("Testing event queue") {
GIVEN("Create event queue and check if queue is empty") {
events::EventQueue<charger::events::Event> queue;
THEN("Queue should be empty") {
REQUIRE(queue.pop() == std::nullopt);
}
}
GIVEN("Queue pop one element") {
events::EventQueue<charger::events::Event> queue;
queue.push(charger::events::StopCharging{true});
THEN("Queue should have one element") {
auto event = queue.pop();
REQUIRE(event.has_value());
REQUIRE(std::holds_alternative<charger::events::StopCharging>(event.value()) == true);
REQUIRE(queue.pop() == std::nullopt);
}
}
GIVEN("Queue pop 4 element") {
events::EventQueue<charger::events::Event> queue;
queue.push(charger::events::StopCharging{true});
queue.push(charger::events::CS1{false});
queue.push(charger::events::CS1{true});
queue.push(charger::events::ChargePermission{true});
THEN("Queue should have 4 elements in the correct order") {
auto event = queue.pop();
REQUIRE(event.has_value());
REQUIRE(std::holds_alternative<charger::events::StopCharging>(event.value()) == true);
const auto stop_charging = std::get<charger::events::StopCharging>(event.value());
REQUIRE(stop_charging == charger::events::StopCharging{true});
event = queue.pop();
REQUIRE(event.has_value());
REQUIRE(std::holds_alternative<charger::events::CS1>(event.value()) == true);
auto cs1 = std::get<charger::events::CS1>(event.value());
REQUIRE(cs1 == charger::events::CS1{false});
event = queue.pop();
REQUIRE(event.has_value());
REQUIRE(std::holds_alternative<charger::events::CS1>(event.value()) == true);
cs1 = std::get<charger::events::CS1>(event.value());
REQUIRE(cs1 == charger::events::CS1{true});
event = queue.pop();
REQUIRE(event.has_value());
REQUIRE(std::holds_alternative<charger::events::ChargePermission>(event.value()) == true);
const auto permission = std::get<charger::events::ChargePermission>(event.value());
REQUIRE(permission == charger::events::ChargePermission{true});
REQUIRE(queue.pop() == std::nullopt);
}
}
}