Skip to content

Commit 51287f6

Browse files
ssekar15SanjayyyV
andcommitted
net: ocpp: Add a support for Open Charge Point Protocol(OCPP v1.6) stack
Basic support for open charge point protocol v1.6 as native stack with below functionality 1. Framework for ocpp stack and central system communication using RPC over websocket according to occp-j. 2. Core profile with basic PDU Signed-off-by: Saravanan Sekar <[email protected]> Co-authored-by: Sanjay Vallimanalan <[email protected]>
1 parent 322da1d commit 51287f6

File tree

12 files changed

+3113
-0
lines changed

12 files changed

+3113
-0
lines changed

include/zephyr/net/ocpp.h

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/*
2+
* Copyright (c) 2024 Linumiz
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/**
8+
* @file ocpp.h
9+
*
10+
* @defgroup ocpp_api OCPP library
11+
* @since 4.3
12+
* @version 0.1.0
13+
* @ingroup networking
14+
* @{
15+
* @brief OCPP Charge Point Implementation
16+
*
17+
* @note The implementation assumes Websocket module is enabled.
18+
*
19+
* @note By default the implementation uses OCPP version 1.6.
20+
*/
21+
22+
#ifndef ZEPHYR_INCLUDE_NET_OCPP_H_
23+
#define ZEPHYR_INCLUDE_NET_OCPP_H_
24+
25+
#include <stdio.h>
26+
#include <zephyr/kernel.h>
27+
#include <zephyr/net/net_ip.h>
28+
29+
#ifdef __cplusplus
30+
extern "C" {
31+
#endif
32+
33+
/** Max length of string literals e.g idtag */
34+
#define CISTR50 50
35+
36+
/**
37+
* @brief OCPP IdTag authorization status in result to ocpp request
38+
* authorization
39+
*/
40+
enum ocpp_auth_status {
41+
OCPP_AUTH_INVALID, /*< IdTag not valid */
42+
OCPP_AUTH_ACCEPTED, /*< accepted, allowed to charge */
43+
OCPP_AUTH_BLOCKED, /*< blocked to charge */
44+
OCPP_AUTH_EXPIRED, /*< IdTag expired, not allowed to charge */
45+
OCPP_AUTH_CONCURRENT_TX /*< Parallel access of same IdTag */
46+
};
47+
48+
enum ocpp_notify_reason {
49+
/** User must fill the current reading */
50+
OCPP_USR_GET_METER_VALUE,
51+
52+
/** Process the start charging request as like idtag received from local
53+
* e.g authorize etc
54+
*/
55+
OCPP_USR_START_CHARGING,
56+
57+
/** Process the stop charging sequence */
58+
OCPP_USR_STOP_CHARGING,
59+
60+
/** Unlock mechanical connector of CP */
61+
OCPP_USR_UNLOCK_CONNECTOR,
62+
};
63+
64+
/** @brief OCPP meter readings to be filled on user callback request from
65+
* library
66+
*/
67+
enum ocpp_meter_measurand {
68+
OCPP_OMM_CURRENT_FROM_EV, /*< current from EV, in A */
69+
OCPP_OMM_CURRENT_TO_EV, /*< current to EV, in A */
70+
OCPP_OMM_CURRENT_MAX_OFFERED_TO_EV, /*< maximum current offered to EV, in A */
71+
OCPP_OMM_ACTIVE_ENERGY_FROM_EV, /*< active energy from EV, in Wh */
72+
OCPP_OMM_ACTIVE_ENERGY_TO_EV, /*< active energy to EV, in Wh */
73+
OCPP_OMM_REACTIVE_ENERGY_FROM_EV, /*< reactive energy from EV, in varh */
74+
OCPP_OMM_REACTIVE_ENERGY_TO_EV, /*< reactive energy to EV, in varh */
75+
OCPP_OMM_ACTIVE_POWER_FROM_EV, /*< active power from EV, in W */
76+
OCPP_OMM_ACTIVE_POWER_TO_EV, /*< active power to EV, in W */
77+
OCPP_OMM_REACTIVE_POWER_FROM_EV, /*< reactive power from EV, in var */
78+
OCPP_OMM_REACTIVE_POWER_TO_EV, /*< reactive power to EV, in var */
79+
OCPP_OMM_POWERLINE_FREQ, /*< powerline frequency, in Hz */
80+
OCPP_OMM_POWER_FACTOR, /*< power factor of supply */
81+
OCPP_OMM_POWER_MAX_OFFERED_TO_EV, /*< maximum power offered to EV, in W */
82+
OCPP_OMM_FAN_SPEED, /*< fan speed, in rpm */
83+
OCPP_OMM_CHARGING_PERCENT, /*< charging percentage */
84+
OCPP_OMM_TEMPERATURE, /*< temperature inside charge point, in Celsius */
85+
OCPP_OMM_VOLTAGE_AC_RMS, /*< AC RMS supply voltage, in V */
86+
87+
OCPP_OMM_END
88+
};
89+
90+
/** @brief OCPP user callback notification/request of input/output values
91+
* union member should be accessed with enum value ocpp_notify_reason
92+
* correspondingly.
93+
* e.g. callback reason is OCPP_USR_GET_METER_VALUE, struct meter_val
94+
* is valid
95+
*/
96+
union ocpp_io_value {
97+
98+
struct {
99+
/** Input to user, requested connector_id or 0 - main meter */
100+
int id_con;
101+
102+
/** Input to user, measurand */
103+
enum ocpp_meter_measurand mes;
104+
105+
/** To be filled by user, value as string */
106+
char val[CISTR50];
107+
} meter_val;
108+
109+
struct {
110+
char idtag[CISTR50]; /**< Input to user */
111+
112+
/** Input to user(optional). connector id -1 means invalid */
113+
int id_con;
114+
} start_charge;
115+
116+
struct {
117+
int id_con; /**< Input to user, to stop charging connector */
118+
} stop_charge;
119+
120+
struct {
121+
int id_con; /**< Input to user, to unlock connector id. */
122+
} unlock_con;
123+
};
124+
125+
/** @brief Parameters for ocpp_init information about Charge Point (CP)
126+
* all are string literal except num_of_con
127+
*/
128+
struct ocpp_cp_info {
129+
char *model; /**< Charge Point (CP) model */
130+
char *vendor; /**< CP vendor */
131+
132+
int num_of_con; /**< Max. number of connector supports */
133+
134+
/** optional fields */
135+
char *sl_no; /**< CP serial number */
136+
char *box_sl_no; /**< Box serial number */
137+
char *fw_ver; /**< Firmware version */
138+
char *iccid; /**< ICC ID */
139+
char *imsi; /**< IMSI */
140+
char *meter_sl_no; /**< Main power meter serial number */
141+
char *meter_type; /**< Main power meter type */
142+
};
143+
144+
/** @brief Parameters for ocpp_init information about central system (CS) */
145+
struct ocpp_cs_info {
146+
char *cs_ip; /**< Central system IP address */
147+
char *ws_url; /**< Websocket url exclude ipaddr & port */
148+
int port; /**< Central system port number */
149+
sa_family_t sa_family; /**< IP protocol family type 4/6 */
150+
};
151+
152+
/** @brief Parameters opaque session handle for ocpp_* API */
153+
typedef void *ocpp_session_handle_t;
154+
155+
/**
156+
* @brief Asynchronous event notification callback registered by the
157+
* application. advised callback should not be hold for longer time
158+
* to unblock the ocpp protocol stack/lib.
159+
*
160+
* @param[in] reason for callback invoked.
161+
* @param[in] io reffered corresponding to reason.
162+
* @param[in] user_data passed on ocpp_init.
163+
*
164+
* @return 0 or a negative error code (errno.h)
165+
*/
166+
typedef int (*ocpp_user_notify_callback_t)(enum ocpp_notify_reason reason,
167+
union ocpp_io_value *io,
168+
void *user_data);
169+
170+
/**
171+
* @brief OCPP library init.
172+
*
173+
* @param[in] cpi Charge Point information
174+
* @param[in] csi Central System information
175+
* @param[in] cb user register callback
176+
* @param[in] user_data same reference will be passed on callback
177+
*
178+
* @return 0 on success or a negative error code (errno.h) indicating reason of failure
179+
*
180+
* @note Must be called before any other ocpp API
181+
*/
182+
int ocpp_init(struct ocpp_cp_info *cpi,
183+
struct ocpp_cs_info *csi,
184+
ocpp_user_notify_callback_t cb,
185+
void *user_data);
186+
187+
/**
188+
* @brief API to request a new Session
189+
*
190+
* @param[out] hndl a valid opaque handle
191+
*
192+
* @return 0 on success or a negative error code (errno.h) indicating reason of failure
193+
*
194+
* @note Each connector should open unique session after ocpp_init and
195+
* prior to anyother ocpp_* request message api
196+
*/
197+
int ocpp_session_open(ocpp_session_handle_t *hndl);
198+
199+
/**
200+
* @brief API to close a Session
201+
*
202+
* @param[in] hndl a handle received from session open
203+
*/
204+
void ocpp_session_close(ocpp_session_handle_t hndl);
205+
206+
/**
207+
* @brief Authorize request call to CS to get validity of idtag
208+
*
209+
* @param[in] hndl session handle
210+
* @param[in] idtag (string literal) to get authorize validity
211+
* @param[out] status authorization status
212+
* @param[in] timeout_ms in msec
213+
*
214+
* @return 0 on success or a negative error code (errno.h) indicating reason of failure
215+
*/
216+
int ocpp_authorize(ocpp_session_handle_t hndl,
217+
char *idtag,
218+
enum ocpp_auth_status *status,
219+
uint32_t timeout_ms);
220+
221+
/**
222+
* @brief Notify transaction start to CS
223+
*
224+
* @param[in] hndl session handle
225+
* @param[in] Wh energy meter reading of this connector
226+
* @param[in] conn_id connector id should be > 0 and sequential number
227+
* @param[in] timeout_ms timeout in msec
228+
*
229+
* @return: 0 on success
230+
* EACCES - not authorized, should follow the stop charging process
231+
* a negative error code (errno.h) indicating reason of failure
232+
*/
233+
int ocpp_start_transaction(ocpp_session_handle_t hndl,
234+
int Wh,
235+
uint8_t conn_id,
236+
uint32_t timeout_ms);
237+
238+
/**
239+
* @brief Notify transaction stopped to CS
240+
*
241+
* @param[in] hndl session handle
242+
* @param[in] Wh energy meter reading of this connector
243+
* @param[in] timeout_ms timeout in msec
244+
*
245+
* @return 0 on success or a negative error code (errno.h) indicating reason of failure
246+
*/
247+
int ocpp_stop_transaction(ocpp_session_handle_t hndl,
248+
int Wh,
249+
uint32_t timeout_ms);
250+
251+
#ifdef __cplusplus
252+
}
253+
#endif
254+
255+
#endif /* ZEPHYR_INCLUDE_NET_OCPP_H_ */
256+
257+
/**@} */

