Giter Site home page Giter Site logo

codelabsab / rust-ocpp Goto Github PK

View Code? Open in Web Editor NEW
63.0 7.0 12.0 4.84 MB

Libraries for ocpp 1.6 and 2.0.1

Home Page: https://docs.rs/rust-ocpp/latest/rust_ocpp/

License: Apache License 2.0

Rust 100.00%
ev charging ocpp201 ocpp16j ocpp ocpp-j rust

rust-ocpp's Introduction

rust-ocpp

crates.io workflow codecov

The rust-ocpp libs implements the Open Charge Point Protocol used in charging stations. You can read more on the official Open Charge Alliance website.

Both OCPP v1.6 and v2.0.1 are implemented and validated using the official json schemas from Open Charge Alliance.

You can find the tests in schema_validation.rs for both v.1.6 and v2.0.1

repo structure

src/ : library files for v1.6 and v2.0.1

docs/ : official ocpp specification

How to Use

Add rust-ocpp as a dependency in your Cargo.toml. It will default to version 2.0.1

[dependencies]
rust-ocpp = "0.3.1"

To use 1.6 you need to specify a protocol version with a feature flag:

[dependencies]
rust-ocpp = { version = "0.3.1", features = ["v1_6"] }

or use both versions

[dependencies]
rust-ocpp = { version = "0.3.1", features = ["v2_0_1", "v1_6"] }

How to Build

To build the rust-ocpp library, you need to have Rust and Cargo installed on your system. You can install them by following the instructions provided at the official Rust website.

Once you have Rust and Cargo installed, you can build the library using the following steps:

  1. Clone the rust-ocpp repository:

    git clone https://github.com/codelabsab/rust-ocpp.git
  2. Change into the rust-ocpp directory:

    cd rust-ocpp
  3. Build the library using Cargo for both 1.6 and 2.0.1:

    cargo build --all-features

    This command will compile the library and its dependencies. If the build is successful, you will find the compiled artifacts in the target/debug directory.

  4. Run the tests on both versions:

    cargo test --all-features
    

    This command will execute the tests for both OCPP versions. If all tests pass, it means that the library is functioning correctly.

  5. Build a specific version:

    To build a specific version of rust-ocpp, you can use the appropriate feature flag when running the build command. For example, to build v1_6:

    cargo build --features v1_6

    To build v2_0_1:

    cargo build --features v2_0_1
  6. (Optional) Build for release:

    If you want to build the library for release, with optimizations enabled, you can use the following command:

    cargo build --features v2_0_1 --release

    The release build will produce optimized artifacts in the target/release directory.

  7. (Optional) Install the library:

    If you want to install the library globally on your system, you can use the following command:

    cargo install --path .

    This command will compile the library and its dependencies and install it in the Cargo binary directory, so you can use it as a dependency in other projects.

That's it! You have successfully built the rust-ocpp library. If you encounter any issues during the build process, please check the project's issue tracker on GitHub or open a new issue for assistance.

Testing

rust-ocpp provides testing against json schemas for both OCPP v1.6 and v2.0.1 versions. To run the tests, you can use Cargo's built-in test runner.

Running Tests

To run the tests for a specific version, use the appropriate feature flag when running the tests.

For OCPP v1.6 tests:

cargo test --features v1_6

For OCPP v2.0.1 tests:

cargo test --features v2_0_1

To run all tests:

cargo test

or for a specific version

cargo test --features v1_6

Test Coverage

The test coverage for rust-ocpp is measured using Codecov. You can find the current test coverage report on codecov.

Contributing to Tests

Contributions to the test suite are very much appreciated. If you encounter any bugs, discover edge cases, or have ideas for additional test cases, feel free to open an issue or submit a pull request. We will be happy to review and incorporate your contributions.

Please ensure that you run the tests and maintain or improve the overall test coverage before submitting any changes. Additionally, adhere to the existing testing conventions and follow the code style guidelines to maintain consistency.

Contribute

Use rustfmt before you PR.

pre-commit config is available. You can read more about it at pre-commits website and checkout their repo on github

rust-ocpp's People

Contributors

baztar avatar dependabot[bot] avatar elwerene avatar erk- avatar larsk2009 avatar parberge avatar tommymalmqvist avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-ocpp's Issues

Consider putting 1.6 and 2.0 support behind feature flags

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?

OCPP1.6: size of integer for transaction_id

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.

Real app examples using the lib

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

Add support for types declared in OCPP JSON Specification (RPC Framework)

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:

  1. Call
  2. CallResult
  3. CallError

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.

Adding #[serde(deny_unknown_fields, rename_all = "camelCase")]

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:

  • replace #[serde(rename_all = "camelCase")]
  • with #[serde(deny_unknown_fields, rename_all = "camelCase")]

Web socket

It's just a great codebase that I'm looking into, and I'm also trying to contribute to it."

Few questions:

  1. 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.

  2. If someone needs to implement the core OCPP WebSocket functionality in Rust, could you suggest some resources?

Derive default

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.

Question on authoring approach

Thanks for this library!

Just curious as to how you went about authoring these types initially- from OCPP provided json schema, or manually? Thanks.

OCPP1.6 Missing Option for timestamp in StatusNotificationRequest

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.