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:
@@ -0,0 +1 @@
|
||||
add_subdirectory(light_switch)
|
||||
@@ -0,0 +1,16 @@
|
||||
add_executable(light_switch)
|
||||
|
||||
target_sources(light_switch
|
||||
PRIVATE
|
||||
light_switch.cpp
|
||||
states.cpp
|
||||
context.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(light_switch
|
||||
PRIVATE
|
||||
fsm::fsm
|
||||
)
|
||||
|
||||
# target_compile_definitions(light_switch PUBLIC HEAP_FREE_MODE)
|
||||
target_compile_features(light_switch PRIVATE cxx_std_14)
|
||||
@@ -0,0 +1,9 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2023 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#include "fsm.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
void Context::set_brightness(int value) {
|
||||
printf("Set brightness to %d\n", value);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2023 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef FSM_HPP
|
||||
#define FSM_HPP
|
||||
|
||||
#include <fsm/buffer.hpp>
|
||||
#include <fsm/fsm.hpp>
|
||||
|
||||
struct Context {
|
||||
void set_brightness(int value);
|
||||
};
|
||||
|
||||
enum class Event {
|
||||
PRESSED_ON,
|
||||
PRESSED_OFF,
|
||||
ENTER_MOTION_MODE,
|
||||
MOTION_DETECT,
|
||||
MOTION_TIMEOUT,
|
||||
};
|
||||
|
||||
#ifdef HEAP_FREE_MODE
|
||||
using BufferType = fsm::buffer::SwapBuffer<24, 16, 2>;
|
||||
using FSM = fsm::FSM<Event, int, BufferType>;
|
||||
#else
|
||||
using FSM = fsm::FSM<Event, int>;
|
||||
#endif
|
||||
|
||||
using SimpleState = fsm::states::StateWithContext<FSM::SimpleStateType, Context>;
|
||||
using CompoundState = fsm::states::StateWithContext<FSM::CompoundStateType, Context>;
|
||||
|
||||
static const auto PASS_ON = FSM::StateAllocatorType::PASS_ON;
|
||||
static const auto HANDLED_INTERNALLY = FSM::StateAllocatorType::HANDLED_INTERNALLY;
|
||||
|
||||
#endif // FSM_HPP
|
||||
@@ -0,0 +1,89 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2023 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "fsm.hpp"
|
||||
#include "states.hpp"
|
||||
|
||||
auto delayed_timepoint(int delay_ms) {
|
||||
return std::chrono::steady_clock::now() + std::chrono::milliseconds(delay_ms);
|
||||
}
|
||||
|
||||
void feed_machine_until(FSM& machine, int delay_ms) {
|
||||
auto next_event_tp = delayed_timepoint(delay_ms);
|
||||
|
||||
while (true) {
|
||||
|
||||
auto feed_result = machine.feed();
|
||||
if (feed_result.transition()) {
|
||||
continue;
|
||||
} else if (feed_result.unhandled_event()) {
|
||||
break;
|
||||
} else if (feed_result.has_value() == false) {
|
||||
// returning no value means don't do anything
|
||||
break;
|
||||
}
|
||||
|
||||
// fall-through: got a value
|
||||
if (*feed_result == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto next_feed_tp = delayed_timepoint(*feed_result);
|
||||
if (next_feed_tp < next_event_tp) {
|
||||
std::this_thread::sleep_until(next_feed_tp);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::this_thread::sleep_until(next_event_tp);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
Context ctx;
|
||||
|
||||
const int DEFAULT_DELAY = 200;
|
||||
|
||||
struct EventTodo {
|
||||
Event event;
|
||||
int delay;
|
||||
};
|
||||
|
||||
auto events = std::vector<EventTodo>({
|
||||
{Event::PRESSED_ON, DEFAULT_DELAY},
|
||||
{Event::PRESSED_ON, DEFAULT_DELAY},
|
||||
{Event::PRESSED_ON, DEFAULT_DELAY},
|
||||
{Event::ENTER_MOTION_MODE, DEFAULT_DELAY},
|
||||
{Event::PRESSED_ON, DEFAULT_DELAY},
|
||||
{Event::PRESSED_OFF, DEFAULT_DELAY},
|
||||
{Event::ENTER_MOTION_MODE, DEFAULT_DELAY},
|
||||
{Event::MOTION_DETECT, 6000},
|
||||
{Event::MOTION_TIMEOUT, DEFAULT_DELAY},
|
||||
{Event::MOTION_DETECT, DEFAULT_DELAY},
|
||||
{Event::PRESSED_ON, DEFAULT_DELAY},
|
||||
{Event::PRESSED_ON, DEFAULT_DELAY},
|
||||
});
|
||||
|
||||
#ifdef HEAP_FREE_MODE
|
||||
BufferType static_buffer{};
|
||||
FSM machine(static_buffer);
|
||||
#else
|
||||
FSM machine{};
|
||||
#endif
|
||||
|
||||
machine.reset<LightOff>(ctx);
|
||||
|
||||
for (const auto& todo : events) {
|
||||
machine.handle_event(todo.event);
|
||||
|
||||
feed_machine_until(machine, todo.delay);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 46 KiB |
@@ -0,0 +1,62 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2023 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#include "states.hpp"
|
||||
|
||||
SimpleState::HandleEventReturnType LightOn::handle_event(AllocatorType& sa, Event ev) {
|
||||
if (ev == Event::PRESSED_ON) {
|
||||
current_brightness = (current_brightness % 3) + 1;
|
||||
ctx.set_brightness(current_brightness);
|
||||
return HANDLED_INTERNALLY;
|
||||
} else if (ev == Event::PRESSED_OFF) {
|
||||
return sa.create_simple<LightOff>(ctx);
|
||||
} else {
|
||||
return PASS_ON;
|
||||
}
|
||||
}
|
||||
|
||||
SimpleState::HandleEventReturnType MotionMode::handle_event(AllocatorType& sa, Event ev) {
|
||||
if (ev == Event::PRESSED_OFF) {
|
||||
return sa.create_simple<LightOff>(ctx);
|
||||
} else if (ev == Event::PRESSED_ON) {
|
||||
return sa.create_simple<LightOn>(ctx);
|
||||
} else {
|
||||
return PASS_ON;
|
||||
}
|
||||
}
|
||||
|
||||
SimpleState::HandleEventReturnType MotionDetected::handle_event(AllocatorType& sa, Event ev) {
|
||||
if (ev == Event::MOTION_TIMEOUT) {
|
||||
return sa.create_simple<MotionIdle>(ctx);
|
||||
} else {
|
||||
return PASS_ON;
|
||||
}
|
||||
}
|
||||
|
||||
SimpleState::CallbackReturnType MotionDetected::callback() {
|
||||
if (timeout_started) {
|
||||
return Event::MOTION_TIMEOUT;
|
||||
}
|
||||
|
||||
timeout_started = true;
|
||||
|
||||
return TIMEOUT_MS;
|
||||
}
|
||||
|
||||
SimpleState::HandleEventReturnType LightOff::handle_event(AllocatorType& sa, Event ev) {
|
||||
if (ev == Event::PRESSED_ON) {
|
||||
return sa.create_simple<LightOn>(ctx);
|
||||
} else if (ev == Event::ENTER_MOTION_MODE) {
|
||||
sa.create_compound<MotionMode>(ctx);
|
||||
return sa.create_simple<MotionIdle>(ctx);
|
||||
} else {
|
||||
return PASS_ON;
|
||||
}
|
||||
}
|
||||
|
||||
SimpleState::HandleEventReturnType MotionIdle::handle_event(AllocatorType& sa, Event ev) {
|
||||
if (ev == Event::MOTION_DETECT) {
|
||||
return sa.create_simple<MotionDetected>(ctx);
|
||||
} else {
|
||||
return PASS_ON;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2023 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef STATES_HPP
|
||||
#define STATES_HPP
|
||||
|
||||
#include "fsm.hpp"
|
||||
|
||||
struct LightOff : public SimpleState {
|
||||
using SimpleState::SimpleState;
|
||||
|
||||
void enter() final {
|
||||
ctx.set_brightness(0);
|
||||
}
|
||||
|
||||
HandleEventReturnType handle_event(AllocatorType&, Event) final;
|
||||
};
|
||||
|
||||
struct LightOn : public SimpleState {
|
||||
using SimpleState::SimpleState;
|
||||
|
||||
void enter() final {
|
||||
ctx.set_brightness(current_brightness);
|
||||
}
|
||||
|
||||
HandleEventReturnType handle_event(AllocatorType&, Event) final;
|
||||
|
||||
private:
|
||||
int current_brightness{1};
|
||||
};
|
||||
|
||||
struct MotionMode : public CompoundState {
|
||||
using CompoundState::CompoundState;
|
||||
|
||||
HandleEventReturnType handle_event(AllocatorType&, Event) final;
|
||||
};
|
||||
|
||||
struct MotionIdle : public SimpleState {
|
||||
using SimpleState::SimpleState;
|
||||
|
||||
void enter() final {
|
||||
ctx.set_brightness(0);
|
||||
}
|
||||
|
||||
HandleEventReturnType handle_event(AllocatorType&, Event) final;
|
||||
};
|
||||
|
||||
struct MotionDetected : public SimpleState {
|
||||
using SimpleState::SimpleState;
|
||||
|
||||
void enter() final {
|
||||
ctx.set_brightness(3);
|
||||
}
|
||||
|
||||
HandleEventReturnType handle_event(AllocatorType&, Event) final;
|
||||
|
||||
CallbackReturnType callback() final;
|
||||
|
||||
private:
|
||||
static const int TIMEOUT_MS = 3000;
|
||||
bool timeout_started{false};
|
||||
};
|
||||
|
||||
#endif // STATES_HPP
|
||||
Reference in New Issue
Block a user