codelabsab / rust-ocpp Goto Github PK
View Code? Open in Web Editor NEWLibraries for ocpp 1.6 and 2.0.1
Home Page: https://docs.rs/rust-ocpp/latest/rust_ocpp/
License: Apache License 2.0
Libraries for ocpp 1.6 and 2.0.1
Home Page: https://docs.rs/rust-ocpp/latest/rust_ocpp/
License: Apache License 2.0
Hello.
I would like to request about info of where I can find some real projects using this Rust library, or if you have one (like a server for management) to find an example.
Thanks in advice
First, thanks for providing this crate with all of the various types handled quite nicely. This has allowed me to rapidly prototype clients and servers in Rust.
Both 1.6 and 2.0.1 include an additional sheet where the RPC Framework is defined, and in each spec there are three message types into which all of the various structs and enums already created fit:
While I have implemented these myself to allow for processing of received JSON messages into an enum from which I can use match semantics, I can't help but think there's room for these convenience types within this project directly.
Example follows:
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Deserialize, Serialize, Debug)]
enum Action {
Heartbeat,
// Fill this with all possible Action values for a Call
}
#[derive(Deserialize, Serialize, Debug)]
enum ErrorCode {
NotImplemented,
NotSupported,
InternalError,
ProtocolError,
SecurityError,
FormationViolation,
PropertyConstraintViolation,
OccurenceConstraintViolation,
TypeConstraintViolation,
GenericError,
}
#[derive(Deserialize, Serialize, Debug)]
struct CallData {
msg_type_id: u8,
unique_id: String,
action: Action,
payload: Value,
}
#[derive(Deserialize, Serialize, Debug)]
struct CallResultData {
msg_type_id: u8,
unique_id: String,
payload: Value,
}
#[derive(Deserialize, Serialize, Debug)]
struct CallErrorData {
msg_type_id: u8,
unique_id: String,
error_code: ErrorCode,
error_description: String,
error_details: Value,
}
#[derive(Deserialize, Serialize, Debug)]
#[serde(untagged)]
enum OcppMessage {
Call(CallData),
CallResult(CallResultData),
CallError(CallErrorData),
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let call = r#"[2, "123456", "Heartbeat", {}]"#;
let call_result = r#"[3, "123456", {"currentTime": "2023-04-05T17:20:00.000Z"}]"#;
let call_error = r#"[4, "987654", "NotImplemented", "", {}]"#;
let c: OcppMessage = serde_json::from_str(call)?;
let d: OcppMessage = serde_json::from_str(call_result)?;
let e: OcppMessage = serde_json::from_str(call_error)?;
println!("{c:?}");
// Call(CallData { msg_type_id: 2, unique_id: "123456", action: Heartbeat, payload: Object {} })
println!("{d:?}");
// CallResult(CallResultData { msg_type_id: 3, unique_id: "123456", payload: Object {"currentTime": String("2023-04-05T17:20:00.000Z")} })
println!("{e:?}");
// CallError(CallErrorData { msg_type_id: 4, unique_id: "987654", error_code: NotImplemented, error_description: "", error_details: Object {} })
Ok(())
}
If this is something the project would be interested in including, I'm happy to help. For my uses, I will be implementing TryFrom for various messages to handle the conversion of the Value
fields into the types this crate already provides.
I'm on version 0.4.1 and 0.4.4 is available, but I have yet to find what the differences are between the versions. Having a changelog would be wonderful to get a quick idea of what to expect, and git tags would allow me to dive into detail on differences.
Thanks!
Thanks for this library!
Just curious as to how you went about authoring these types initially- from OCPP provided json schema, or manually? Thanks.
Without deny_unknown_fields, Serde may matched any message to '{}'. Getting a stricter control is especially important for transaction that send '{}' as response (i.e. StatusNotification). As a result with enforcing 'deny_unknown_fields' Serde may match to {} any backend error message.
Proposal in all message definition:
Would you be interested in adding a default
derive trait? I think this can be useful for testing purposes so you quickly create one of the types without having to specify all of the optional types.
If you'd agree with adding this, I can make a PR for it.
It's just a great codebase that I'm looking into, and I'm also trying to contribute to it."
Few questions:
It seems that the WebSocket part of OCPP is not included in this project, so it may focus solely on CPMS (Charge Point Management System) functionality.
If someone needs to implement the core OCPP WebSocket functionality in Rust, could you suggest some resources?
I'm playing around a bit, but my solitary charge point only supports 1.6 so all the references to 2.0 stuff in the docs and rust-analyzer autocomplete are basically just noise to me.
Would you accept a PR putting each module behind a feature flag?
The github action we use for publishing (katyo/publish-creates
) will check if we have changes in git repo in relation to the current release of the library on crates.io. Since we will do changes to things inside the repo that doesn't have to be part of a crate release I think we should turn this check off. If I understand correctly we can turn it off by setting check-repo: false
as input.
See https://github.com/katyo/publish-crates?tab=readme-ov-file#inputs
Thank you very much for this library. While using it, I found some poles implementing OCPP 1.6 that expect 32bits integer for transaction_id instead of 64bits as it is specified in the messages here. Reading the OCPP standard, I could not find any place where the size of integers is defined (they just specify integer
both in the documentation and in the json validation files).
Do you have more information about what OCPP specifies here?
I'd be happy to provide a PR if you want to switch to i32; on the other hand, 32bit is not a lot of entropy for a distributed system and I'd have preferred to use at least 64 bits, so I understand if you're happy to leave things as they are.
Hi Code Labs,
For OCPP1.6, I think there is a minor error in StatusNotificationRequest.
According to the document the timestamp field for StatusNotificationRequest should be an optional field.
pub struct StatusNotificationRequest {
pub connector_id: u64,
pub error_code: ChargePointErrorCode,
pub info: Option<String>,
pub status: ChargePointStatus,
pub timestamp: DateTime<Utc>, <-- Option<DateTime<Utc>> I think
pub vendor_id: Option<String>,
pub vendor_error_code: Option<String>,
}
I am still beginner in both rust and ev field, so I am sorry if this is my misunderstanding.
Thanks.
This action is unmaintained (https://github.com/actions-rs). Apparently there are discussions here about alternatives. We should find one and use that instead
It's not actually used within the crate, but the value of rust_ocpp::v1_6::messages::change_configuration::LOCAL_AUTH_LIST_MAX_LENGTH
is incorrect; right now it's "LocalAuthListEnabled"
, probably copied and pasted from LOCAL_AUTH_LIST_ENABLED
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.