subsys/net/lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ add_subdirectory_ifdef(CONFIG_NET_TRICKLE trickle)
1919
add_subdirectory_ifdef(CONFIG_NET_DHCPV6 dhcpv6)
2020
add_subdirectory_ifdef(CONFIG_PROMETHEUS prometheus)
2121
add_subdirectory_ifdef(CONFIG_WIFI_CREDENTIALS wifi_credentials)
22+
add_subdirectory_ifdef(CONFIG_OCPP ocpp)
2223

2324
if (CONFIG_NET_DHCPV4 OR CONFIG_NET_DHCPV4_SERVER)
2425
add_subdirectory(dhcpv4)

subsys/net/lib/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ source "subsys/net/lib/socks/Kconfig"
2525

2626
source "subsys/net/lib/sntp/Kconfig"
2727

28+
source "subsys/net/lib/ocpp/Kconfig"
29+
2830
endmenu
2931

3032
menu "Network Libraries"

subsys/net/lib/ocpp/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
zephyr_library()
4+
5+
zephyr_library_sources(
6+
ocpp.c
7+
core.c
8+
key_mgmt.c
9+
ocpp_j.c
10+
ocpp_wamp_rpc.c
11+
)

subsys/net/lib/ocpp/Kconfig

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Copyright (c) 2025 Linumiz GmbH
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config OCPP
5+
bool "Open Charge Point Protocol [EXPERIMENTAL]"
6+
depends on JSON_LIBRARY
7+
depends on WEBSOCKET_CLIENT
8+
select EXPERIMENTAL
9+
help
10+
This option enables the open charge point protocol library
11+
12+
if OCPP
13+
14+
module=OCPP
15+
module-dep=NET_LOG
16+
module-str=Log level for OCPP
17+
module-help=Enables ocpp debug messages.
18+
source "subsys/net/Kconfig.template.log_config.net"
19+
20+
config OCPP_INT_THREAD_STACKSIZE
21+
int "OCPP internal thread stacksize"
22+
default 4096
23+
help
24+
OCPP internal thread stacksize
25+
26+
config OCPP_WSREADER_THREAD_STACKSIZE
27+
int "OCPP websocket reader thread stacksize"
28+
default 4096
29+
help
30+
OCPP websocket reader thread stacksize
31+
32+
config OCPP_RECV_BUFFER_SIZE
33+
int "OCPP websocket recive buffer size"
34+
default 2048
35+
help
36+
OCPP websocket recive buffer size
37+
38+
config OCPP_INTERNAL_MSGQ_CNT
39+
int "OCPP internal message queue count"
40+
default 10
41+
help
42+
Messages communication between websocket reader and internal
43+
process thread
44+
45+
config OCPP_MSG_JSON
46+
bool "PDU message format as JSON"
47+
default y
48+
help
49+
If enabled y, then the Charge Point and Central System PDU message
50+
format as JSON
51+
52+
config OCPP_PROFILE_SMART_CHARGE
53+
bool "OCPP profile smart charging"
54+
help
55+
Enables the OCPP library to support the Smart Charging profile
56+
functionality. Charge Point may support this profile as optional.
57+
58+
config OCPP_PROFILE_REMOTE_TRIG
59+
bool "OCPP profile remote trigger"
60+
help
61+
Enables the OCPP library to support the Remote Trigger
62+
functionality. Charge Point may support this profile as optional.
63+
64+
config OCPP_PROFILE_RESERVATION
65+
bool "OCPP profile reservation"
66+
help
67+
Enables the OCPP library to support the Profile Reservation
68+
functionality. Charge Point may support this profile as optional.
69+
70+
config OCPP_PROFILE_LOCAL_AUTH_LIST
71+
bool "OCPP profile local authorization list"
72+
help
73+
Enables the OCPP library to support the Local Authorization List
74+
functionality. Stores IdTag and its validity information in the
75+
persistent stroage. Charge Point may support this as optional.
76+
77+
config OCPP_PROFILE_FIRMWARE_MGNT
78+
bool "OCPP profile firmware management"
79+
help
80+
Enables the OCPP library to support the Firmware Management of
81+
Charge Point as optional profile.
82+
83+
endif # OCPP

0 commit comments

Comments
 (0)