#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum NegotiatedVersion {
Ocpp201,
Ocpp21,
}
impl NegotiatedVersion {
#[must_use]
pub fn from_subprotocol(proto: &str) -> Option<Self> {
match proto {
"ocpp2.0.1" => Some(Self::Ocpp201),
"ocpp2.1" => Some(Self::Ocpp21),
_ => None,
}
}
#[must_use]
pub const fn as_subprotocol(self) -> &'static str {
match self {
Self::Ocpp201 => "ocpp2.0.1",
Self::Ocpp21 => "ocpp2.1",
}
}
}
pub const OCPP21_ONLY_ACTIONS: &[&str] = &[
"AFRRSignal",
"AdjustPeriodicEventStream",
"BatterySwap",
"ChangeTransactionTariff",
"ClearDERControl",
"ClearTariffs",
"ClosePeriodicEventStream",
"GetDERControl",
"GetPeriodicEventStream",
"GetTariffs",
"NotifyAllowedEnergyTransfer",
"NotifyDERAlarm",
"NotifyDERStartStop",
"NotifyPeriodicEventStream",
"NotifyPriorityCharging",
"NotifySettlement",
"NotifyWebPaymentStarted",
"OpenPeriodicEventStream",
"PullDynamicScheduleUpdate",
"ReportDERControl",
"RequestBatterySwap",
"SetDERControl",
"SetDefaultTariff",
"UpdateDynamicSchedule",
"UsePriorityCharging",
"VatNumberValidation",
];
#[must_use]
pub fn is_ocpp21_only_action(action: &str) -> bool {
OCPP21_ONLY_ACTIONS.contains(&action)
}
#[must_use]
pub const fn allows_message_type(version: NegotiatedVersion, type_id: u8) -> bool {
match type_id {
2..=4 => true,
5 | 6 => matches!(version, NegotiatedVersion::Ocpp21),
_ => false,
}
}
#[must_use]
pub fn allows_action(version: NegotiatedVersion, action: &str) -> bool {
match version {
NegotiatedVersion::Ocpp21 => true,
NegotiatedVersion::Ocpp201 => !is_ocpp21_only_action(action),
}
}