|
| 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 timeout 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] meter_val energy meter reading of this connector in Wh |
| 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 meter_val, |
| 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] meter_val energy meter reading of this connector in Wh |
| 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 meter_val, |
| 249 | + uint32_t timeout_ms); |
| 250 | + |
| 251 | +#ifdef __cplusplus |
| 252 | +} |
| 253 | +#endif |
| 254 | + |
| 255 | +#endif /* ZEPHYR_INCLUDE_NET_OCPP_H_ */ |
| 256 | + |
| 257 | +/**@} */ |
0 commit comments