use std::time::Duration;
use serde_json::{Value, json};
use tokio::sync::mpsc;
use super::{
ConnectorStatus, OcppVersion, PendingCall, PendingContext, ResponseStatus,
Simulator, SimulatorConfig, TxEventType, UiEvent, UiLogLevel, now_timestamp,
validate_negotiated_subprotocol,
};
mod charging_profiles;
mod configuration;
mod schema_validation;
mod state;
mod transactions;
mod ws_lifecycle;
fn simulator_test_config(protocol: OcppVersion) -> SimulatorConfig {
SimulatorConfig {
ws_url: "ws://localhost:9000/ocpp".to_string(),
cp_id: "CP-TEST".to_string(),
protocol,
connectors: 2,
vendor: "ocppsim".to_string(),
model: "test".to_string(),
firmware: "0.0.0".to_string(),
append_cp_id: false,
trace_frames: false,
strict: false,
request_timeout: Duration::from_secs(30),
heartbeat_seconds: Some(10),
}
}
fn simulator_for_tests_with_protocol(protocol: OcppVersion) -> Simulator {
let (simulator, _ui_rx) = simulator_for_tests_with_protocol_and_ui(protocol);
simulator
}
fn simulator_for_tests_with_protocol_and_ui(
protocol: OcppVersion,
) -> (Simulator, mpsc::UnboundedReceiver<UiEvent>) {
let config = simulator_test_config(protocol);
let (ui_tx, ui_rx) = mpsc::unbounded_channel();
let (cmd_tx, _cmd_rx) = mpsc::unbounded_channel();
(Simulator::new(config, ui_tx, cmd_tx), ui_rx)
}
fn simulator_for_tests() -> Simulator {
simulator_for_tests_with_protocol(OcppVersion::V1_6)
}
fn simulator_for_tests_v2_0_1() -> Simulator {
simulator_for_tests_with_protocol(OcppVersion::V2_0_1)
}
fn simulator_for_tests_v2_1() -> Simulator {
simulator_for_tests_with_protocol(OcppVersion::V2_1)
}
fn assert_schema_valid(relative_schema: &str, payload: &Value) {
let schema_text = crate::embedded_schemas::schema_text(relative_schema)
.unwrap_or_else(|| panic!("missing embedded schema {relative_schema}"));
let schema: Value = serde_json::from_str(schema_text).expect("schema");
let validator = jsonschema::validator_for(&schema).expect("compile schema");
let errors = validator
.iter_errors(payload)
.map(|error| error.to_string())
.collect::<Vec<_>>();
assert!(
errors.is_empty(),
"payload did not match {}: {}\npayload={}",
relative_schema,
errors.join("; "),
payload
);
}
fn queued_payload(simulator: &Simulator, action: &str) -> Value {
simulator
.queue
.iter()
.find(|call| call.action == action)
.map(|call| call.payload.clone())
.expect("queued action")
}
fn schema_path(schema_dir: &str, file_name: &str) -> String {
format!("{schema_dir}/{file_name}")
}
fn get_variable_data(variable: &str) -> Value {
json!({
"component": { "name": "ChargingStation" },
"variable": { "name": variable },
})
}
fn set_variable_data(variable: &str, value: &str) -> Value {
json!({
"component": { "name": "ChargingStation" },
"variable": { "name": variable },
"attributeValue": value,
})
}