ocpp 0.24.1
A C++ implementation of the Open Charge Point Protocol
component_state_manager.hpp
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
3
4#pragma once
5
6#include "database_handler.hpp"
7#include <ocpp/v2/ocpp_enums.hpp>
8
9namespace ocpp::v2 {
10
12class EvseOutOfRangeException : public std::exception {
13public:
14 explicit EvseOutOfRangeException(int32_t id) : msg{"Evse with id " + std::to_string(id) + " does not exist"} {
15 }
16
17 ~EvseOutOfRangeException() noexcept override = default;
18
19 const char* what() const noexcept override {
20 return msg.c_str();
21 }
22
23private:
24 std::string msg;
25};
26
28class ConnectorOutOfRangeException : public std::exception {
29public:
30 explicit ConnectorOutOfRangeException(int32_t connector_id, int32_t evse_id) :
31 msg{"Connector with id " + std::to_string(connector_id) + " does not exist for evse with id " +
32 std::to_string(evse_id)} {
33 }
34
35 ~ConnectorOutOfRangeException() noexcept override = default;
36
37 const char* what() const noexcept override {
38 return msg.c_str();
39 }
40
41private:
42 std::string msg;
43};
44
48 OperationalStatusEnum individual_operational_status;
50 bool faulted;
57
61 ConnectorStatusEnum to_connector_status();
62};
63
65public:
67
70 const std::function<void(const OperationalStatusEnum new_status)>& callback) = 0;
71
74 const std::function<void(const int32_t evse_id, const OperationalStatusEnum new_status)>& callback) = 0;
75
78 const std::function<void(const int32_t evse_id, const int32_t connector_id,
79 const OperationalStatusEnum new_status)>& callback) = 0;
80
82 virtual OperationalStatusEnum get_cs_individual_operational_status() = 0;
83
87 virtual OperationalStatusEnum get_evse_individual_operational_status(int32_t evse_id) = 0;
88
92 virtual OperationalStatusEnum get_connector_individual_operational_status(int32_t evse_id,
93 int32_t connector_id) = 0;
94
98 virtual OperationalStatusEnum get_cs_persisted_operational_status() = 0;
99
103 virtual OperationalStatusEnum get_evse_persisted_operational_status(int32_t evse_id) = 0;
104
108 virtual OperationalStatusEnum get_connector_persisted_operational_status(int32_t evse_id, int32_t connector_id) = 0;
109
111 virtual void set_cs_individual_operational_status(OperationalStatusEnum new_status, bool persist) = 0;
112
116 virtual void set_evse_individual_operational_status(int32_t evse_id, OperationalStatusEnum new_status,
117 bool persist) = 0;
118
122 virtual void set_connector_individual_operational_status(int32_t evse_id, int32_t connector_id,
123 OperationalStatusEnum new_status, bool persist) = 0;
124
127 virtual OperationalStatusEnum get_evse_effective_operational_status(int32_t evse_id) = 0;
128
131 virtual OperationalStatusEnum get_connector_effective_operational_status(int32_t evse_id, int32_t connector_id) = 0;
132
135 virtual ConnectorStatusEnum get_connector_effective_status(int32_t evse_id, int32_t connector_id) = 0;
136
138 virtual void set_connector_occupied(int32_t evse_id, int32_t connector_id, bool is_occupied) = 0;
139
141 virtual void set_connector_reserved(int32_t evse_id, int32_t connector_id, bool is_reserved) = 0;
142
144 virtual void set_connector_faulted(int32_t evse_id, int32_t connector_id, bool is_faulted) = 0;
145
147 virtual void set_connector_unavailable(int32_t evse_id, int32_t connector_id, bool is_unavailable) = 0;
148
153
157
162
165 virtual void send_status_notification_single_connector(int32_t evse_id, int32_t connector_id) = 0;
166};
167
170private:
171 std::shared_ptr<DatabaseHandler> database;
172
174 OperationalStatusEnum cs_individual_status;
176 std::vector<std::pair<OperationalStatusEnum, std::vector<FullConnectorStatus>>>
177 evse_and_connector_individual_statuses;
178
180 OperationalStatusEnum last_cs_effective_operational_status;
182 std::vector<std::pair<OperationalStatusEnum, std::vector<OperationalStatusEnum>>>
183 last_evse_and_connector_effective_operational_statuses;
184
187 // We need to track this separately because the send_connector_status_notification_callback can fail
188 std::vector<std::vector<ConnectorStatusEnum>> last_connector_reported_statuses;
189
192 std::optional<std::function<void(const OperationalStatusEnum new_status)>>
193 cs_effective_availability_changed_callback = std::nullopt;
194
198 std::optional<std::function<void(const int32_t evse_id, const OperationalStatusEnum new_status)>>
199 evse_effective_availability_changed_callback = std::nullopt;
200
205 std::optional<
206 std::function<void(const int32_t evse_id, const int32_t connector_id, const OperationalStatusEnum new_status)>>
207 connector_effective_availability_changed_callback = std::nullopt;
208
215 std::function<bool(const int32_t evse_id, const int32_t connector_id, const ConnectorStatusEnum new_status,
216 bool initiated_by_trigger_message)>
217 send_connector_status_notification_callback;
218
220 int32_t num_evses();
222 int32_t num_connectors(int32_t evse_id);
223
225 void check_evse_id(int32_t evse_id);
227 void check_evse_and_connector_id(int32_t evse_id, int32_t connector_id);
228
230 OperationalStatusEnum& individual_evse_status(int32_t evse_id);
232 FullConnectorStatus& individual_connector_status(int32_t evse_id, int32_t connector_id);
233
236 OperationalStatusEnum& last_evse_effective_status(int32_t evse_id);
239 OperationalStatusEnum& last_connector_effective_status(int32_t evse_id, int32_t connector_id);
242 ConnectorStatusEnum& last_connector_reported_status(int32_t evse_id, int32_t connector_id);
243
248 void trigger_callbacks_cs(bool only_if_state_changed);
253 void trigger_callbacks_evse(int32_t evse_id, bool only_if_state_changed);
258 void trigger_callbacks_connector(int32_t evse_id, int32_t connector_id, bool only_if_state_changed);
259
264 void send_status_notification_single_connector_internal(int32_t evse_id, int32_t connector_id, bool only_if_changed,
265 bool intiated_by_trigger_message = false);
266
269 void read_all_states_from_database_or_set_defaults(const std::map<int32_t, int32_t>& evse_connector_structure);
270
273 void initialize_reported_state_cache();
274
275public:
288 explicit ComponentStateManager(
289 const std::map<int32_t, int32_t>& evse_connector_structure, std::shared_ptr<DatabaseHandler> db_handler,
290 std::function<bool(const int32_t evse_id, const int32_t connector_id, const ConnectorStatusEnum new_status,
291 const bool initiated_by_trigger_message)>
292 send_connector_status_notification_callback);
293
295 const std::function<void(const OperationalStatusEnum new_status)>& callback);
296
298 const std::function<void(const int32_t evse_id, const OperationalStatusEnum new_status)>& callback);
299
301 const std::function<void(const int32_t evse_id, const int32_t connector_id,
302 const OperationalStatusEnum new_status)>& callback);
303
304 OperationalStatusEnum get_cs_individual_operational_status();
305 OperationalStatusEnum get_evse_individual_operational_status(int32_t evse_id);
306 OperationalStatusEnum get_connector_individual_operational_status(int32_t evse_id, int32_t connector_id);
307
308 OperationalStatusEnum get_cs_persisted_operational_status();
309 OperationalStatusEnum get_evse_persisted_operational_status(int32_t evse_id);
310 OperationalStatusEnum get_connector_persisted_operational_status(int32_t evse_id, int32_t connector_id);
311
312 void set_cs_individual_operational_status(OperationalStatusEnum new_status, bool persist);
313 void set_evse_individual_operational_status(int32_t evse_id, OperationalStatusEnum new_status, bool persist);
314 void set_connector_individual_operational_status(int32_t evse_id, int32_t connector_id,
315 OperationalStatusEnum new_status, bool persist);
316
317 OperationalStatusEnum get_evse_effective_operational_status(int32_t evse_id);
318 OperationalStatusEnum get_connector_effective_operational_status(int32_t evse_id, int32_t connector_id);
319 ConnectorStatusEnum get_connector_effective_status(int32_t evse_id, int32_t connector_id);
320
321 void set_connector_occupied(int32_t evse_id, int32_t connector_id, bool is_occupied);
322 void set_connector_reserved(int32_t evse_id, int32_t connector_id, bool is_reserved);
323 void set_connector_faulted(int32_t evse_id, int32_t connector_id, bool is_faulted);
324 void set_connector_unavailable(int32_t evse_id, int32_t connector_id, bool is_unavailable);
325
327
330 void send_status_notification_single_connector(int32_t evse_id, int32_t connector_id);
331};
332
333} // namespace ocpp::v2
Definition: component_state_manager.hpp:64
virtual OperationalStatusEnum get_connector_persisted_operational_status(int32_t evse_id, int32_t connector_id)=0
Get the individual status (Operative/Inoperative) of a connector, as persisted in the database This s...
virtual OperationalStatusEnum get_evse_persisted_operational_status(int32_t evse_id)=0
Get the individual status (Operative/Inoperative) of an EVSE, as persisted in the database This statu...
virtual OperationalStatusEnum get_evse_individual_operational_status(int32_t evse_id)=0
Get the individual status (Operative/Inoperative) of an EVSE, as set by the CSMS Note: This is not th...
virtual void send_status_notification_single_connector(int32_t evse_id, int32_t connector_id)=0
Call the send_connector_status_notification_callback for a single connector. This is usually done whe...
virtual ConnectorStatusEnum get_connector_effective_status(int32_t evse_id, int32_t connector_id)=0
Get the effective Available/Unavailable/Occupied/Faulted/Reserved status of a connector....
virtual void set_cs_individual_operational_status(OperationalStatusEnum new_status, bool persist)=0
Set the individual status (Operative/Inoperative) of the CS.
virtual void set_connector_faulted(int32_t evse_id, int32_t connector_id, bool is_faulted)=0
Update the state of the connector when errors are raised and cleared.
virtual OperationalStatusEnum get_cs_persisted_operational_status()=0
Get the individual status (Operative/Inoperative) of the CS, as persisted in the database This status...
virtual void set_connector_unavailable(int32_t evse_id, int32_t connector_id, bool is_unavailable)=0
Update the state of the connector when unavailable or enabled.
virtual void set_connector_occupied(int32_t evse_id, int32_t connector_id, bool is_occupied)=0
Update the state of the connector when plugged in or out.
virtual OperationalStatusEnum get_connector_individual_operational_status(int32_t evse_id, int32_t connector_id)=0
Get the individual status (Operative/Inoperative) of a connector, as set by the CSMS Note: This is no...
virtual void set_connector_individual_operational_status(int32_t evse_id, int32_t connector_id, OperationalStatusEnum new_status, bool persist)=0
Set the individual status (Operative/Inoperative) of a connector Note: This is not the same as the ef...
virtual void trigger_all_effective_availability_changed_callbacks()=0
Call the {cs, evse, connector}_effective_availability_changed_callback callback once for every compon...
virtual void set_cs_effective_availability_changed_callback(const std::function< void(const OperationalStatusEnum new_status)> &callback)=0
Set a callback to be called when the effective Operative/Inoperative state of the CS changes.
virtual void send_status_notification_all_connectors()=0
Call the send_connector_status_notification_callback once for every connector. This is usually done o...
virtual void set_evse_individual_operational_status(int32_t evse_id, OperationalStatusEnum new_status, bool persist)=0
Set the individual status (Operative/Inoperative) of an EVSE Note: This is not the same as the effect...
virtual void set_connector_effective_availability_changed_callback(const std::function< void(const int32_t evse_id, const int32_t connector_id, const OperationalStatusEnum new_status)> &callback)=0
Set a callback to be called when the effective Operative/Inoperative state of a connector changes.
virtual OperationalStatusEnum get_cs_individual_operational_status()=0
Get the individual status (Operative/Inoperative) of the CS, as set by the CSMS.
virtual void set_evse_effective_availability_changed_callback(const std::function< void(const int32_t evse_id, const OperationalStatusEnum new_status)> &callback)=0
Set a callback to be called when the effective Operative/Inoperative state of an EVSE changes.
virtual void set_connector_reserved(int32_t evse_id, int32_t connector_id, bool is_reserved)=0
Update the state of the connector when reservations are made or expire.
virtual void send_status_notification_changed_connectors()=0
Call the send_connector_status_notification_callback once for every connector whose state has changed...
virtual OperationalStatusEnum get_connector_effective_operational_status(int32_t evse_id, int32_t connector_id)=0
Get the effective Operative/Inoperative status of a connector. This is computed from the connector's,...
virtual OperationalStatusEnum get_evse_effective_operational_status(int32_t evse_id)=0
Get the effective Operative/Inoperative status of an EVSE This is computed from the EVSE's and the CS...
Stores and monitors operational/effective states of the CS, EVSEs, and connectors.
Definition: component_state_manager.hpp:169
OperationalStatusEnum get_connector_effective_operational_status(int32_t evse_id, int32_t connector_id)
Get the effective Operative/Inoperative status of a connector. This is computed from the connector's,...
Definition: component_state_manager.cpp:263
OperationalStatusEnum get_evse_individual_operational_status(int32_t evse_id)
Get the individual status (Operative/Inoperative) of an EVSE, as set by the CSMS Note: This is not th...
Definition: component_state_manager.cpp:184
ComponentStateManager(const std::map< int32_t, int32_t > &evse_connector_structure, std::shared_ptr< DatabaseHandler > db_handler, std::function< bool(const int32_t evse_id, const int32_t connector_id, const ConnectorStatusEnum new_status, const bool initiated_by_trigger_message)> send_connector_status_notification_callback)
At construction time, the state of each component (CS, EVSEs, and connectors) is retrieved from the d...
Definition: component_state_manager.cpp:66
void set_connector_faulted(int32_t evse_id, int32_t connector_id, bool is_faulted)
Update the state of the connector when errors are raised and cleared.
Definition: component_state_manager.cpp:298
void set_connector_reserved(int32_t evse_id, int32_t connector_id, bool is_reserved)
Update the state of the connector when reservations are made or expire.
Definition: component_state_manager.cpp:294
void set_evse_effective_availability_changed_callback(const std::function< void(const int32_t evse_id, const OperationalStatusEnum new_status)> &callback)
Set a callback to be called when the effective Operative/Inoperative state of an EVSE changes.
Definition: component_state_manager.cpp:170
void send_status_notification_changed_connectors()
Call the send_connector_status_notification_callback once for every connector whose state has changed...
Definition: component_state_manager.cpp:333
OperationalStatusEnum get_evse_effective_operational_status(int32_t evse_id)
Get the effective Operative/Inoperative status of an EVSE This is computed from the EVSE's and the CS...
Definition: component_state_manager.cpp:248
ConnectorStatusEnum get_connector_effective_status(int32_t evse_id, int32_t connector_id)
Get the effective Available/Unavailable/Occupied/Faulted/Reserved status of a connector....
Definition: component_state_manager.cpp:255
OperationalStatusEnum get_evse_persisted_operational_status(int32_t evse_id)
Get the individual status (Operative/Inoperative) of an EVSE, as persisted in the database This statu...
Definition: component_state_manager.cpp:274
OperationalStatusEnum get_cs_persisted_operational_status()
Get the individual status (Operative/Inoperative) of the CS, as persisted in the database This status...
Definition: component_state_manager.cpp:271
void set_cs_effective_availability_changed_callback(const std::function< void(const OperationalStatusEnum new_status)> &callback)
Set a callback to be called when the effective Operative/Inoperative state of the CS changes.
Definition: component_state_manager.cpp:165
void set_connector_individual_operational_status(int32_t evse_id, int32_t connector_id, OperationalStatusEnum new_status, bool persist)
Set the individual status (Operative/Inoperative) of a connector Note: This is not the same as the ef...
Definition: component_state_manager.cpp:216
void send_status_notification_all_connectors()
Call the send_connector_status_notification_callback once for every connector. This is usually done o...
Definition: component_state_manager.cpp:326
void trigger_all_effective_availability_changed_callbacks()
Call the {cs, evse, connector}_effective_availability_changed_callback callback once for every compon...
Definition: component_state_manager.cpp:308
void set_connector_effective_availability_changed_callback(const std::function< void(const int32_t evse_id, const int32_t connector_id, const OperationalStatusEnum new_status)> &callback)
Set a callback to be called when the effective Operative/Inoperative state of a connector changes.
Definition: component_state_manager.cpp:175
void set_connector_unavailable(int32_t evse_id, int32_t connector_id, bool is_unavailable)
Update the state of the connector when unavailable or enabled.
Definition: component_state_manager.cpp:303
void set_connector_occupied(int32_t evse_id, int32_t connector_id, bool is_occupied)
Update the state of the connector when plugged in or out.
Definition: component_state_manager.cpp:284
OperationalStatusEnum get_connector_persisted_operational_status(int32_t evse_id, int32_t connector_id)
Get the individual status (Operative/Inoperative) of a connector, as persisted in the database This s...
Definition: component_state_manager.cpp:278
OperationalStatusEnum get_cs_individual_operational_status()
Get the individual status (Operative/Inoperative) of the CS, as set by the CSMS.
Definition: component_state_manager.cpp:181
void set_cs_individual_operational_status(OperationalStatusEnum new_status, bool persist)
Set the individual status (Operative/Inoperative) of the CS.
Definition: component_state_manager.cpp:192
void send_status_notification_single_connector(int32_t evse_id, int32_t connector_id)
Call the send_connector_status_notification_callback for a single connector. This is usually done whe...
Definition: component_state_manager.cpp:340
void set_evse_individual_operational_status(int32_t evse_id, OperationalStatusEnum new_status, bool persist)
Set the individual status (Operative/Inoperative) of an EVSE Note: This is not the same as the effect...
Definition: component_state_manager.cpp:203
OperationalStatusEnum get_connector_individual_operational_status(int32_t evse_id, int32_t connector_id)
Get the individual status (Operative/Inoperative) of a connector, as set by the CSMS Note: This is no...
Definition: component_state_manager.cpp:187
Exception used when an connector_id that does not exist is accessed.
Definition: component_state_manager.hpp:28
Exception used when an evse that does not exist is accessed.
Definition: component_state_manager.hpp:12
Describes the individual state of a single connector.
Definition: component_state_manager.hpp:46
bool occupied
True if the connector has a cable plugged in, assumed false on boot.
Definition: component_state_manager.hpp:54
bool faulted
True if the connector has an active (uncleared) error, assumed false on boot.
Definition: component_state_manager.hpp:50
ConnectorStatusEnum to_connector_status()
Translates the individual state to an Available/Unavailable/Occupied/Reserved/Faulted state This does...
Definition: component_state_manager.cpp:231
OperationalStatusEnum individual_operational_status
Operative/Inoperative status, usually set by the CSMS.
Definition: component_state_manager.hpp:48
bool reserved
True if the connector has an active reservation, assumed false on boot.
Definition: component_state_manager.hpp:52
bool unavailable
True if the connector is explicitly set to unavailable.
Definition: component_state_manager.hpp:56