inital
This commit is contained in:
12
OCPP.Core.Server/.config/dotnet-tools.json
Normal file
12
OCPP.Core.Server/.config/dotnet-tools.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-ef": {
|
||||
"version": "5.0.1",
|
||||
"commands": [
|
||||
"dotnet-ef"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
132
OCPP.Core.Server/ChargePointStatus.cs
Normal file
132
OCPP.Core.Server/ChargePointStatus.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.WebSockets;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
/// <summary>
|
||||
/// Encapsulates the data of a connected chargepoint in the server
|
||||
/// </summary>
|
||||
public class ChargePointStatus
|
||||
{
|
||||
private Dictionary<int, OnlineConnectorStatus> _onlineConnectors;
|
||||
|
||||
public ChargePointStatus()
|
||||
{
|
||||
}
|
||||
|
||||
public ChargePointStatus(ChargePoint chargePoint)
|
||||
{
|
||||
Id = chargePoint.ChargePointId;
|
||||
Name = chargePoint.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ID of chargepoint
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of chargepoint
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OCPP protocol version
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("protocol")]
|
||||
public string Protocol { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary with online connectors
|
||||
/// </summary>
|
||||
public Dictionary<int, OnlineConnectorStatus> OnlineConnectors
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_onlineConnectors == null)
|
||||
{
|
||||
_onlineConnectors = new Dictionary<int, OnlineConnectorStatus>();
|
||||
}
|
||||
return _onlineConnectors;
|
||||
}
|
||||
set
|
||||
{
|
||||
_onlineConnectors = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WebSocket for internal processing
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public WebSocket WebSocket { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encapsulates details about online charge point connectors
|
||||
/// </summary>
|
||||
public class OnlineConnectorStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Status of charge connector
|
||||
/// </summary>
|
||||
public ConnectorStatusEnum Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current charge rate in kW
|
||||
/// </summary>
|
||||
public double? ChargeRateKW { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current meter value in kWh
|
||||
/// </summary>
|
||||
public double? MeterKWH { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// StateOfCharges in percent
|
||||
/// </summary>
|
||||
public double? SoC { get; set; }
|
||||
}
|
||||
|
||||
public enum ConnectorStatusEnum
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"")]
|
||||
Undefined = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Available")]
|
||||
Available = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Occupied")]
|
||||
Occupied = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Unavailable")]
|
||||
Unavailable = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Faulted")]
|
||||
Faulted = 4
|
||||
}
|
||||
}
|
||||
205
OCPP.Core.Server/ControllerBase.cs
Normal file
205
OCPP.Core.Server/ControllerBase.cs
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Schema;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP16;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Internal string for OCPP protocol version
|
||||
/// </summary>
|
||||
protected virtual string ProtocolVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Configuration context for reading app settings
|
||||
/// </summary>
|
||||
protected IConfiguration Configuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Chargepoint status
|
||||
/// </summary>
|
||||
protected ChargePointStatus ChargePointStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ILogger object
|
||||
/// </summary>
|
||||
protected ILogger Logger { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// DbContext object
|
||||
/// </summary>
|
||||
protected OCPPCoreContext DbContext { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public ControllerBase(IConfiguration config, ILoggerFactory loggerFactory, ChargePointStatus chargePointStatus, OCPPCoreContext dbContext)
|
||||
{
|
||||
Configuration = config;
|
||||
|
||||
if (chargePointStatus != null)
|
||||
{
|
||||
ChargePointStatus = chargePointStatus;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("New ControllerBase => empty chargepoint status");
|
||||
}
|
||||
DbContext = dbContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize and validate JSON message (if schema file exists)
|
||||
/// </summary>
|
||||
protected T DeserializeMessage<T>(OCPPMessage msg)
|
||||
{
|
||||
string path = Assembly.GetExecutingAssembly().Location;
|
||||
string codeBase = Path.GetDirectoryName(path);
|
||||
|
||||
bool validateMessages = Configuration.GetValue<bool>("ValidateMessages", false);
|
||||
|
||||
string schemaJson = null;
|
||||
if (validateMessages &&
|
||||
!string.IsNullOrEmpty(codeBase) &&
|
||||
Directory.Exists(codeBase))
|
||||
{
|
||||
string msgTypeName = typeof(T).Name;
|
||||
string filename = Path.Combine(codeBase, $"Schema{ProtocolVersion}", $"{msgTypeName}.json");
|
||||
if (File.Exists(filename))
|
||||
{
|
||||
Logger.LogTrace("DeserializeMessage => Using schema file: {0}", filename);
|
||||
schemaJson = File.ReadAllText(filename);
|
||||
}
|
||||
}
|
||||
|
||||
JsonTextReader reader = new JsonTextReader(new StringReader(msg.JsonPayload));
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
|
||||
if (!string.IsNullOrEmpty(schemaJson))
|
||||
{
|
||||
JSchemaValidatingReader validatingReader = new JSchemaValidatingReader(reader);
|
||||
validatingReader.Schema = JSchema.Parse(schemaJson);
|
||||
|
||||
IList<string> messages = new List<string>();
|
||||
validatingReader.ValidationEventHandler += (o, a) => messages.Add(a.Message);
|
||||
T obj = serializer.Deserialize<T>(validatingReader);
|
||||
if (messages.Count > 0)
|
||||
{
|
||||
foreach (string err in messages)
|
||||
{
|
||||
Logger.LogWarning("DeserializeMessage {0} => Validation error: {1}", msg.Action, err);
|
||||
}
|
||||
throw new FormatException("Message validation failed");
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deserialization WITHOUT schema validation
|
||||
Logger.LogTrace("DeserializeMessage => Deserialization without schema validation");
|
||||
return serializer.Deserialize<T>(reader);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Helper function for creating and updating the ConnectorStatus in then database
|
||||
/// </summary>
|
||||
protected bool UpdateConnectorStatus(int connectorId, string status, DateTimeOffset? statusTime, double? meter, DateTimeOffset? meterTime)
|
||||
{
|
||||
try
|
||||
{
|
||||
ConnectorStatus connectorStatus = DbContext.Find<ConnectorStatus>(ChargePointStatus.Id, connectorId);
|
||||
if (connectorStatus == null)
|
||||
{
|
||||
// no matching entry => create connector status
|
||||
connectorStatus = new ConnectorStatus();
|
||||
connectorStatus.ChargePointId = ChargePointStatus.Id;
|
||||
connectorStatus.ConnectorId = connectorId;
|
||||
Logger.LogTrace("UpdateConnectorStatus => Creating new DB-ConnectorStatus: ID={0} / Connector={1}", connectorStatus.ChargePointId, connectorStatus.ConnectorId);
|
||||
DbContext.Add<ConnectorStatus>(connectorStatus);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(status))
|
||||
{
|
||||
connectorStatus.LastStatus = status;
|
||||
connectorStatus.LastStatusTime = ((statusTime.HasValue) ? statusTime.Value : DateTimeOffset.UtcNow).DateTime;
|
||||
}
|
||||
|
||||
if (meter.HasValue)
|
||||
{
|
||||
connectorStatus.LastMeter = meter.Value;
|
||||
connectorStatus.LastMeterTime = ((meterTime.HasValue) ? meterTime.Value : DateTimeOffset.UtcNow).DateTime;
|
||||
}
|
||||
DbContext.SaveChanges();
|
||||
Logger.LogInformation("UpdateConnectorStatus => Save ConnectorStatus: ID={0} / Connector={1} / Status={2} / Meter={3}", connectorStatus.ChargePointId, connectorId, status, meter);
|
||||
return true;
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "UpdateConnectorStatus => Exception writing connector status (ID={0} / Connector={1}): {2}", ChargePointStatus?.Id, connectorId, exp.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean charge tag Id from possible suffix ("..._abc")
|
||||
/// </summary>
|
||||
protected static string CleanChargeTagId(string rawChargeTagId, ILogger logger)
|
||||
{
|
||||
string idTag = rawChargeTagId;
|
||||
|
||||
// KEBA adds the serial to the idTag ("<idTag>_<serial>") => cut off suffix
|
||||
if (!string.IsNullOrWhiteSpace(rawChargeTagId))
|
||||
{
|
||||
int sep = rawChargeTagId.IndexOf('_');
|
||||
if (sep >= 0)
|
||||
{
|
||||
idTag = rawChargeTagId.Substring(0, sep);
|
||||
logger.LogTrace("CleanChargeTagId => Charge tag '{0}' => '{1}'", rawChargeTagId, idTag);
|
||||
}
|
||||
}
|
||||
|
||||
return idTag;
|
||||
}
|
||||
|
||||
protected static DateTimeOffset MaxExpiryDate
|
||||
{
|
||||
get
|
||||
{
|
||||
return new DateTime(2199, 12, 31);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
95
OCPP.Core.Server/ControllerOCPP16.Authorize.cs
Normal file
95
OCPP.Core.Server/ControllerOCPP16.Authorize.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP16;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP16
|
||||
{
|
||||
public string HandleAuthorize(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
AuthorizeResponse authorizeResponse = new AuthorizeResponse();
|
||||
|
||||
string idTag = null;
|
||||
try
|
||||
{
|
||||
Logger.LogTrace("Processing authorize request...");
|
||||
AuthorizeRequest authorizeRequest = DeserializeMessage<AuthorizeRequest>(msgIn);
|
||||
Logger.LogTrace("Authorize => Message deserialized");
|
||||
idTag = CleanChargeTagId(authorizeRequest.IdTag, Logger);
|
||||
|
||||
authorizeResponse.IdTagInfo.ParentIdTag = string.Empty;
|
||||
authorizeResponse.IdTagInfo.ExpiryDate = DateTimeOffset.UtcNow.AddMinutes(5); // default: 5 minutes
|
||||
try
|
||||
{
|
||||
ChargeTag ct = DbContext.Find<ChargeTag>(idTag);
|
||||
if (ct != null)
|
||||
{
|
||||
if (ct.ExpiryDate.HasValue)
|
||||
{
|
||||
authorizeResponse.IdTagInfo.ExpiryDate = ct.ExpiryDate.Value;
|
||||
}
|
||||
authorizeResponse.IdTagInfo.ParentIdTag = ct.ParentTagId;
|
||||
if (ct.Blocked.HasValue && ct.Blocked.Value)
|
||||
{
|
||||
authorizeResponse.IdTagInfo.Status = IdTagInfoStatus.Blocked;
|
||||
}
|
||||
else if (ct.ExpiryDate.HasValue && ct.ExpiryDate.Value < DateTime.Now)
|
||||
{
|
||||
authorizeResponse.IdTagInfo.Status = IdTagInfoStatus.Expired;
|
||||
}
|
||||
else
|
||||
{
|
||||
authorizeResponse.IdTagInfo.Status = IdTagInfoStatus.Accepted;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
authorizeResponse.IdTagInfo.Status = IdTagInfoStatus.Invalid;
|
||||
}
|
||||
|
||||
Logger.LogInformation("Authorize => Status: {0}", authorizeResponse.IdTagInfo.Status);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "Authorize => Exception reading charge tag ({0}): {1}", idTag, exp.Message);
|
||||
authorizeResponse.IdTagInfo.Status = IdTagInfoStatus.Invalid;
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(authorizeResponse);
|
||||
Logger.LogTrace("Authorize => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "Authorize => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.FormationViolation;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus?.Id, null,msgIn.Action, $"'{idTag}'=>{authorizeResponse.IdTagInfo?.Status}", errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
72
OCPP.Core.Server/ControllerOCPP16.BootNotification.cs
Normal file
72
OCPP.Core.Server/ControllerOCPP16.BootNotification.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP16;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP16
|
||||
{
|
||||
public string HandleBootNotification(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
|
||||
try
|
||||
{
|
||||
Logger.LogTrace("Processing boot notification...");
|
||||
BootNotificationRequest bootNotificationRequest = DeserializeMessage<BootNotificationRequest>(msgIn);
|
||||
Logger.LogTrace("BootNotification => Message deserialized");
|
||||
|
||||
BootNotificationResponse bootNotificationResponse = new BootNotificationResponse();
|
||||
bootNotificationResponse.CurrentTime = DateTimeOffset.UtcNow;
|
||||
bootNotificationResponse.Interval = Configuration.GetValue<int>("HeartBeatInterval", 300); // in seconds
|
||||
|
||||
if (ChargePointStatus != null)
|
||||
{
|
||||
// Known charge station => accept
|
||||
bootNotificationResponse.Status = BootNotificationResponseStatus.Accepted;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown charge station => reject
|
||||
bootNotificationResponse.Status = BootNotificationResponseStatus.Rejected;
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(bootNotificationResponse);
|
||||
Logger.LogTrace("BootNotification => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "BootNotification => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.FormationViolation;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus.Id, null, msgIn.Action, null, errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
74
OCPP.Core.Server/ControllerOCPP16.DataTransfer.cs
Normal file
74
OCPP.Core.Server/ControllerOCPP16.DataTransfer.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP16;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP16
|
||||
{
|
||||
public string HandleDataTransfer(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
DataTransferResponse dataTransferResponse = new DataTransferResponse();
|
||||
|
||||
bool msgWritten = false;
|
||||
|
||||
try
|
||||
{
|
||||
Logger.LogTrace("Processing data transfer...");
|
||||
DataTransferRequest dataTransferRequest = DeserializeMessage<DataTransferRequest>(msgIn);
|
||||
Logger.LogTrace("DataTransfer => Message deserialized");
|
||||
|
||||
if (ChargePointStatus != null)
|
||||
{
|
||||
// Known charge station
|
||||
msgWritten = WriteMessageLog(ChargePointStatus.Id, null, msgIn.Action, string.Format("VendorId={0} / MessageId={1} / Data={2}", dataTransferRequest.VendorId, dataTransferRequest.MessageId, dataTransferRequest.Data), errorCode);
|
||||
dataTransferResponse.Status = DataTransferResponseStatus.Accepted;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown charge station
|
||||
errorCode = ErrorCodes.GenericError;
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(dataTransferResponse);
|
||||
Logger.LogTrace("DataTransfer => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "DataTransfer => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
|
||||
if (!msgWritten)
|
||||
{
|
||||
WriteMessageLog(ChargePointStatus.Id, null, msgIn.Action, null, errorCode);
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
48
OCPP.Core.Server/ControllerOCPP16.Heartbeat.cs
Normal file
48
OCPP.Core.Server/ControllerOCPP16.Heartbeat.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP16;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP16
|
||||
{
|
||||
public string HandleHeartBeat(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
|
||||
Logger.LogTrace("Processing heartbeat...");
|
||||
HeartbeatResponse heartbeatResponse = new HeartbeatResponse();
|
||||
heartbeatResponse.CurrentTime = DateTimeOffset.UtcNow;
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(heartbeatResponse);
|
||||
Logger.LogTrace("Heartbeat => Response serialized");
|
||||
|
||||
WriteMessageLog(ChargePointStatus?.Id, null, msgIn.Action, null, errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
222
OCPP.Core.Server/ControllerOCPP16.MeterValues.cs
Normal file
222
OCPP.Core.Server/ControllerOCPP16.MeterValues.cs
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
http://www.diva-portal.se/smash/get/diva2:838105/FULLTEXT01.pdf
|
||||
|
||||
Measurand values Description
|
||||
Energy.Active.Import.Register Energy imported by EV (Wh of kWh)
|
||||
Power.Active.Import Instantaneous active power imported by EV (W or kW)
|
||||
Current.Import Instantaneous current flow to EV (A)
|
||||
Voltage AC RMS supply voltage (V)
|
||||
Temperature Temperature reading inside the charge point
|
||||
|
||||
<cs:meterValuesRequest>
|
||||
<cs:connectorId>0</cs:connectorId>
|
||||
<cs:transactionId>170</cs:transactionId>
|
||||
<cs:values>
|
||||
<cs:timestamp>2014-12-03T10:52:59.410Z</cs:timestamp>
|
||||
<cs:value cs:measurand="Current.Import" cs:unit="Amp">41.384</cs:value>
|
||||
<cs:value cs:measurand="Voltage" cs:unit="Volt">226.0</cs:value>
|
||||
<cs:value cs:measurand="Power.Active.Import" cs:unit="W">7018</cs:value>
|
||||
<cs:value cs:measurand="Energy.Active.Import.Register" cs:unit="Wh">2662</cs:value>
|
||||
<cs:value cs:measurand="Temperature" cs:unit="Celsius">24</cs:value>
|
||||
</cs:values>
|
||||
</cs:meterValuesRequest>
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP16;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP16
|
||||
{
|
||||
public string HandleMeterValues(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
MeterValuesResponse meterValuesResponse = new MeterValuesResponse();
|
||||
|
||||
int connectorId = -1;
|
||||
string msgMeterValue = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
Logger.LogTrace("Processing meter values...");
|
||||
MeterValuesRequest meterValueRequest = DeserializeMessage<MeterValuesRequest>(msgIn);
|
||||
Logger.LogTrace("MeterValues => Message deserialized");
|
||||
|
||||
connectorId = meterValueRequest.ConnectorId;
|
||||
|
||||
if (ChargePointStatus != null)
|
||||
{
|
||||
// Known charge station => process meter values
|
||||
double currentChargeKW = -1;
|
||||
double meterKWH = -1;
|
||||
DateTimeOffset? meterTime = null;
|
||||
double stateOfCharge = -1;
|
||||
foreach (MeterValue meterValue in meterValueRequest.MeterValue)
|
||||
{
|
||||
foreach (SampledValue sampleValue in meterValue.SampledValue)
|
||||
{
|
||||
Logger.LogTrace("MeterValues => Context={0} / Format={1} / Value={2} / Unit={3} / Location={4} / Measurand={5} / Phase={6}",
|
||||
sampleValue.Context, sampleValue.Format, sampleValue.Value, sampleValue.Unit, sampleValue.Location, sampleValue.Measurand, sampleValue.Phase);
|
||||
|
||||
if (sampleValue.Measurand == SampledValueMeasurand.Power_Active_Import)
|
||||
{
|
||||
// current charging power
|
||||
if (double.TryParse(sampleValue.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out currentChargeKW))
|
||||
{
|
||||
if (sampleValue.Unit == SampledValueUnit.W ||
|
||||
sampleValue.Unit == SampledValueUnit.VA ||
|
||||
sampleValue.Unit == SampledValueUnit.Var ||
|
||||
sampleValue.Unit == null)
|
||||
{
|
||||
Logger.LogTrace("MeterValues => Charging '{0:0.0}' W", currentChargeKW);
|
||||
// convert W => kW
|
||||
currentChargeKW = currentChargeKW / 1000;
|
||||
}
|
||||
else if (sampleValue.Unit == SampledValueUnit.KW ||
|
||||
sampleValue.Unit == SampledValueUnit.KVA ||
|
||||
sampleValue.Unit == SampledValueUnit.Kvar)
|
||||
{
|
||||
// already kW => OK
|
||||
Logger.LogTrace("MeterValues => Charging '{0:0.0}' kW", currentChargeKW);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogWarning("MeterValues => Charging: unexpected unit: '{0}' (Value={1})", sampleValue.Unit, sampleValue.Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("MeterValues => Charging: invalid value '{0}' (Unit={1})", sampleValue.Value, sampleValue.Unit);
|
||||
}
|
||||
}
|
||||
else if (sampleValue.Measurand == SampledValueMeasurand.Energy_Active_Import_Register ||
|
||||
sampleValue.Measurand == null)
|
||||
{
|
||||
// charged amount of energy
|
||||
if (double.TryParse(sampleValue.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out meterKWH))
|
||||
{
|
||||
if (sampleValue.Unit == SampledValueUnit.Wh ||
|
||||
sampleValue.Unit == SampledValueUnit.Varh ||
|
||||
sampleValue.Unit == null)
|
||||
{
|
||||
Logger.LogTrace("MeterValues => Value: '{0:0.0}' Wh", meterKWH);
|
||||
// convert Wh => kWh
|
||||
meterKWH = meterKWH / 1000;
|
||||
}
|
||||
else if (sampleValue.Unit == SampledValueUnit.KWh ||
|
||||
sampleValue.Unit == SampledValueUnit.Kvarh)
|
||||
{
|
||||
// already kWh => OK
|
||||
Logger.LogTrace("MeterValues => Value: '{0:0.0}' kWh", meterKWH);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogWarning("MeterValues => Value: unexpected unit: '{0}' (Value={1})", sampleValue.Unit, sampleValue.Value);
|
||||
}
|
||||
meterTime = meterValue.Timestamp;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("MeterValues => Value: invalid value '{0}' (Unit={1})", sampleValue.Value, sampleValue.Unit);
|
||||
}
|
||||
}
|
||||
else if (sampleValue.Measurand == SampledValueMeasurand.SoC)
|
||||
{
|
||||
// state of charge (battery status)
|
||||
if (double.TryParse(sampleValue.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out stateOfCharge))
|
||||
{
|
||||
Logger.LogTrace("MeterValues => SoC: '{0:0.0}'%", stateOfCharge);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("MeterValues => invalid value '{0}' (SoC)", sampleValue.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write charging/meter data in chargepoint status
|
||||
if (connectorId > 0)
|
||||
{
|
||||
msgMeterValue = $"Meter (kWh): {meterKWH} | Charge (kW): {currentChargeKW} | SoC (%): {stateOfCharge}";
|
||||
|
||||
if (meterKWH >= 0)
|
||||
{
|
||||
UpdateConnectorStatus(connectorId, null, null, meterKWH, meterTime);
|
||||
}
|
||||
|
||||
if (currentChargeKW >= 0 || meterKWH >= 0 || stateOfCharge >= 0)
|
||||
{
|
||||
if (ChargePointStatus.OnlineConnectors.ContainsKey(connectorId))
|
||||
{
|
||||
OnlineConnectorStatus ocs = ChargePointStatus.OnlineConnectors[connectorId];
|
||||
if (currentChargeKW >= 0) ocs.ChargeRateKW = currentChargeKW;
|
||||
if (meterKWH >= 0) ocs.MeterKWH = meterKWH;
|
||||
if (stateOfCharge >= 0) ocs.SoC = stateOfCharge;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnlineConnectorStatus ocs = new OnlineConnectorStatus();
|
||||
if (currentChargeKW >= 0) ocs.ChargeRateKW = currentChargeKW;
|
||||
if (meterKWH >= 0) ocs.MeterKWH = meterKWH;
|
||||
if (stateOfCharge >= 0) ocs.SoC = stateOfCharge;
|
||||
if (ChargePointStatus.OnlineConnectors.TryAdd(connectorId, ocs))
|
||||
{
|
||||
Logger.LogTrace("MeterValues => Set OnlineConnectorStatus for ChargePoint={0} / Connector={1} / Values: {2}", ChargePointStatus?.Id, connectorId, msgMeterValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("MeterValues => Error adding new OnlineConnectorStatus for ChargePoint={0} / Connector={1} / Values: {2}", ChargePointStatus?.Id, connectorId, msgMeterValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown charge station
|
||||
errorCode = ErrorCodes.GenericError;
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(meterValuesResponse);
|
||||
Logger.LogTrace("MeterValues => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "MeterValues => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus.Id, connectorId, msgIn.Action, msgMeterValue, errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
59
OCPP.Core.Server/ControllerOCPP16.Reset.cs
Normal file
59
OCPP.Core.Server/ControllerOCPP16.Reset.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP16;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP16
|
||||
{
|
||||
public void HandleReset(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
Logger.LogInformation("Reset answer: ChargePointId={0} / MsgType={1} / ErrCode={2}", ChargePointStatus.Id, msgIn.MessageType, msgIn.ErrorCode);
|
||||
|
||||
try
|
||||
{
|
||||
ResetResponse resetResponse = DeserializeMessage<ResetResponse>(msgIn);
|
||||
Logger.LogInformation("Reset => Answer status: {0}", resetResponse?.Status);
|
||||
WriteMessageLog(ChargePointStatus?.Id, null, msgOut.Action, resetResponse?.Status.ToString(), msgIn.ErrorCode);
|
||||
|
||||
if (msgOut.TaskCompletionSource != null)
|
||||
{
|
||||
// Set API response as TaskCompletion-result
|
||||
string apiResult = "{\"status\": " + JsonConvert.ToString(resetResponse.Status.ToString()) + "}";
|
||||
Logger.LogTrace("HandleReset => API response: {0}" , apiResult);
|
||||
|
||||
msgOut.TaskCompletionSource.SetResult(apiResult);
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "HandleReset => Exception: {0}", exp.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
153
OCPP.Core.Server/ControllerOCPP16.StartTransaction.cs
Normal file
153
OCPP.Core.Server/ControllerOCPP16.StartTransaction.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP16;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP16
|
||||
{
|
||||
public string HandleStartTransaction(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
StartTransactionResponse startTransactionResponse = new StartTransactionResponse();
|
||||
|
||||
int connectorId = -1;
|
||||
bool denyConcurrentTx = Configuration.GetValue<bool>("DenyConcurrentTx", false);
|
||||
|
||||
try
|
||||
{
|
||||
Logger.LogTrace("Processing startTransaction request...");
|
||||
StartTransactionRequest startTransactionRequest = DeserializeMessage<StartTransactionRequest>(msgIn);
|
||||
Logger.LogTrace("StartTransaction => Message deserialized");
|
||||
|
||||
string idTag = CleanChargeTagId(startTransactionRequest.IdTag, Logger);
|
||||
connectorId = startTransactionRequest.ConnectorId;
|
||||
|
||||
startTransactionResponse.IdTagInfo.ParentIdTag = string.Empty;
|
||||
startTransactionResponse.IdTagInfo.ExpiryDate = MaxExpiryDate;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(idTag))
|
||||
{
|
||||
// no RFID-Tag => accept request
|
||||
startTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.Accepted;
|
||||
Logger.LogInformation("StartTransaction => no charge tag => Status: {0}", startTransactionResponse.IdTagInfo.Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
ChargeTag ct = DbContext.Find<ChargeTag>(idTag);
|
||||
if (ct != null)
|
||||
{
|
||||
if (ct.ExpiryDate.HasValue) startTransactionResponse.IdTagInfo.ExpiryDate = ct.ExpiryDate.Value;
|
||||
startTransactionResponse.IdTagInfo.ParentIdTag = ct.ParentTagId;
|
||||
if (ct.Blocked.HasValue && ct.Blocked.Value)
|
||||
{
|
||||
startTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.Blocked;
|
||||
}
|
||||
else if (ct.ExpiryDate.HasValue && ct.ExpiryDate.Value < DateTime.Now)
|
||||
{
|
||||
startTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.Expired;
|
||||
}
|
||||
else
|
||||
{
|
||||
startTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.Accepted;
|
||||
|
||||
if (denyConcurrentTx)
|
||||
{
|
||||
// Check that no open transaction with this idTag exists
|
||||
Transaction tx = DbContext.Transactions
|
||||
.Where(t => !t.StopTime.HasValue && t.StartTagId == idTag)
|
||||
.OrderByDescending(t => t.TransactionId)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (tx != null)
|
||||
{
|
||||
startTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.ConcurrentTx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
startTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.Invalid;
|
||||
}
|
||||
|
||||
Logger.LogInformation("StartTransaction => Charge tag='{0}' => Status: {1}", idTag, startTransactionResponse.IdTagInfo.Status);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "StartTransaction => Exception reading charge tag ({0}): {1}", idTag, exp.Message);
|
||||
startTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
if (connectorId > 0)
|
||||
{
|
||||
// Update meter value in db connector status
|
||||
UpdateConnectorStatus(connectorId, ConnectorStatusEnum.Occupied.ToString(), startTransactionRequest.Timestamp, (double)startTransactionRequest.MeterStart / 1000, startTransactionRequest.Timestamp);
|
||||
}
|
||||
|
||||
if (startTransactionResponse.IdTagInfo.Status == IdTagInfoStatus.Accepted)
|
||||
{
|
||||
try
|
||||
{
|
||||
Transaction transaction = new Transaction();
|
||||
transaction.ChargePointId = ChargePointStatus?.Id;
|
||||
transaction.ConnectorId = startTransactionRequest.ConnectorId;
|
||||
transaction.StartTagId = idTag;
|
||||
transaction.StartTime = startTransactionRequest.Timestamp.UtcDateTime;
|
||||
transaction.MeterStart = (double)startTransactionRequest.MeterStart / 1000; // Meter value here is always Wh
|
||||
transaction.StartResult = startTransactionResponse.IdTagInfo.Status.ToString();
|
||||
DbContext.Add<Transaction>(transaction);
|
||||
DbContext.SaveChanges();
|
||||
|
||||
// Return DB-ID as transaction ID
|
||||
startTransactionResponse.TransactionId = transaction.TransactionId;
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "StartTransaction => Exception writing transaction: chargepoint={0} / tag={1}", ChargePointStatus?.Id, idTag);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(startTransactionResponse);
|
||||
Logger.LogTrace("StartTransaction => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "StartTransaction => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.FormationViolation;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus?.Id, connectorId, msgIn.Action, startTransactionResponse.IdTagInfo?.Status.ToString(), errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
124
OCPP.Core.Server/ControllerOCPP16.StatusNotification.cs
Normal file
124
OCPP.Core.Server/ControllerOCPP16.StatusNotification.cs
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP16;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP16
|
||||
{
|
||||
public string HandleStatusNotification(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
StatusNotificationResponse statusNotificationResponse = new StatusNotificationResponse();
|
||||
|
||||
int connectorId = 0;
|
||||
bool msgWritten = false;
|
||||
|
||||
try
|
||||
{
|
||||
Logger.LogTrace("Processing status notification...");
|
||||
StatusNotificationRequest statusNotificationRequest = DeserializeMessage<StatusNotificationRequest>(msgIn);
|
||||
Logger.LogTrace("StatusNotification => Message deserialized");
|
||||
|
||||
connectorId = statusNotificationRequest.ConnectorId;
|
||||
|
||||
// Write raw status in DB
|
||||
msgWritten = WriteMessageLog(ChargePointStatus.Id, connectorId, msgIn.Action, string.Format("Info={0} / Status={1} / ", statusNotificationRequest.Info, statusNotificationRequest.Status), statusNotificationRequest.ErrorCode.ToString());
|
||||
|
||||
ConnectorStatusEnum newStatus = ConnectorStatusEnum.Undefined;
|
||||
|
||||
switch (statusNotificationRequest.Status)
|
||||
{
|
||||
case StatusNotificationRequestStatus.Available:
|
||||
newStatus = ConnectorStatusEnum.Available;
|
||||
break;
|
||||
case StatusNotificationRequestStatus.Preparing:
|
||||
case StatusNotificationRequestStatus.Charging:
|
||||
case StatusNotificationRequestStatus.SuspendedEVSE:
|
||||
case StatusNotificationRequestStatus.SuspendedEV:
|
||||
case StatusNotificationRequestStatus.Finishing:
|
||||
case StatusNotificationRequestStatus.Reserved:
|
||||
newStatus = ConnectorStatusEnum.Occupied;
|
||||
break;
|
||||
case StatusNotificationRequestStatus.Unavailable:
|
||||
newStatus = ConnectorStatusEnum.Unavailable;
|
||||
break;
|
||||
case StatusNotificationRequestStatus.Faulted:
|
||||
newStatus = ConnectorStatusEnum.Faulted;
|
||||
break;
|
||||
|
||||
}
|
||||
Logger.LogInformation("StatusNotification => ChargePoint={0} / Connector={1} / newStatus={2}", ChargePointStatus?.Id, connectorId, newStatus.ToString());
|
||||
|
||||
if (connectorId > 0)
|
||||
{
|
||||
if (UpdateConnectorStatus(connectorId, newStatus.ToString(), statusNotificationRequest.Timestamp, null, null) == false)
|
||||
{
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
|
||||
if (ChargePointStatus.OnlineConnectors.ContainsKey(connectorId))
|
||||
{
|
||||
OnlineConnectorStatus ocs = ChargePointStatus.OnlineConnectors[connectorId];
|
||||
ocs.Status = newStatus;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnlineConnectorStatus ocs = new OnlineConnectorStatus();
|
||||
ocs.Status = newStatus;
|
||||
if (ChargePointStatus.OnlineConnectors.TryAdd(connectorId, ocs))
|
||||
{
|
||||
Logger.LogTrace("StatusNotification => new OnlineConnectorStatus with values: ChargePoint={0} / Connector={1} / newStatus={2}", ChargePointStatus?.Id, connectorId, newStatus.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("StatusNotification => Error adding new OnlineConnectorStatus for ChargePoint={0} / Connector={1}", ChargePointStatus?.Id, connectorId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogWarning("StatusNotification => Status for unexpected ConnectorId={1} on ChargePoint={0}", ChargePointStatus?.Id, connectorId);
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(statusNotificationResponse);
|
||||
Logger.LogTrace("StatusNotification => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "StatusNotification => ChargePoint={0} / Exception: {1}", ChargePointStatus.Id, exp.Message);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
|
||||
if (!msgWritten)
|
||||
{
|
||||
WriteMessageLog(ChargePointStatus.Id, connectorId, msgIn.Action, null, errorCode);
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
169
OCPP.Core.Server/ControllerOCPP16.StopTransaction.cs
Normal file
169
OCPP.Core.Server/ControllerOCPP16.StopTransaction.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP16;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP16
|
||||
{
|
||||
public string HandleStopTransaction(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
StopTransactionResponse stopTransactionResponse = new StopTransactionResponse();
|
||||
stopTransactionResponse.IdTagInfo = new IdTagInfo();
|
||||
|
||||
try
|
||||
{
|
||||
Logger.LogTrace("Processing stopTransaction request...");
|
||||
StopTransactionRequest stopTransactionRequest = DeserializeMessage<StopTransactionRequest>(msgIn);
|
||||
Logger.LogTrace("StopTransaction => Message deserialized");
|
||||
|
||||
string idTag = CleanChargeTagId(stopTransactionRequest.IdTag, Logger);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(idTag))
|
||||
{
|
||||
// no RFID-Tag => accept request
|
||||
stopTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.Accepted;
|
||||
Logger.LogInformation("StopTransaction => no charge tag => Status: {0}", stopTransactionResponse.IdTagInfo.Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
stopTransactionResponse.IdTagInfo.ExpiryDate = MaxExpiryDate;
|
||||
|
||||
try
|
||||
{
|
||||
ChargeTag ct = DbContext.Find<ChargeTag>(idTag);
|
||||
if (ct != null)
|
||||
{
|
||||
if (ct.ExpiryDate.HasValue) stopTransactionResponse.IdTagInfo.ExpiryDate = ct.ExpiryDate.Value;
|
||||
stopTransactionResponse.IdTagInfo.ParentIdTag = ct.ParentTagId;
|
||||
if (ct.Blocked.HasValue && ct.Blocked.Value)
|
||||
{
|
||||
stopTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.Blocked;
|
||||
}
|
||||
else if (ct.ExpiryDate.HasValue && ct.ExpiryDate.Value < DateTime.Now)
|
||||
{
|
||||
stopTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.Expired;
|
||||
}
|
||||
else
|
||||
{
|
||||
stopTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.Accepted;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stopTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.Invalid;
|
||||
}
|
||||
|
||||
Logger.LogInformation("StopTransaction => RFID-tag='{0}' => Status: {1}", idTag, stopTransactionResponse.IdTagInfo.Status);
|
||||
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "StopTransaction => Exception reading charge tag ({0}): {1}", idTag, exp.Message);
|
||||
stopTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
if (stopTransactionResponse.IdTagInfo.Status == IdTagInfoStatus.Accepted)
|
||||
{
|
||||
try
|
||||
{
|
||||
Transaction transaction = DbContext.Find<Transaction>(stopTransactionRequest.TransactionId);
|
||||
if (transaction != null &&
|
||||
transaction.ChargePointId == ChargePointStatus.Id &&
|
||||
!transaction.StopTime.HasValue)
|
||||
{
|
||||
if (transaction.ConnectorId > 0)
|
||||
{
|
||||
// Update meter value in db connector status
|
||||
UpdateConnectorStatus(transaction.ConnectorId, null, null, (double)stopTransactionRequest.MeterStop / 1000, stopTransactionRequest.Timestamp);
|
||||
}
|
||||
|
||||
// check current tag against start tag
|
||||
bool valid = true;
|
||||
if (!string.Equals(transaction.StartTagId, idTag, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
// tags are different => same group?
|
||||
ChargeTag startTag = DbContext.Find<ChargeTag>(transaction.StartTagId);
|
||||
if (startTag != null)
|
||||
{
|
||||
if (!string.Equals(startTag.ParentTagId, stopTransactionResponse.IdTagInfo.ParentIdTag, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
Logger.LogInformation("StopTransaction => Start-Tag ('{0}') and End-Tag ('{1}') do not match: Invalid!", transaction.StartTagId, idTag);
|
||||
stopTransactionResponse.IdTagInfo.Status = IdTagInfoStatus.Invalid;
|
||||
valid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogInformation("StopTransaction => Different RFID-Tags but matching group ('{0}')", stopTransactionResponse.IdTagInfo.ParentIdTag);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("StopTransaction => Start-Tag not found: '{0}'", transaction.StartTagId);
|
||||
// assume "valid" and allow to end the transaction
|
||||
}
|
||||
}
|
||||
|
||||
if (valid)
|
||||
{
|
||||
transaction.StopTagId = idTag;
|
||||
transaction.MeterStop = (double)stopTransactionRequest.MeterStop / 1000; // Meter value here is always Wh
|
||||
transaction.StopReason = stopTransactionRequest.Reason.ToString();
|
||||
transaction.StopTime = stopTransactionRequest.Timestamp.UtcDateTime;
|
||||
DbContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("StopTransaction => Unknown or not matching transaction: id={0} / chargepoint={1} / tag={2}", stopTransactionRequest.TransactionId, ChargePointStatus?.Id, idTag);
|
||||
WriteMessageLog(ChargePointStatus?.Id, transaction?.ConnectorId, msgIn.Action, string.Format("UnknownTransaction:ID={0}/Meter={1}", stopTransactionRequest.TransactionId, stopTransactionRequest.MeterStop), errorCode);
|
||||
errorCode = ErrorCodes.PropertyConstraintViolation;
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "StopTransaction => Exception writing transaction: chargepoint={0} / tag={1}", ChargePointStatus?.Id, idTag);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(stopTransactionResponse);
|
||||
Logger.LogTrace("StopTransaction => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "StopTransaction => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.FormationViolation;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus?.Id, null, msgIn.Action, stopTransactionResponse.IdTagInfo?.Status.ToString(), errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
59
OCPP.Core.Server/ControllerOCPP16.UnlockConnector.cs
Normal file
59
OCPP.Core.Server/ControllerOCPP16.UnlockConnector.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP16;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP16
|
||||
{
|
||||
public void HandleUnlockConnector(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
Logger.LogInformation("UnlockConnector answer: ChargePointId={0} / MsgType={1} / ErrCode={2}", ChargePointStatus.Id, msgIn.MessageType, msgIn.ErrorCode);
|
||||
|
||||
try
|
||||
{
|
||||
UnlockConnectorResponse unlockConnectorResponse = DeserializeMessage<UnlockConnectorResponse>(msgIn);
|
||||
Logger.LogInformation("HandleUnlockConnector => Answer status: {0}", unlockConnectorResponse?.Status);
|
||||
WriteMessageLog(ChargePointStatus?.Id, null, msgOut.Action, unlockConnectorResponse?.Status.ToString(), msgIn.ErrorCode);
|
||||
|
||||
if (msgOut.TaskCompletionSource != null)
|
||||
{
|
||||
// Set API response as TaskCompletion-result
|
||||
string apiResult = "{\"status\": " + JsonConvert.ToString(unlockConnectorResponse.Status.ToString()) + "}";
|
||||
Logger.LogTrace("HandleUnlockConnector => API response: {0}", apiResult);
|
||||
|
||||
msgOut.TaskCompletionSource.SetResult(apiResult);
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "HandleUnlockConnector => Exception: {0}", exp.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
175
OCPP.Core.Server/ControllerOCPP16.cs
Normal file
175
OCPP.Core.Server/ControllerOCPP16.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP16;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP16 : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Internal string for OCPP protocol version
|
||||
/// </summary>
|
||||
protected override string ProtocolVersion
|
||||
{
|
||||
get { return "16"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public ControllerOCPP16(IConfiguration config, ILoggerFactory loggerFactory, ChargePointStatus chargePointStatus, OCPPCoreContext dbContext) :
|
||||
base(config, loggerFactory, chargePointStatus, dbContext)
|
||||
{
|
||||
Logger = loggerFactory.CreateLogger(typeof(ControllerOCPP16));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes the charge point message and returns the answer message
|
||||
/// </summary>
|
||||
public OCPPMessage ProcessRequest(OCPPMessage msgIn)
|
||||
{
|
||||
OCPPMessage msgOut = new OCPPMessage();
|
||||
msgOut.MessageType = "3";
|
||||
msgOut.UniqueId = msgIn.UniqueId;
|
||||
|
||||
string errorCode = null;
|
||||
|
||||
switch (msgIn.Action)
|
||||
{
|
||||
case "BootNotification":
|
||||
errorCode = HandleBootNotification(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "Heartbeat":
|
||||
errorCode = HandleHeartBeat(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "Authorize":
|
||||
errorCode = HandleAuthorize(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "StartTransaction":
|
||||
errorCode = HandleStartTransaction(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "StopTransaction":
|
||||
errorCode = HandleStopTransaction(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "MeterValues":
|
||||
errorCode = HandleMeterValues(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "StatusNotification":
|
||||
errorCode = HandleStatusNotification(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "DataTransfer":
|
||||
errorCode = HandleDataTransfer(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
default:
|
||||
errorCode = ErrorCodes.NotSupported;
|
||||
WriteMessageLog(ChargePointStatus.Id, null, msgIn.Action, msgIn.JsonPayload, errorCode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(errorCode))
|
||||
{
|
||||
// Inavlid message type => return type "4" (CALLERROR)
|
||||
msgOut.MessageType = "4";
|
||||
msgOut.ErrorCode = errorCode;
|
||||
Logger.LogDebug("ControllerOCPP16 => Return error code messge: ErrorCode={0}", errorCode);
|
||||
}
|
||||
|
||||
return msgOut;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Processes the charge point message and returns the answer message
|
||||
/// </summary>
|
||||
public void ProcessAnswer(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
// The response (msgIn) has no action => check action in original request (msgOut)
|
||||
switch (msgOut.Action)
|
||||
{
|
||||
case "Reset":
|
||||
HandleReset(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "UnlockConnector":
|
||||
HandleUnlockConnector(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
default:
|
||||
WriteMessageLog(ChargePointStatus.Id, null, msgIn.Action, msgIn.JsonPayload, "Unknown answer");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function for writing a log entry in database
|
||||
/// </summary>
|
||||
private bool WriteMessageLog(string chargePointId, int? connectorId, string message, string result, string errorCode)
|
||||
{
|
||||
try
|
||||
{
|
||||
int dbMessageLog = Configuration.GetValue<int>("DbMessageLog", 0);
|
||||
if (dbMessageLog > 0 && !string.IsNullOrWhiteSpace(chargePointId))
|
||||
{
|
||||
bool doLog = (dbMessageLog > 1 ||
|
||||
(message != "BootNotification" &&
|
||||
message != "Heartbeat" &&
|
||||
message != "DataTransfer" &&
|
||||
message != "StatusNotification"));
|
||||
|
||||
if (doLog)
|
||||
{
|
||||
MessageLog msgLog = new MessageLog();
|
||||
msgLog.ChargePointId = chargePointId;
|
||||
msgLog.ConnectorId = connectorId;
|
||||
msgLog.LogTime = DateTime.UtcNow;
|
||||
msgLog.Message = message;
|
||||
msgLog.Result = result;
|
||||
msgLog.ErrorCode = errorCode;
|
||||
DbContext.MessageLogs.Add(msgLog);
|
||||
Logger.LogTrace("MessageLog => Writing entry '{0}'", message);
|
||||
DbContext.SaveChanges();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "MessageLog => Error writing entry '{0}'", message);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
106
OCPP.Core.Server/ControllerOCPP20.Authorize.cs
Normal file
106
OCPP.Core.Server/ControllerOCPP20.Authorize.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public string HandleAuthorize(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
AuthorizeResponse authorizeResponse = new AuthorizeResponse();
|
||||
|
||||
string idTag = null;
|
||||
try
|
||||
{
|
||||
Logger.LogTrace("Processing authorize request...");
|
||||
AuthorizeRequest authorizeRequest = DeserializeMessage<AuthorizeRequest>(msgIn);
|
||||
Logger.LogTrace("Authorize => Message deserialized");
|
||||
idTag = CleanChargeTagId(authorizeRequest.IdToken?.IdToken, Logger);
|
||||
|
||||
authorizeResponse.CustomData = new CustomDataType();
|
||||
authorizeResponse.CustomData.VendorId = VendorId;
|
||||
|
||||
authorizeResponse.IdTokenInfo = new IdTokenInfoType();
|
||||
authorizeResponse.IdTokenInfo.CustomData = new CustomDataType();
|
||||
authorizeResponse.IdTokenInfo.CustomData.VendorId = VendorId;
|
||||
authorizeResponse.IdTokenInfo.GroupIdToken = new IdTokenType();
|
||||
authorizeResponse.IdTokenInfo.GroupIdToken.CustomData = new CustomDataType();
|
||||
authorizeResponse.IdTokenInfo.GroupIdToken.CustomData.VendorId = VendorId;
|
||||
authorizeResponse.IdTokenInfo.GroupIdToken.IdToken = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
ChargeTag ct = DbContext.Find<ChargeTag>(idTag);
|
||||
if (ct != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ct.ParentTagId))
|
||||
{
|
||||
authorizeResponse.IdTokenInfo.GroupIdToken.IdToken = ct.ParentTagId;
|
||||
}
|
||||
|
||||
if (ct.Blocked.HasValue && ct.Blocked.Value)
|
||||
{
|
||||
authorizeResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Blocked;
|
||||
}
|
||||
else if (ct.ExpiryDate.HasValue && ct.ExpiryDate.Value < DateTime.Now)
|
||||
{
|
||||
authorizeResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Expired;
|
||||
}
|
||||
else
|
||||
{
|
||||
authorizeResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Accepted;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
authorizeResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Invalid;
|
||||
}
|
||||
|
||||
Logger.LogInformation("Authorize => Status: {0}", authorizeResponse.IdTokenInfo.Status);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "Authorize => Exception reading charge tag ({0}): {1}", idTag, exp.Message);
|
||||
authorizeResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Invalid;
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(authorizeResponse);
|
||||
Logger.LogTrace("Authorize => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "Authorize => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.FormationViolation;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus?.Id, null, msgIn.Action, $"'{idTag}'=>{authorizeResponse.IdTokenInfo?.Status}", errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
82
OCPP.Core.Server/ControllerOCPP20.BootNotification.cs
Normal file
82
OCPP.Core.Server/ControllerOCPP20.BootNotification.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public string HandleBootNotification(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
string bootReason = null;
|
||||
try
|
||||
{
|
||||
Logger.LogTrace("Processing boot notification...");
|
||||
BootNotificationRequest bootNotificationRequest = DeserializeMessage<BootNotificationRequest>(msgIn);
|
||||
Logger.LogTrace("BootNotification => Message deserialized");
|
||||
|
||||
bootReason = bootNotificationRequest?.Reason.ToString();
|
||||
Logger.LogInformation("BootNotification => Reason={0}", bootReason);
|
||||
|
||||
BootNotificationResponse bootNotificationResponse = new BootNotificationResponse();
|
||||
bootNotificationResponse.CurrentTime = DateTimeOffset.UtcNow;
|
||||
bootNotificationResponse.Interval = Configuration.GetValue<int>("HeartBeatInterval", 300); // in seconds
|
||||
|
||||
bootNotificationResponse.StatusInfo = new StatusInfoType();
|
||||
bootNotificationResponse.StatusInfo.ReasonCode = string.Empty;
|
||||
bootNotificationResponse.StatusInfo.AdditionalInfo = string.Empty;
|
||||
|
||||
bootNotificationResponse.CustomData = new CustomDataType();
|
||||
bootNotificationResponse.CustomData.VendorId = VendorId;
|
||||
|
||||
if (ChargePointStatus != null)
|
||||
{
|
||||
// Known charge station => accept
|
||||
bootNotificationResponse.Status = RegistrationStatusEnumType.Accepted;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown charge station => reject
|
||||
bootNotificationResponse.Status = RegistrationStatusEnumType.Rejected;
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(bootNotificationResponse);
|
||||
Logger.LogTrace("BootNotification => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "BootNotification => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.FormationViolation;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus.Id, null, msgIn.Action, bootReason, errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
76
OCPP.Core.Server/ControllerOCPP20.ClearedChargingLimit.cs
Normal file
76
OCPP.Core.Server/ControllerOCPP20.ClearedChargingLimit.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public string HandleClearedChargingLimit(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
|
||||
Logger.LogTrace("Processing ClearedChargingLimit...");
|
||||
ClearedChargingLimitResponse clearedChargingLimitResponse = new ClearedChargingLimitResponse();
|
||||
clearedChargingLimitResponse.CustomData = new CustomDataType();
|
||||
clearedChargingLimitResponse.CustomData.VendorId = VendorId;
|
||||
|
||||
string source = null;
|
||||
int connectorId = 0;
|
||||
|
||||
try
|
||||
{
|
||||
ClearedChargingLimitRequest clearedChargingLimitRequest = DeserializeMessage<ClearedChargingLimitRequest>(msgIn);
|
||||
Logger.LogTrace("ClearedChargingLimit => Message deserialized");
|
||||
|
||||
if (ChargePointStatus != null)
|
||||
{
|
||||
// Known charge station
|
||||
source = clearedChargingLimitRequest.ChargingLimitSource.ToString();
|
||||
connectorId = clearedChargingLimitRequest.EvseId;
|
||||
Logger.LogInformation("ClearedChargingLimit => Source={0}", source);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown charge station
|
||||
errorCode = ErrorCodes.GenericError;
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(clearedChargingLimitResponse);
|
||||
Logger.LogTrace("ClearedChargingLimit => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "ClearedChargingLimit => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus.Id, connectorId, msgIn.Action, source, errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
74
OCPP.Core.Server/ControllerOCPP20.DataTransfer.cs
Normal file
74
OCPP.Core.Server/ControllerOCPP20.DataTransfer.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public string HandleDataTransfer(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
DataTransferResponse dataTransferResponse = new DataTransferResponse();
|
||||
|
||||
bool msgWritten = false;
|
||||
|
||||
try
|
||||
{
|
||||
Logger.LogTrace("Processing data transfer...");
|
||||
DataTransferRequest dataTransferRequest = DeserializeMessage<DataTransferRequest>(msgIn);
|
||||
Logger.LogTrace("DataTransfer => Message deserialized");
|
||||
|
||||
if (ChargePointStatus != null)
|
||||
{
|
||||
// Known charge station
|
||||
msgWritten = WriteMessageLog(ChargePointStatus.Id, null, msgIn.Action, string.Format("VendorId={0} / MessageId={1} / Data={2}", dataTransferRequest.VendorId, dataTransferRequest.MessageId, dataTransferRequest.Data), errorCode);
|
||||
dataTransferResponse.Status = DataTransferStatusEnumType.Accepted;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown charge station
|
||||
errorCode = ErrorCodes.GenericError;
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(dataTransferResponse);
|
||||
Logger.LogTrace("DataTransfer => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "DataTransfer => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
|
||||
if (!msgWritten)
|
||||
{
|
||||
WriteMessageLog(ChargePointStatus.Id, null, msgIn.Action, null, errorCode);
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public string HandleFirmwareStatusNotification(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
|
||||
Logger.LogTrace("Processing FirmwareStatusNotification...");
|
||||
FirmwareStatusNotificationResponse firmwareStatusNotificationResponse = new FirmwareStatusNotificationResponse();
|
||||
firmwareStatusNotificationResponse.CustomData = new CustomDataType();
|
||||
firmwareStatusNotificationResponse.CustomData.VendorId = VendorId;
|
||||
|
||||
string status = null;
|
||||
|
||||
try
|
||||
{
|
||||
FirmwareStatusNotificationRequest firmwareStatusNotificationRequest = DeserializeMessage<FirmwareStatusNotificationRequest>(msgIn);
|
||||
Logger.LogTrace("FirmwareStatusNotification => Message deserialized");
|
||||
|
||||
|
||||
if (ChargePointStatus != null)
|
||||
{
|
||||
// Known charge station
|
||||
status = firmwareStatusNotificationRequest.Status.ToString();
|
||||
Logger.LogInformation("FirmwareStatusNotification => Status={0}", status);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown charge station
|
||||
errorCode = ErrorCodes.GenericError;
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(firmwareStatusNotificationResponse);
|
||||
Logger.LogTrace("FirmwareStatusNotification => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "FirmwareStatusNotification => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus.Id, null, msgIn.Action, status, errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
OCPP.Core.Server/ControllerOCPP20.Heartbeat.cs
Normal file
51
OCPP.Core.Server/ControllerOCPP20.Heartbeat.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public string HandleHeartBeat(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
|
||||
Logger.LogTrace("Processing heartbeat...");
|
||||
HeartbeatResponse heartbeatResponse = new HeartbeatResponse();
|
||||
heartbeatResponse.CustomData = new CustomDataType();
|
||||
heartbeatResponse.CustomData.VendorId = VendorId;
|
||||
|
||||
heartbeatResponse.CurrentTime = DateTimeOffset.UtcNow;
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(heartbeatResponse);
|
||||
Logger.LogTrace("Heartbeat => Response serialized");
|
||||
|
||||
WriteMessageLog(ChargePointStatus?.Id, null, msgIn.Action, null, errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
75
OCPP.Core.Server/ControllerOCPP20.LogStatusNotification.cs
Normal file
75
OCPP.Core.Server/ControllerOCPP20.LogStatusNotification.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public string HandleLogStatusNotification(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
|
||||
Logger.LogTrace("Processing LogStatusNotification...");
|
||||
LogStatusNotificationResponse logStatusNotificationResponse = new LogStatusNotificationResponse();
|
||||
logStatusNotificationResponse.CustomData = new CustomDataType();
|
||||
logStatusNotificationResponse.CustomData.VendorId = VendorId;
|
||||
|
||||
string status = null;
|
||||
|
||||
try
|
||||
{
|
||||
LogStatusNotificationRequest logStatusNotificationRequest = DeserializeMessage<LogStatusNotificationRequest>(msgIn);
|
||||
Logger.LogTrace("LogStatusNotification => Message deserialized");
|
||||
|
||||
|
||||
if (ChargePointStatus != null)
|
||||
{
|
||||
// Known charge station
|
||||
status = logStatusNotificationRequest.Status.ToString();
|
||||
Logger.LogInformation("LogStatusNotification => Status={0}", status);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown charge station
|
||||
errorCode = ErrorCodes.GenericError;
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(logStatusNotificationResponse);
|
||||
Logger.LogTrace("LogStatusNotification => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "LogStatusNotification => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus.Id, null, msgIn.Action, status, errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
117
OCPP.Core.Server/ControllerOCPP20.MeterValues.cs
Normal file
117
OCPP.Core.Server/ControllerOCPP20.MeterValues.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public string HandleMeterValues(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
MeterValuesResponse meterValuesResponse = new MeterValuesResponse();
|
||||
|
||||
meterValuesResponse.CustomData = new CustomDataType();
|
||||
meterValuesResponse.CustomData.VendorId = VendorId;
|
||||
|
||||
int connectorId = -1;
|
||||
string msgMeterValue = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
Logger.LogTrace("Processing meter values...");
|
||||
MeterValuesRequest meterValueRequest = DeserializeMessage<MeterValuesRequest>(msgIn);
|
||||
Logger.LogTrace("MeterValues => Message deserialized");
|
||||
|
||||
connectorId = meterValueRequest.EvseId;
|
||||
|
||||
if (ChargePointStatus != null)
|
||||
{
|
||||
// Known charge station => extract meter values with correct scale
|
||||
double currentChargeKW = -1;
|
||||
double meterKWH = -1;
|
||||
DateTimeOffset? meterTime = null;
|
||||
double stateOfCharge = -1;
|
||||
GetMeterValues(meterValueRequest.MeterValue, out meterKWH, out currentChargeKW, out stateOfCharge, out meterTime);
|
||||
|
||||
// write charging/meter data in chargepoint status
|
||||
if (connectorId > 0)
|
||||
{
|
||||
msgMeterValue = $"Meter (kWh): {meterKWH} | Charge (kW): {currentChargeKW} | SoC (%): {stateOfCharge}";
|
||||
|
||||
if (meterKWH >= 0)
|
||||
{
|
||||
UpdateConnectorStatus(connectorId, null, null, meterKWH, meterTime);
|
||||
}
|
||||
|
||||
if (currentChargeKW >= 0 || meterKWH >= 0 || stateOfCharge >= 0)
|
||||
{
|
||||
if (ChargePointStatus.OnlineConnectors.ContainsKey(connectorId))
|
||||
{
|
||||
OnlineConnectorStatus ocs = ChargePointStatus.OnlineConnectors[connectorId];
|
||||
if (currentChargeKW >= 0) ocs.ChargeRateKW = currentChargeKW;
|
||||
if (meterKWH >= 0) ocs.MeterKWH = meterKWH;
|
||||
if (stateOfCharge >= 0) ocs.SoC = stateOfCharge;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnlineConnectorStatus ocs = new OnlineConnectorStatus();
|
||||
if (currentChargeKW >= 0) ocs.ChargeRateKW = currentChargeKW;
|
||||
if (meterKWH >= 0) ocs.MeterKWH = meterKWH;
|
||||
if (stateOfCharge >= 0) ocs.SoC = stateOfCharge;
|
||||
if (ChargePointStatus.OnlineConnectors.TryAdd(connectorId, ocs))
|
||||
{
|
||||
Logger.LogTrace("MeterValues => Set OnlineConnectorStatus for ChargePoint={0} / Connector={1} / Values: {2}", ChargePointStatus?.Id, connectorId, msgMeterValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("MeterValues => Error adding new OnlineConnectorStatus for ChargePoint={0} / Connector={1} / Values: {2}", ChargePointStatus?.Id, connectorId, msgMeterValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown charge station
|
||||
errorCode = ErrorCodes.GenericError;
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(meterValuesResponse);
|
||||
Logger.LogTrace("MeterValues => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "MeterValues => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus.Id, connectorId, msgIn.Action, msgMeterValue, errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
102
OCPP.Core.Server/ControllerOCPP20.NotifyChargingLimit.cs
Normal file
102
OCPP.Core.Server/ControllerOCPP20.NotifyChargingLimit.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public string HandleNotifyChargingLimit(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
|
||||
Logger.LogTrace("Processing NotifyChargingLimit...");
|
||||
NotifyChargingLimitResponse notifyChargingLimitResponse = new NotifyChargingLimitResponse();
|
||||
notifyChargingLimitResponse.CustomData = new CustomDataType();
|
||||
notifyChargingLimitResponse.CustomData.VendorId = VendorId;
|
||||
|
||||
string source = null;
|
||||
StringBuilder periods = new StringBuilder();
|
||||
int connectorId = 0;
|
||||
|
||||
try
|
||||
{
|
||||
NotifyChargingLimitRequest notifyChargingLimitRequest = DeserializeMessage<NotifyChargingLimitRequest>(msgIn);
|
||||
Logger.LogTrace("NotifyChargingLimit => Message deserialized");
|
||||
|
||||
|
||||
if (ChargePointStatus != null)
|
||||
{
|
||||
// Known charge station
|
||||
source = notifyChargingLimitRequest.ChargingLimit?.ChargingLimitSource.ToString();
|
||||
if (notifyChargingLimitRequest.ChargingSchedule != null)
|
||||
{
|
||||
foreach (ChargingScheduleType schedule in notifyChargingLimitRequest.ChargingSchedule)
|
||||
{
|
||||
if (schedule.ChargingSchedulePeriod != null)
|
||||
{
|
||||
foreach (ChargingSchedulePeriodType period in schedule.ChargingSchedulePeriod)
|
||||
{
|
||||
if (periods.Length > 0)
|
||||
{
|
||||
periods.Append(" | ");
|
||||
}
|
||||
|
||||
periods.Append(string.Format("{0}s: {1}{2}", period.StartPeriod, period.Limit, schedule.ChargingRateUnit));
|
||||
|
||||
if (period.NumberPhases > 0)
|
||||
{
|
||||
periods.Append(string.Format(" ({0} Phases)", period.NumberPhases));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
connectorId = notifyChargingLimitRequest.EvseId;
|
||||
Logger.LogInformation("NotifyChargingLimit => {0}", periods);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown charge station
|
||||
errorCode = ErrorCodes.GenericError;
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(notifyChargingLimitResponse);
|
||||
Logger.LogTrace("NotifyChargingLimit => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "NotifyChargingLimit => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus.Id, connectorId, msgIn.Action, source, errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
101
OCPP.Core.Server/ControllerOCPP20.NotifyEVChargingSchedule.cs
Normal file
101
OCPP.Core.Server/ControllerOCPP20.NotifyEVChargingSchedule.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public string HandleNotifyEVChargingSchedule(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
|
||||
Logger.LogTrace("Processing NotifyEVChargingSchedule...");
|
||||
NotifyEVChargingScheduleResponse notifyEVChargingScheduleResponse = new NotifyEVChargingScheduleResponse();
|
||||
notifyEVChargingScheduleResponse.CustomData = new CustomDataType();
|
||||
notifyEVChargingScheduleResponse.CustomData.VendorId = VendorId;
|
||||
|
||||
StringBuilder periods = new StringBuilder();
|
||||
int connectorId = 0;
|
||||
|
||||
try
|
||||
{
|
||||
NotifyEVChargingScheduleRequest notifyEVChargingScheduleRequest = DeserializeMessage<NotifyEVChargingScheduleRequest>(msgIn);
|
||||
Logger.LogTrace("NotifyEVChargingSchedule => Message deserialized");
|
||||
|
||||
|
||||
if (ChargePointStatus != null)
|
||||
{
|
||||
// Known charge station
|
||||
if (notifyEVChargingScheduleRequest.ChargingSchedule != null)
|
||||
{
|
||||
if (notifyEVChargingScheduleRequest.ChargingSchedule?.ChargingSchedulePeriod != null)
|
||||
{
|
||||
// Concat all periods and write them in messag log...
|
||||
|
||||
DateTimeOffset timeBase = notifyEVChargingScheduleRequest.TimeBase;
|
||||
foreach (ChargingSchedulePeriodType period in notifyEVChargingScheduleRequest.ChargingSchedule?.ChargingSchedulePeriod)
|
||||
{
|
||||
if (periods.Length > 0)
|
||||
{
|
||||
periods.Append(" | ");
|
||||
}
|
||||
|
||||
DateTimeOffset time = timeBase.AddSeconds(period.StartPeriod);
|
||||
periods.Append(string.Format("{0}: {1}{2}", time.ToString("O"), period.Limit, notifyEVChargingScheduleRequest.ChargingSchedule.ChargingRateUnit.ToString()));
|
||||
|
||||
if (period.NumberPhases > 0)
|
||||
{
|
||||
periods.Append(string.Format(" ({0} Phases)", period.NumberPhases));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
connectorId = notifyEVChargingScheduleRequest.EvseId;
|
||||
Logger.LogInformation("NotifyEVChargingSchedule => {0}", periods.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown charge station
|
||||
errorCode = ErrorCodes.GenericError;
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(notifyEVChargingScheduleResponse);
|
||||
Logger.LogTrace("NotifyEVChargingSchedule => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "NotifyEVChargingSchedule => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus.Id, connectorId, msgIn.Action, periods.ToString(), errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
59
OCPP.Core.Server/ControllerOCPP20.Reset.cs
Normal file
59
OCPP.Core.Server/ControllerOCPP20.Reset.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public void HandleReset(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
Logger.LogInformation("Reset answer: ChargePointId={0} / MsgType={1} / ErrCode={2}", ChargePointStatus.Id, msgIn.MessageType, msgIn.ErrorCode);
|
||||
|
||||
try
|
||||
{
|
||||
ResetResponse resetResponse = DeserializeMessage<ResetResponse>(msgIn);
|
||||
Logger.LogInformation("Reset => Answer status: {0}", resetResponse?.Status);
|
||||
WriteMessageLog(ChargePointStatus?.Id, null, msgOut.Action, resetResponse?.Status.ToString(), msgIn.ErrorCode);
|
||||
|
||||
if (msgOut.TaskCompletionSource != null)
|
||||
{
|
||||
// Set API response as TaskCompletion-result
|
||||
string apiResult = "{\"status\": " + JsonConvert.ToString(resetResponse.Status.ToString()) + "}";
|
||||
Logger.LogTrace("HandleReset => API response: {0}" , apiResult);
|
||||
|
||||
msgOut.TaskCompletionSource.SetResult(apiResult);
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "HandleReset => Exception: {0}", exp.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
122
OCPP.Core.Server/ControllerOCPP20.StatusNotification.cs
Normal file
122
OCPP.Core.Server/ControllerOCPP20.StatusNotification.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public string HandleStatusNotification(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
StatusNotificationResponse statusNotificationResponse = new StatusNotificationResponse();
|
||||
|
||||
statusNotificationResponse.CustomData = new CustomDataType();
|
||||
statusNotificationResponse.CustomData.VendorId = VendorId;
|
||||
|
||||
int connectorId = 0;
|
||||
bool msgWritten = false;
|
||||
|
||||
try
|
||||
{
|
||||
Logger.LogTrace("Processing status notification...");
|
||||
StatusNotificationRequest statusNotificationRequest = DeserializeMessage<StatusNotificationRequest>(msgIn);
|
||||
Logger.LogTrace("StatusNotification => Message deserialized");
|
||||
|
||||
connectorId = statusNotificationRequest.ConnectorId;
|
||||
|
||||
// Write raw status in DB
|
||||
msgWritten = WriteMessageLog(ChargePointStatus.Id, connectorId, msgIn.Action, string.Format("Status={0}", statusNotificationRequest.ConnectorStatus), string.Empty);
|
||||
|
||||
ConnectorStatusEnum newStatus = ConnectorStatusEnum.Undefined;
|
||||
|
||||
switch (statusNotificationRequest.ConnectorStatus)
|
||||
{
|
||||
case ConnectorStatusEnumType.Available:
|
||||
newStatus = ConnectorStatusEnum.Available;
|
||||
break;
|
||||
case ConnectorStatusEnumType.Occupied:
|
||||
case ConnectorStatusEnumType.Reserved:
|
||||
newStatus = ConnectorStatusEnum.Occupied;
|
||||
break;
|
||||
case ConnectorStatusEnumType.Unavailable:
|
||||
newStatus = ConnectorStatusEnum.Unavailable;
|
||||
break;
|
||||
case ConnectorStatusEnumType.Faulted:
|
||||
newStatus = ConnectorStatusEnum.Faulted;
|
||||
break;
|
||||
}
|
||||
Logger.LogInformation("StatusNotification => ChargePoint={0} / Connector={1} / newStatus={2}", ChargePointStatus?.Id, connectorId, newStatus.ToString());
|
||||
|
||||
if (connectorId > 0)
|
||||
{
|
||||
if (UpdateConnectorStatus(connectorId, newStatus.ToString(), statusNotificationRequest.Timestamp, null, null) == false)
|
||||
{
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
|
||||
if (ChargePointStatus.OnlineConnectors.ContainsKey(connectorId))
|
||||
{
|
||||
OnlineConnectorStatus ocs = ChargePointStatus.OnlineConnectors[connectorId];
|
||||
ocs.Status = newStatus;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnlineConnectorStatus ocs = new OnlineConnectorStatus();
|
||||
ocs.Status = newStatus;
|
||||
if (ChargePointStatus.OnlineConnectors.TryAdd(connectorId, ocs))
|
||||
{
|
||||
Logger.LogTrace("StatusNotification => new OnlineConnectorStatus with values: ChargePoint={0} / Connector={1} / newStatus={2}", ChargePointStatus?.Id, connectorId, newStatus.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("StatusNotification => Error adding new OnlineConnectorStatus for ChargePoint={0} / Connector={1}", ChargePointStatus?.Id, connectorId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogWarning("StatusNotification => Status for unexpected ConnectorId={1} on ChargePoint={0}", ChargePointStatus?.Id, connectorId);
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(statusNotificationResponse);
|
||||
Logger.LogTrace("StatusNotification => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "StatusNotification => ChargePoint={0} / Exception: {1}", ChargePointStatus.Id, exp.Message);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
|
||||
if (!msgWritten)
|
||||
{
|
||||
WriteMessageLog(ChargePointStatus.Id, connectorId, msgIn.Action, null, errorCode);
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
401
OCPP.Core.Server/ControllerOCPP20.TransactionEvent.cs
Normal file
401
OCPP.Core.Server/ControllerOCPP20.TransactionEvent.cs
Normal file
@@ -0,0 +1,401 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public string HandleTransactionEvent(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
string errorCode = null;
|
||||
TransactionEventResponse transactionEventResponse = new TransactionEventResponse();
|
||||
transactionEventResponse.CustomData = new CustomDataType();
|
||||
transactionEventResponse.CustomData.VendorId = VendorId;
|
||||
transactionEventResponse.IdTokenInfo = new IdTokenInfoType();
|
||||
|
||||
int connectorId = 0;
|
||||
|
||||
try
|
||||
{
|
||||
Logger.LogTrace("TransactionEvent => Processing transactionEvent request...");
|
||||
TransactionEventRequest transactionEventRequest = DeserializeMessage<TransactionEventRequest>(msgIn);
|
||||
Logger.LogTrace("TransactionEvent => Message deserialized");
|
||||
|
||||
string idTag = CleanChargeTagId(transactionEventRequest.IdToken?.IdToken, Logger);
|
||||
connectorId = (transactionEventRequest.Evse != null) ? transactionEventRequest.Evse.ConnectorId : 0;
|
||||
|
||||
|
||||
// Extract meter values with correct scale
|
||||
double currentChargeKW = -1;
|
||||
double meterKWH = -1;
|
||||
DateTimeOffset? meterTime = null;
|
||||
double stateOfCharge = -1;
|
||||
GetMeterValues(transactionEventRequest.MeterValue, out meterKWH, out currentChargeKW, out stateOfCharge, out meterTime);
|
||||
|
||||
if (connectorId > 0 && meterKWH >= 0)
|
||||
{
|
||||
UpdateConnectorStatus(connectorId, null, null, meterKWH, meterTime);
|
||||
}
|
||||
|
||||
if (transactionEventRequest.EventType == TransactionEventEnumType.Started)
|
||||
{
|
||||
try
|
||||
{
|
||||
#region Start Transaction
|
||||
bool denyConcurrentTx = Configuration.GetValue<bool>("DenyConcurrentTx", false);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(idTag))
|
||||
{
|
||||
// no RFID-Tag => accept request
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Accepted;
|
||||
Logger.LogInformation("StartTransaction => no charge tag => accepted");
|
||||
}
|
||||
else
|
||||
{
|
||||
ChargeTag ct = DbContext.Find<ChargeTag>(idTag);
|
||||
if (ct != null)
|
||||
{
|
||||
if (ct.Blocked.HasValue && ct.Blocked.Value)
|
||||
{
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Blocked;
|
||||
}
|
||||
else if (ct.ExpiryDate.HasValue && ct.ExpiryDate.Value < DateTime.Now)
|
||||
{
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Expired;
|
||||
}
|
||||
else
|
||||
{
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Accepted;
|
||||
|
||||
if (denyConcurrentTx)
|
||||
{
|
||||
// Check that no open transaction with this idTag exists
|
||||
Transaction tx = DbContext.Transactions
|
||||
.Where(t => !t.StopTime.HasValue && t.StartTagId == idTag)
|
||||
.OrderByDescending(t => t.TransactionId)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (tx != null)
|
||||
{
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.ConcurrentTx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Unknown;
|
||||
}
|
||||
|
||||
Logger.LogInformation("StartTransaction => Charge tag='{0}' => Status: {1}", idTag, transactionEventResponse.IdTokenInfo.Status);
|
||||
|
||||
}
|
||||
|
||||
if (transactionEventResponse.IdTokenInfo.Status == AuthorizationStatusEnumType.Accepted)
|
||||
{
|
||||
UpdateConnectorStatus(connectorId, ConnectorStatusEnum.Occupied.ToString(), meterTime, null, null);
|
||||
|
||||
try
|
||||
{
|
||||
Logger.LogInformation("StartTransaction => Meter='{0}' (kWh)", meterKWH);
|
||||
|
||||
Transaction transaction = new Transaction();
|
||||
transaction.Uid = transactionEventRequest.TransactionInfo.TransactionId;
|
||||
transaction.ChargePointId = ChargePointStatus?.Id;
|
||||
transaction.ConnectorId = connectorId;
|
||||
transaction.StartTagId = idTag;
|
||||
transaction.StartTime = transactionEventRequest.Timestamp.UtcDateTime;
|
||||
transaction.MeterStart = meterKWH;
|
||||
transaction.StartResult = transactionEventRequest.TriggerReason.ToString();
|
||||
DbContext.Add<Transaction>(transaction);
|
||||
|
||||
DbContext.SaveChanges();
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "StartTransaction => Exception writing transaction: chargepoint={0} / tag={1}", ChargePointStatus?.Id, idTag);
|
||||
errorCode = ErrorCodes.InternalError;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "StartTransaction => Exception: {0}", exp.Message);
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Invalid;
|
||||
}
|
||||
}
|
||||
else if (transactionEventRequest.EventType == TransactionEventEnumType.Updated)
|
||||
{
|
||||
try
|
||||
{
|
||||
#region Update Transaction
|
||||
Transaction transaction = DbContext.Transactions
|
||||
.Where(t => t.Uid == transactionEventRequest.TransactionInfo.TransactionId)
|
||||
.OrderByDescending(t => t.TransactionId)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (transaction != null &&
|
||||
transaction.ChargePointId == ChargePointStatus.Id &&
|
||||
!transaction.StopTime.HasValue)
|
||||
{
|
||||
// write current meter value in "stop" value
|
||||
if (meterKWH >= 0)
|
||||
{
|
||||
Logger.LogInformation("UpdateTransaction => Meter='{0}' (kWh)", meterKWH);
|
||||
transaction.MeterStop = meterKWH;
|
||||
DbContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("UpdateTransaction => Unknown or not matching transaction: uid='{0}' / chargepoint='{1}' / tag={2}", transactionEventRequest.TransactionInfo?.TransactionId, ChargePointStatus?.Id, idTag);
|
||||
WriteMessageLog(ChargePointStatus?.Id, null, msgIn.Action, string.Format("UnknownTransaction:UID={0}/Meter={1}", transactionEventRequest.TransactionInfo?.TransactionId, GetMeterValue(transactionEventRequest.MeterValue)), errorCode);
|
||||
errorCode = ErrorCodes.PropertyConstraintViolation;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "UpdateTransaction => Exception: {0}", exp.Message);
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Invalid;
|
||||
}
|
||||
}
|
||||
else if (transactionEventRequest.EventType == TransactionEventEnumType.Ended)
|
||||
{
|
||||
try
|
||||
{
|
||||
#region End Transaction
|
||||
ChargeTag ct = null;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(idTag))
|
||||
{
|
||||
// no RFID-Tag => accept request
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Accepted;
|
||||
Logger.LogInformation("EndTransaction => no charge tag => accepted");
|
||||
}
|
||||
else
|
||||
{
|
||||
ct = DbContext.Find<ChargeTag>(idTag);
|
||||
if (ct != null)
|
||||
{
|
||||
if (ct.Blocked.HasValue && ct.Blocked.Value)
|
||||
{
|
||||
Logger.LogInformation("EndTransaction => Tag '{1}' blocked)", idTag);
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Blocked;
|
||||
}
|
||||
else if (ct.ExpiryDate.HasValue && ct.ExpiryDate.Value < DateTime.Now)
|
||||
{
|
||||
Logger.LogInformation("EndTransaction => Tag '{1}' expired)", idTag);
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Expired;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogInformation("EndTransaction => Tag '{1}' accepted)", idTag);
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Accepted;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogInformation("EndTransaction => Tag '{1}' unknown)", idTag);
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
Transaction transaction = DbContext.Transactions
|
||||
.Where(t => t.Uid == transactionEventRequest.TransactionInfo.TransactionId)
|
||||
.OrderByDescending(t => t.TransactionId)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (transaction != null &&
|
||||
transaction.ChargePointId == ChargePointStatus.Id &&
|
||||
!transaction.StopTime.HasValue)
|
||||
{
|
||||
// check current tag against start tag
|
||||
bool valid = true;
|
||||
if (!string.Equals(transaction.StartTagId, idTag, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
// tags are different => same group?
|
||||
ChargeTag startTag = DbContext.Find<ChargeTag>(transaction.StartTagId);
|
||||
if (startTag != null)
|
||||
{
|
||||
if (!string.Equals(startTag.ParentTagId, ct?.ParentTagId, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
Logger.LogInformation("EndTransaction => Start-Tag ('{0}') and End-Tag ('{1}') do not match: Invalid!", transaction.StartTagId, ct?.TagId);
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Invalid;
|
||||
valid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogInformation("EndTransaction => Different charge tags but matching group ('{0}')", ct?.ParentTagId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("EndTransaction => Start-Tag not found: '{0}'", transaction.StartTagId);
|
||||
// assume "valid" and allow to end the transaction
|
||||
}
|
||||
}
|
||||
|
||||
if (valid)
|
||||
{
|
||||
// write current meter value in "stop" value
|
||||
Logger.LogInformation("EndTransaction => Meter='{0}' (kWh)", meterKWH);
|
||||
|
||||
transaction.StopTime = transactionEventRequest.Timestamp.UtcDateTime;
|
||||
transaction.MeterStop = meterKWH;
|
||||
transaction.StopTagId = idTag;
|
||||
transaction.StopReason = transactionEventRequest.TriggerReason.ToString();
|
||||
DbContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("EndTransaction => Unknown or not matching transaction: uid='{0}' / chargepoint='{1}' / tag={2}", transactionEventRequest.TransactionInfo?.TransactionId, ChargePointStatus?.Id, idTag);
|
||||
WriteMessageLog(ChargePointStatus?.Id, connectorId, msgIn.Action, string.Format("UnknownTransaction:UID={0}/Meter={1}", transactionEventRequest.TransactionInfo?.TransactionId, GetMeterValue(transactionEventRequest.MeterValue)), errorCode);
|
||||
errorCode = ErrorCodes.PropertyConstraintViolation;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "EndTransaction => Exception: {0}", exp.Message);
|
||||
transactionEventResponse.IdTokenInfo.Status = AuthorizationStatusEnumType.Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
msgOut.JsonPayload = JsonConvert.SerializeObject(transactionEventResponse);
|
||||
Logger.LogTrace("TransactionEvent => Response serialized");
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "TransactionEvent => Exception: {0}", exp.Message);
|
||||
errorCode = ErrorCodes.FormationViolation;
|
||||
}
|
||||
|
||||
WriteMessageLog(ChargePointStatus?.Id, connectorId, msgIn.Action, transactionEventResponse.IdTokenInfo.Status.ToString(), errorCode);
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Extract main meter value from collection
|
||||
/// </summary>
|
||||
private double GetMeterValue(ICollection<MeterValueType> meterValues)
|
||||
{
|
||||
double currentChargeKW = -1;
|
||||
double meterKWH = -1;
|
||||
DateTimeOffset? meterTime = null;
|
||||
double stateOfCharge = -1;
|
||||
GetMeterValues(meterValues, out meterKWH, out currentChargeKW, out stateOfCharge, out meterTime);
|
||||
|
||||
return meterKWH;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract different meter values from collection
|
||||
/// </summary>
|
||||
private void GetMeterValues(ICollection<MeterValueType> meterValues, out double meterKWH, out double currentChargeKW, out double stateOfCharge, out DateTimeOffset? meterTime)
|
||||
{
|
||||
currentChargeKW = -1;
|
||||
meterKWH = -1;
|
||||
meterTime = null;
|
||||
stateOfCharge = -1;
|
||||
|
||||
foreach (MeterValueType meterValue in meterValues)
|
||||
{
|
||||
foreach (SampledValueType sampleValue in meterValue.SampledValue)
|
||||
{
|
||||
Logger.LogTrace("GetMeterValues => Context={0} / SignedMeterValue={1} / Value={2} / Unit={3} / Location={4} / Measurand={5} / Phase={6}",
|
||||
sampleValue.Context, sampleValue.SignedMeterValue, sampleValue.Value, sampleValue.UnitOfMeasure, sampleValue.Location, sampleValue.Measurand, sampleValue.Phase);
|
||||
|
||||
if (sampleValue.Measurand == MeasurandEnumType.Power_Active_Import)
|
||||
{
|
||||
// current charging power
|
||||
currentChargeKW = sampleValue.Value;
|
||||
if (sampleValue.UnitOfMeasure?.Unit == "W" ||
|
||||
sampleValue.UnitOfMeasure?.Unit == "VA" ||
|
||||
sampleValue.UnitOfMeasure?.Unit == "var" ||
|
||||
sampleValue.UnitOfMeasure?.Unit == null ||
|
||||
sampleValue.UnitOfMeasure == null)
|
||||
{
|
||||
Logger.LogTrace("GetMeterValues => Charging '{0:0.0}' W", currentChargeKW);
|
||||
// convert W => kW
|
||||
currentChargeKW = currentChargeKW / 1000;
|
||||
}
|
||||
else if (sampleValue.UnitOfMeasure?.Unit == "KW" ||
|
||||
sampleValue.UnitOfMeasure?.Unit == "kVA" ||
|
||||
sampleValue.UnitOfMeasure?.Unit == "kvar")
|
||||
{
|
||||
// already kW => OK
|
||||
Logger.LogTrace("GetMeterValues => Charging '{0:0.0}' kW", currentChargeKW);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogWarning("GetMeterValues => Charging: unexpected unit: '{0}' (Value={1})", sampleValue.UnitOfMeasure?.Unit, sampleValue.Value);
|
||||
}
|
||||
}
|
||||
else if (sampleValue.Measurand == MeasurandEnumType.Energy_Active_Import_Register ||
|
||||
sampleValue.Measurand == MeasurandEnumType.Missing) // Spec: Default=Energy_Active_Import_Register
|
||||
{
|
||||
// charged amount of energy
|
||||
meterKWH = sampleValue.Value;
|
||||
if (sampleValue.UnitOfMeasure?.Unit == "Wh" ||
|
||||
sampleValue.UnitOfMeasure?.Unit == "VAh" ||
|
||||
sampleValue.UnitOfMeasure?.Unit == "varh" ||
|
||||
(sampleValue.UnitOfMeasure == null || sampleValue.UnitOfMeasure.Unit == null))
|
||||
{
|
||||
Logger.LogTrace("GetMeterValues => Value: '{0:0.0}' Wh", meterKWH);
|
||||
// convert Wh => kWh
|
||||
meterKWH = meterKWH / 1000;
|
||||
}
|
||||
else if (sampleValue.UnitOfMeasure?.Unit == "kWh" ||
|
||||
sampleValue.UnitOfMeasure?.Unit == "kVAh" ||
|
||||
sampleValue.UnitOfMeasure?.Unit == "kvarh")
|
||||
{
|
||||
// already kWh => OK
|
||||
Logger.LogTrace("GetMeterValues => Value: '{0:0.0}' kWh", meterKWH);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogWarning("GetMeterValues => Value: unexpected unit: '{0}' (Value={1})", sampleValue.UnitOfMeasure?.Unit, sampleValue.Value);
|
||||
}
|
||||
meterTime = meterValue.Timestamp;
|
||||
}
|
||||
else if (sampleValue.Measurand == MeasurandEnumType.SoC)
|
||||
{
|
||||
// state of charge (battery status)
|
||||
stateOfCharge = sampleValue.Value;
|
||||
Logger.LogTrace("GetMeterValues => SoC: '{0:0.0}'%", stateOfCharge);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
59
OCPP.Core.Server/ControllerOCPP20.UnlockConnector.cs
Normal file
59
OCPP.Core.Server/ControllerOCPP20.UnlockConnector.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20
|
||||
{
|
||||
public void HandleUnlockConnector(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
Logger.LogInformation("UnlockConnector answer: ChargePointId={0} / MsgType={1} / ErrCode={2}", ChargePointStatus.Id, msgIn.MessageType, msgIn.ErrorCode);
|
||||
|
||||
try
|
||||
{
|
||||
UnlockConnectorResponse unlockConnectorResponse = DeserializeMessage<UnlockConnectorResponse>(msgIn);
|
||||
Logger.LogInformation("HandleUnlockConnector => Answer status: {0}", unlockConnectorResponse?.Status);
|
||||
WriteMessageLog(ChargePointStatus?.Id, null, msgOut.Action, unlockConnectorResponse?.Status.ToString(), msgIn.ErrorCode);
|
||||
|
||||
if (msgOut.TaskCompletionSource != null)
|
||||
{
|
||||
// Set API response as TaskCompletion-result
|
||||
string apiResult = "{\"status\": " + JsonConvert.ToString(unlockConnectorResponse.Status.ToString()) + "}";
|
||||
Logger.LogTrace("HandleUnlockConnector => API response: {0}", apiResult);
|
||||
|
||||
msgOut.TaskCompletionSource.SetResult(apiResult);
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "HandleUnlockConnector => Exception: {0}", exp.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
198
OCPP.Core.Server/ControllerOCPP20.cs
Normal file
198
OCPP.Core.Server/ControllerOCPP20.cs
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OCPP.Core.Database;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class ControllerOCPP20 : ControllerBase
|
||||
{
|
||||
public const string VendorId = "dallmann consulting GmbH";
|
||||
|
||||
/// <summary>
|
||||
/// Internal string for OCPP protocol version
|
||||
/// </summary>
|
||||
protected override string ProtocolVersion
|
||||
{
|
||||
get { return "20"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public ControllerOCPP20(IConfiguration config, ILoggerFactory loggerFactory, ChargePointStatus chargePointStatus, OCPPCoreContext dbContext) :
|
||||
base(config, loggerFactory, chargePointStatus, dbContext)
|
||||
{
|
||||
Logger = loggerFactory.CreateLogger(typeof(ControllerOCPP20));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes the charge point message and returns the answer message
|
||||
/// </summary>
|
||||
public OCPPMessage ProcessRequest(OCPPMessage msgIn)
|
||||
{
|
||||
OCPPMessage msgOut = new OCPPMessage();
|
||||
msgOut.MessageType = "3";
|
||||
msgOut.UniqueId = msgIn.UniqueId;
|
||||
|
||||
string errorCode = null;
|
||||
|
||||
if (msgIn.MessageType == "2")
|
||||
{
|
||||
switch (msgIn.Action)
|
||||
{
|
||||
case "BootNotification":
|
||||
errorCode = HandleBootNotification(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "Heartbeat":
|
||||
errorCode = HandleHeartBeat(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "Authorize":
|
||||
errorCode = HandleAuthorize(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "TransactionEvent":
|
||||
errorCode = HandleTransactionEvent(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "MeterValues":
|
||||
errorCode = HandleMeterValues(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "StatusNotification":
|
||||
errorCode = HandleStatusNotification(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "DataTransfer":
|
||||
errorCode = HandleDataTransfer(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "LogStatusNotification":
|
||||
errorCode = HandleLogStatusNotification(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "FirmwareStatusNotification":
|
||||
errorCode = HandleFirmwareStatusNotification(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "ClearedChargingLimit":
|
||||
errorCode = HandleClearedChargingLimit(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "NotifyChargingLimit":
|
||||
errorCode = HandleNotifyChargingLimit(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "NotifyEVChargingSchedule":
|
||||
errorCode = HandleNotifyEVChargingSchedule(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
default:
|
||||
errorCode = ErrorCodes.NotSupported;
|
||||
WriteMessageLog(ChargePointStatus.Id, null, msgIn.Action, msgIn.JsonPayload, errorCode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("ControllerOCPP20 => Protocol error: wrong message type '{0}'", msgIn.MessageType);
|
||||
errorCode = ErrorCodes.ProtocolError;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(errorCode))
|
||||
{
|
||||
// Inavlid message type => return type "4" (CALLERROR)
|
||||
msgOut.MessageType = "4";
|
||||
msgOut.ErrorCode = errorCode;
|
||||
Logger.LogDebug("ControllerOCPP20 => Return error code messge: ErrorCode={0}", errorCode);
|
||||
}
|
||||
|
||||
return msgOut;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes the charge point message and returns the answer message
|
||||
/// </summary>
|
||||
public void ProcessAnswer(OCPPMessage msgIn, OCPPMessage msgOut)
|
||||
{
|
||||
// The response (msgIn) has no action => check action in original request (msgOut)
|
||||
switch (msgOut.Action)
|
||||
{
|
||||
case "Reset":
|
||||
HandleReset(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
case "UnlockConnector":
|
||||
HandleUnlockConnector(msgIn, msgOut);
|
||||
break;
|
||||
|
||||
default:
|
||||
WriteMessageLog(ChargePointStatus.Id, null, msgIn.Action, msgIn.JsonPayload, "Unknown answer");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function for writing a log entry in database
|
||||
/// </summary>
|
||||
private bool WriteMessageLog(string chargePointId, int? connectorId, string message, string result, string errorCode)
|
||||
{
|
||||
try
|
||||
{
|
||||
int dbMessageLog = Configuration.GetValue<int>("DbMessageLog", 0);
|
||||
if (dbMessageLog > 0 && !string.IsNullOrWhiteSpace(chargePointId))
|
||||
{
|
||||
bool doLog = (dbMessageLog > 1 ||
|
||||
(message != "BootNotification" &&
|
||||
message != "Heartbeat" &&
|
||||
message != "DataTransfer" &&
|
||||
message != "StatusNotification"));
|
||||
|
||||
if (doLog)
|
||||
{
|
||||
MessageLog msgLog = new MessageLog();
|
||||
msgLog.ChargePointId = chargePointId;
|
||||
msgLog.ConnectorId = connectorId;
|
||||
msgLog.LogTime = DateTime.UtcNow;
|
||||
msgLog.Message = message;
|
||||
msgLog.Result = result;
|
||||
msgLog.ErrorCode = errorCode;
|
||||
DbContext.MessageLogs.Add(msgLog);
|
||||
Logger.LogTrace("MessageLog => Writing entry '{0}'", message);
|
||||
DbContext.SaveChanges();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
Logger.LogError(exp, "MessageLog => Error writing entry '{0}'", message);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
39
OCPP.Core.Server/Messages_OCPP16/AuthorizeRequest.cs
Normal file
39
OCPP.Core.Server/Messages_OCPP16/AuthorizeRequest.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class AuthorizeRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("idTag", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(20)]
|
||||
public string IdTag { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
76
OCPP.Core.Server/Messages_OCPP16/AuthorizeResponse.cs
Normal file
76
OCPP.Core.Server/Messages_OCPP16/AuthorizeResponse.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class AuthorizeResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("idTagInfo", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
public IdTagInfo IdTagInfo { get; set; } = new IdTagInfo();
|
||||
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class IdTagInfo
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("expiryDate", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public System.DateTimeOffset ExpiryDate { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("parentIdTag", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(20)]
|
||||
public string ParentIdTag { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public IdTagInfoStatus Status { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum IdTagInfoStatus
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Accepted")]
|
||||
Accepted = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Blocked")]
|
||||
Blocked = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Expired")]
|
||||
Expired = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Invalid")]
|
||||
Invalid = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ConcurrentTx")]
|
||||
ConcurrentTx = 4,
|
||||
|
||||
}
|
||||
}
|
||||
67
OCPP.Core.Server/Messages_OCPP16/BootNotificationRequest.cs
Normal file
67
OCPP.Core.Server/Messages_OCPP16/BootNotificationRequest.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class BootNotificationRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("chargePointVendor", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(20)]
|
||||
public string ChargePointVendor { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("chargePointModel", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(20)]
|
||||
public string ChargePointModel { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("chargePointSerialNumber", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(25)]
|
||||
public string ChargePointSerialNumber { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("chargeBoxSerialNumber", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(25)]
|
||||
public string ChargeBoxSerialNumber { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("firmwareVersion", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(50)]
|
||||
public string FirmwareVersion { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("iccid", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(20)]
|
||||
public string Iccid { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("imsi", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(20)]
|
||||
public string Imsi { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("meterType", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(25)]
|
||||
public string MeterType { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("meterSerialNumber", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(25)]
|
||||
public string MeterSerialNumber { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
55
OCPP.Core.Server/Messages_OCPP16/BootNotificationResponse.cs
Normal file
55
OCPP.Core.Server/Messages_OCPP16/BootNotificationResponse.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class BootNotificationResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public BootNotificationResponseStatus Status { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("currentTime", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset CurrentTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Heartbeat interval in seconds
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("interval", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int Interval { get; set; }
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum BootNotificationResponseStatus
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Accepted")]
|
||||
Accepted = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Pending")]
|
||||
Pending = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Rejected")]
|
||||
Rejected = 2,
|
||||
}
|
||||
}
|
||||
45
OCPP.Core.Server/Messages_OCPP16/DataTransferRequest.cs
Normal file
45
OCPP.Core.Server/Messages_OCPP16/DataTransferRequest.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class DataTransferRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("vendorId", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(255)]
|
||||
public string VendorId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("messageId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(50)]
|
||||
public string MessageId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("data", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public string Data { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
58
OCPP.Core.Server/Messages_OCPP16/DataTransferResponse.cs
Normal file
58
OCPP.Core.Server/Messages_OCPP16/DataTransferResponse.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class DataTransferResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public DataTransferResponseStatus Status { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("data", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public string Data { get; set; }
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum DataTransferResponseStatus
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Accepted")]
|
||||
Accepted = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Rejected")]
|
||||
Rejected = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"UnknownMessageId")]
|
||||
UnknownMessageId = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"UnknownVendorId")]
|
||||
UnknownVendorId = 3,
|
||||
|
||||
}
|
||||
}
|
||||
77
OCPP.Core.Server/Messages_OCPP16/ErrorCodes.cs
Normal file
77
OCPP.Core.Server/Messages_OCPP16/ErrorCodes.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
/// <summary>
|
||||
/// Defined OCPP error codes
|
||||
/// </summary>
|
||||
public class ErrorCodes
|
||||
{
|
||||
/// <summary>
|
||||
/// Requested Action is recognized but not supported by the receiver
|
||||
/// </summary>
|
||||
public static string NotSupported = "NotSupported";
|
||||
|
||||
/// <summary>
|
||||
/// InternalError An internal error occurred and the receiver was not able to process the requested Action successfully
|
||||
/// </summary>
|
||||
public static string InternalError = "InternalError";
|
||||
|
||||
/// <summary>
|
||||
/// Payload for Action is incomplete
|
||||
/// </summary>
|
||||
public static string ProtocolError = "ProtocolError";
|
||||
|
||||
/// <summary>
|
||||
/// During the processing of Action a security issue occurred preventing receiver from completing the Action successfully
|
||||
/// </summary>
|
||||
public static string SecurityError = "SecurityError";
|
||||
|
||||
/// <summary>
|
||||
/// Payload for Action is syntactically incorrect or not conform the PDU structure for Action
|
||||
/// </summary>
|
||||
public static string FormationViolation = "FormationViolation";
|
||||
|
||||
/// <summary>
|
||||
/// Payload is syntactically correct but at least one field contains an invalid value
|
||||
/// </summary>
|
||||
public static string PropertyConstraintViolation = "PropertyConstraintViolation";
|
||||
|
||||
/// <summary>
|
||||
/// Payload for Action is syntactically correct but at least one of the fields violates occurence constraints
|
||||
/// </summary>
|
||||
public static string OccurenceConstraintViolation = "OccurenceConstraintViolation";
|
||||
|
||||
/// <summary>
|
||||
/// Payload for Action is syntactically correct but at least one of the fields violates data type constraints(e.g. “somestring”: 12)
|
||||
/// </summary>
|
||||
public static string TypeConstraintViolation = "TypeConstraintViolation";
|
||||
|
||||
/// <summary>
|
||||
/// Any other error not covered by the previous ones
|
||||
/// </summary>
|
||||
public static string GenericError = "GenericError";
|
||||
}
|
||||
}
|
||||
29
OCPP.Core.Server/Messages_OCPP16/HeartbeatRequest.cs
Normal file
29
OCPP.Core.Server/Messages_OCPP16/HeartbeatRequest.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class HeartbeatRequest
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
31
OCPP.Core.Server/Messages_OCPP16/HeartbeatResponse.cs
Normal file
31
OCPP.Core.Server/Messages_OCPP16/HeartbeatResponse.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class HeartbeatResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("currentTime", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset CurrentTime { get; set; }
|
||||
}
|
||||
}
|
||||
56
OCPP.Core.Server/Messages_OCPP16/MeterValuesRequest.cs
Normal file
56
OCPP.Core.Server/Messages_OCPP16/MeterValuesRequest.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class MeterValuesRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("connectorId", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int ConnectorId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("transactionId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int TransactionId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("meterValue", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
public System.Collections.Generic.ICollection<MeterValue> MeterValue { get; set; } = new System.Collections.ObjectModel.Collection<MeterValue>();
|
||||
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class MeterValue
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("timestamp", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("sampledValue", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
public System.Collections.Generic.ICollection<SampledValue> SampledValue { get; set; } = new System.Collections.ObjectModel.Collection<SampledValue>();
|
||||
}
|
||||
}
|
||||
33
OCPP.Core.Server/Messages_OCPP16/MeterValuesResponse.cs
Normal file
33
OCPP.Core.Server/Messages_OCPP16/MeterValuesResponse.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class MeterValuesResponse
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
48
OCPP.Core.Server/Messages_OCPP16/ResetRequest.cs
Normal file
48
OCPP.Core.Server/Messages_OCPP16/ResetRequest.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class ResetRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public ResetRequestType Type { get; set; }
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum ResetRequestType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Hard")]
|
||||
Hard = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Soft")]
|
||||
Soft = 1,
|
||||
|
||||
}
|
||||
}
|
||||
47
OCPP.Core.Server/Messages_OCPP16/ResetResponse.cs
Normal file
47
OCPP.Core.Server/Messages_OCPP16/ResetResponse.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class ResetResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public ResetResponseStatus Status { get; set; }
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum ResetResponseStatus
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Accepted")]
|
||||
Accepted = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Rejected")]
|
||||
Rejected = 1,
|
||||
}
|
||||
}
|
||||
52
OCPP.Core.Server/Messages_OCPP16/StartTransactionRequest.cs
Normal file
52
OCPP.Core.Server/Messages_OCPP16/StartTransactionRequest.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class StartTransactionRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("connectorId", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int ConnectorId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("idTag", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(20)]
|
||||
public string IdTag { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("meterStart", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int MeterStart { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("reservationId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int ReservationId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("timestamp", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
39
OCPP.Core.Server/Messages_OCPP16/StartTransactionResponse.cs
Normal file
39
OCPP.Core.Server/Messages_OCPP16/StartTransactionResponse.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class StartTransactionResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("idTagInfo", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
public IdTagInfo IdTagInfo { get; set; } = new IdTagInfo();
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("transactionId", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int TransactionId { get; set; }
|
||||
}
|
||||
}
|
||||
147
OCPP.Core.Server/Messages_OCPP16/StatusNotificationRequest.cs
Normal file
147
OCPP.Core.Server/Messages_OCPP16/StatusNotificationRequest.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class StatusNotificationRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("connectorId", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int ConnectorId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("errorCode", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public StatusNotificationRequestErrorCode ErrorCode { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("info", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(50)]
|
||||
public string Info { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public StatusNotificationRequestStatus Status { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("timestamp", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public System.DateTimeOffset? Timestamp { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("vendorId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(255)]
|
||||
public string VendorId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("vendorErrorCode", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(50)]
|
||||
public string VendorErrorCode { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum StatusNotificationRequestErrorCode
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ConnectorLockFailure")]
|
||||
ConnectorLockFailure = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EVCommunicationError")]
|
||||
EVCommunicationError = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"GroundFailure")]
|
||||
GroundFailure = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"HighTemperature")]
|
||||
HighTemperature = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"InternalError")]
|
||||
InternalError = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"LocalListConflict")]
|
||||
LocalListConflict = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"NoError")]
|
||||
NoError = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"OtherError")]
|
||||
OtherError = 7,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"OverCurrentFailure")]
|
||||
OverCurrentFailure = 8,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"PowerMeterFailure")]
|
||||
PowerMeterFailure = 9,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"PowerSwitchFailure")]
|
||||
PowerSwitchFailure = 10,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ReaderFailure")]
|
||||
ReaderFailure = 11,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ResetFailure")]
|
||||
ResetFailure = 12,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"UnderVoltage")]
|
||||
UnderVoltage = 13,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"OverVoltage")]
|
||||
OverVoltage = 14,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"WeakSignal")]
|
||||
WeakSignal = 15,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum StatusNotificationRequestStatus
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Available")]
|
||||
Available = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Preparing")]
|
||||
Preparing = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Charging")]
|
||||
Charging = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SuspendedEVSE")]
|
||||
SuspendedEVSE = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SuspendedEV")]
|
||||
SuspendedEV = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Finishing")]
|
||||
Finishing = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Reserved")]
|
||||
Reserved = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Unavailable")]
|
||||
Unavailable = 7,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Faulted")]
|
||||
Faulted = 8,
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
public class StatusNotificationResponse
|
||||
{
|
||||
}
|
||||
}
|
||||
360
OCPP.Core.Server/Messages_OCPP16/StopTransactionRequest.cs
Normal file
360
OCPP.Core.Server/Messages_OCPP16/StopTransactionRequest.cs
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class StopTransactionRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("idTag", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(20)]
|
||||
public string IdTag { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("meterStop", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int MeterStop { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("timestamp", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("transactionId", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int TransactionId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("reason", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public StopTransactionRequestReason Reason { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("transactionData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public System.Collections.Generic.ICollection<TransactionData> TransactionData { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum StopTransactionRequestReason
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EmergencyStop")]
|
||||
EmergencyStop = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EVDisconnected")]
|
||||
EVDisconnected = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"HardReset")]
|
||||
HardReset = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Local")]
|
||||
Local = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Other")]
|
||||
Other = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"PowerLoss")]
|
||||
PowerLoss = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Reboot")]
|
||||
Reboot = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Remote")]
|
||||
Remote = 7,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SoftReset")]
|
||||
SoftReset = 8,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"UnlockCommand")]
|
||||
UnlockCommand = 9,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"DeAuthorized")]
|
||||
DeAuthorized = 10,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class TransactionData
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("timestamp", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("sampledValue", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
public System.Collections.Generic.ICollection<SampledValue> SampledValue { get; set; } = new System.Collections.ObjectModel.Collection<SampledValue>();
|
||||
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class SampledValue
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("value", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public string Value { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("context", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public SampledValueContext? Context { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("format", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public SampledValueFormat? Format { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("measurand", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public SampledValueMeasurand? Measurand { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("phase", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public SampledValuePhase? Phase { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("location", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public SampledValueLocation? Location { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("unit", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public SampledValueUnit? Unit { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum SampledValueContext
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Interruption.Begin")]
|
||||
Interruption_Begin = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Interruption.End")]
|
||||
Interruption_End = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Sample.Clock")]
|
||||
Sample_Clock = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Sample.Periodic")]
|
||||
Sample_Periodic = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Transaction.Begin")]
|
||||
Transaction_Begin = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Transaction.End")]
|
||||
Transaction_End = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Trigger")]
|
||||
Trigger = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Other")]
|
||||
Other = 7,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum SampledValueFormat
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Raw")]
|
||||
Raw = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SignedData")]
|
||||
SignedData = 1,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum SampledValueMeasurand
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Active.Export.Register")]
|
||||
Energy_Active_Export_Register = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Active.Import.Register")]
|
||||
Energy_Active_Import_Register = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Reactive.Export.Register")]
|
||||
Energy_Reactive_Export_Register = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Reactive.Import.Register")]
|
||||
Energy_Reactive_Import_Register = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Active.Export.Interval")]
|
||||
Energy_Active_Export_Interval = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Active.Import.Interval")]
|
||||
Energy_Active_Import_Interval = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Reactive.Export.Interval")]
|
||||
Energy_Reactive_Export_Interval = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Reactive.Import.Interval")]
|
||||
Energy_Reactive_Import_Interval = 7,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Power.Active.Export")]
|
||||
Power_Active_Export = 8,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Power.Active.Import")]
|
||||
Power_Active_Import = 9,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Power.Offered")]
|
||||
Power_Offered = 10,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Power.Reactive.Export")]
|
||||
Power_Reactive_Export = 11,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Power.Reactive.Import")]
|
||||
Power_Reactive_Import = 12,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Power.Factor")]
|
||||
Power_Factor = 13,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Current.Import")]
|
||||
Current_Import = 14,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Current.Export")]
|
||||
Current_Export = 15,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Current.Offered")]
|
||||
Current_Offered = 16,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Voltage")]
|
||||
Voltage = 17,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Frequency")]
|
||||
Frequency = 18,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Temperature")]
|
||||
Temperature = 19,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SoC")]
|
||||
SoC = 20,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"RPM")]
|
||||
RPM = 21,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum SampledValuePhase
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L1")]
|
||||
L1 = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L2")]
|
||||
L2 = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L3")]
|
||||
L3 = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"N")]
|
||||
N = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L1-N")]
|
||||
L1N = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L2-N")]
|
||||
L2N = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L3-N")]
|
||||
L3N = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L1-L2")]
|
||||
L1L2 = 7,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L2-L3")]
|
||||
L2L3 = 8,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L3-L1")]
|
||||
L3L1 = 9,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum SampledValueLocation
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Cable")]
|
||||
Cable = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EV")]
|
||||
EV = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Inlet")]
|
||||
Inlet = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Outlet")]
|
||||
Outlet = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Body")]
|
||||
Body = 4,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum SampledValueUnit
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Wh")]
|
||||
Wh = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"kWh")]
|
||||
KWh = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"varh")]
|
||||
Varh = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"kvarh")]
|
||||
Kvarh = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"W")]
|
||||
W = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"kW")]
|
||||
KW = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"VA")]
|
||||
VA = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"kVA")]
|
||||
KVA = 7,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"var")]
|
||||
Var = 8,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"kvar")]
|
||||
Kvar = 9,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"A")]
|
||||
A = 10,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"V")]
|
||||
V = 11,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"K")]
|
||||
K = 12,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Celcius")]
|
||||
Celcius = 13,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Fahrenheit")]
|
||||
Fahrenheit = 14,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Percent")]
|
||||
Percent = 15,
|
||||
|
||||
}
|
||||
}
|
||||
35
OCPP.Core.Server/Messages_OCPP16/StopTransactionResponse.cs
Normal file
35
OCPP.Core.Server/Messages_OCPP16/StopTransactionResponse.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class StopTransactionResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("idTagInfo", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public IdTagInfo IdTagInfo { get; set; }
|
||||
}
|
||||
}
|
||||
35
OCPP.Core.Server/Messages_OCPP16/UnlockConnectorRequest.cs
Normal file
35
OCPP.Core.Server/Messages_OCPP16/UnlockConnectorRequest.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class UnlockConnectorRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("connectorId", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int ConnectorId { get; set; }
|
||||
}
|
||||
}
|
||||
50
OCPP.Core.Server/Messages_OCPP16/UnlockConnectorResponse.cs
Normal file
50
OCPP.Core.Server/Messages_OCPP16/UnlockConnectorResponse.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP16
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class UnlockConnectorResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public UnlockConnectorResponseStatus Status { get; set; }
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum UnlockConnectorResponseStatus
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Unlocked")]
|
||||
Unlocked = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"UnlockFailed")]
|
||||
UnlockFailed = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"NotSupported")]
|
||||
NotSupported = 2
|
||||
}
|
||||
}
|
||||
112
OCPP.Core.Server/Messages_OCPP20/AuthorizeRequest.cs
Normal file
112
OCPP.Core.Server/Messages_OCPP20/AuthorizeRequest.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>Used algorithms for the hashes provided.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum HashAlgorithmEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SHA256")]
|
||||
SHA256 = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SHA384")]
|
||||
SHA384 = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SHA512")]
|
||||
SHA512 = 2,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class OCSPRequestDataType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("hashAlgorithm", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public HashAlgorithmEnumType HashAlgorithm { get; set; }
|
||||
|
||||
/// <summary>Hashed value of the Issuer DN (Distinguished Name).
|
||||
///
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("issuerNameHash", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(128)]
|
||||
public string IssuerNameHash { get; set; }
|
||||
|
||||
/// <summary>Hashed value of the issuers public key
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("issuerKeyHash", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(128)]
|
||||
public string IssuerKeyHash { get; set; }
|
||||
|
||||
/// <summary>The serial number of the certificate.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("serialNumber", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(40)]
|
||||
public string SerialNumber { get; set; }
|
||||
|
||||
/// <summary>This contains the responder URL (Case insensitive).
|
||||
///
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("responderURL", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(512)]
|
||||
public string ResponderURL { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class AuthorizeRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("idToken", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
public IdTokenType IdToken { get; set; } = new IdTokenType();
|
||||
|
||||
/// <summary>The X.509 certificated presented by EV and encoded in PEM format.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("certificate", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(5500)]
|
||||
public string Certificate { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("iso15118CertificateHashData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.MinLength(1)]
|
||||
[System.ComponentModel.DataAnnotations.MaxLength(4)]
|
||||
public System.Collections.Generic.ICollection<OCSPRequestDataType> Iso15118CertificateHashData { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
316
OCPP.Core.Server/Messages_OCPP20/AuthorizeResponse.cs
Normal file
316
OCPP.Core.Server/Messages_OCPP20/AuthorizeResponse.cs
Normal file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>ID_ Token. Status. Authorization_ Status
|
||||
/// urn:x-oca:ocpp:uid:1:569372
|
||||
/// Current status of the ID Token.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum AuthorizationStatusEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Accepted")]
|
||||
Accepted = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Blocked")]
|
||||
Blocked = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ConcurrentTx")]
|
||||
ConcurrentTx = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Expired")]
|
||||
Expired = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Invalid")]
|
||||
Invalid = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"NoCredit")]
|
||||
NoCredit = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"NotAllowedTypeEVSE")]
|
||||
NotAllowedTypeEVSE = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"NotAtThisLocation")]
|
||||
NotAtThisLocation = 7,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"NotAtThisTime")]
|
||||
NotAtThisTime = 8,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Unknown")]
|
||||
Unknown = 9,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Certificate status information.
|
||||
/// - if all certificates are valid: return 'Accepted'.
|
||||
/// - if one of the certificates was revoked, return 'CertificateRevoked'.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum AuthorizeCertificateStatusEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Accepted")]
|
||||
Accepted = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SignatureError")]
|
||||
SignatureError = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"CertificateExpired")]
|
||||
CertificateExpired = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"CertificateRevoked")]
|
||||
CertificateRevoked = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"NoCertificateAvailable")]
|
||||
NoCertificateAvailable = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"CertChainError")]
|
||||
CertChainError = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ContractCancelled")]
|
||||
ContractCancelled = 6,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Enumeration of possible idToken types.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum IdTokenEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Central")]
|
||||
Central = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"eMAID")]
|
||||
EMAID = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ISO14443")]
|
||||
ISO14443 = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ISO15693")]
|
||||
ISO15693 = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"KeyCode")]
|
||||
KeyCode = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Local")]
|
||||
Local = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"MacAddress")]
|
||||
MacAddress = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"NoAuthorization")]
|
||||
NoAuthorization = 7,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Message_ Content. Format. Message_ Format_ Code
|
||||
/// urn:x-enexis:ecdm:uid:1:570848
|
||||
/// Format of the message.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum MessageFormatEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ASCII")]
|
||||
ASCII = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"HTML")]
|
||||
HTML = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"URI")]
|
||||
URI = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"UTF8")]
|
||||
UTF8 = 3,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Contains a case insensitive identifier to use for the authorization and the type of authorization to support multiple forms of identifiers.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class AdditionalInfoType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>This field specifies the additional IdToken.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("additionalIdToken", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(36)]
|
||||
public string AdditionalIdToken { get; set; }
|
||||
|
||||
/// <summary>This defines the type of the additionalIdToken. This is a custom type, so the implementation needs to be agreed upon by all involved parties.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(50)]
|
||||
public string Type { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>ID_ Token
|
||||
/// urn:x-oca:ocpp:uid:2:233247
|
||||
/// Contains status information about an identifier.
|
||||
/// It is advised to not stop charging for a token that expires during charging, as ExpiryDate is only used for caching purposes. If ExpiryDate is not given, the status has no end date.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class IdTokenInfoType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public AuthorizationStatusEnumType Status { get; set; }
|
||||
|
||||
/// <summary>ID_ Token. Expiry. Date_ Time
|
||||
/// urn:x-oca:ocpp:uid:1:569373
|
||||
/// Date and Time after which the token must be considered invalid.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("cacheExpiryDateTime", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public System.DateTimeOffset CacheExpiryDateTime { get; set; }
|
||||
|
||||
/// <summary>Priority from a business point of view. Default priority is 0, The range is from -9 to 9. Higher values indicate a higher priority. The chargingPriority in &lt;&lt;transactioneventresponse,TransactionEventResponse&gt;&gt; overrules this one.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("chargingPriority", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int ChargingPriority { get; set; }
|
||||
|
||||
/// <summary>ID_ Token. Language1. Language_ Code
|
||||
/// urn:x-oca:ocpp:uid:1:569374
|
||||
/// Preferred user interface language of identifier user. Contains a language code as defined in &lt;&lt;ref-RFC5646,[RFC5646]&gt;&gt;.
|
||||
///
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("language1", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(8)]
|
||||
public string Language1 { get; set; }
|
||||
|
||||
/// <summary>Only used when the IdToken is only valid for one or more specific EVSEs, not for the entire Charging Station.
|
||||
///
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("evseId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.MinLength(1)]
|
||||
public System.Collections.Generic.ICollection<int> EvseId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("groupIdToken", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public IdTokenType GroupIdToken { get; set; }
|
||||
|
||||
/// <summary>ID_ Token. Language2. Language_ Code
|
||||
/// urn:x-oca:ocpp:uid:1:569375
|
||||
/// Second preferred user interface language of identifier user. Don’t use when language1 is omitted, has to be different from language1. Contains a language code as defined in &lt;&lt;ref-RFC5646,[RFC5646]&gt;&gt;.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("language2", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(8)]
|
||||
public string Language2 { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("personalMessage", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public MessageContentType PersonalMessage { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Contains a case insensitive identifier to use for the authorization and the type of authorization to support multiple forms of identifiers.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class IdTokenType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("additionalInfo", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.MinLength(1)]
|
||||
public System.Collections.Generic.ICollection<AdditionalInfoType> AdditionalInfo { get; set; }
|
||||
|
||||
/// <summary>IdToken is case insensitive. Might hold the hidden id of an RFID tag, but can for example also contain a UUID.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("idToken", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(36)]
|
||||
public string IdToken { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public IdTokenEnumType Type { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Message_ Content
|
||||
/// urn:x-enexis:ecdm:uid:2:234490
|
||||
/// Contains message details, for a message to be displayed on a Charging Station.
|
||||
///
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class MessageContentType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("format", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public MessageFormatEnumType Format { get; set; }
|
||||
|
||||
/// <summary>Message_ Content. Language. Language_ Code
|
||||
/// urn:x-enexis:ecdm:uid:1:570849
|
||||
/// Message language identifier. Contains a language code as defined in &lt;&lt;ref-RFC5646,[RFC5646]&gt;&gt;.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("language", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(8)]
|
||||
public string Language { get; set; }
|
||||
|
||||
/// <summary>Message_ Content. Content. Message
|
||||
/// urn:x-enexis:ecdm:uid:1:570852
|
||||
/// Message contents.
|
||||
///
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("content", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(512)]
|
||||
public string Content { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class AuthorizeResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("idTokenInfo", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
public IdTokenInfoType IdTokenInfo { get; set; } = new IdTokenInfoType();
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("certificateStatus", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public AuthorizeCertificateStatusEnumType CertificateStatus { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
172
OCPP.Core.Server/Messages_OCPP20/BootNotificationRequest.cs
Normal file
172
OCPP.Core.Server/Messages_OCPP20/BootNotificationRequest.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.</summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class CustomDataType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("vendorId", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(255)]
|
||||
public string VendorId { get; set; }
|
||||
|
||||
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
|
||||
|
||||
[Newtonsoft.Json.JsonExtensionData]
|
||||
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
|
||||
{
|
||||
get { return _additionalProperties; }
|
||||
set { _additionalProperties = value; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>This contains the reason for sending this message to the CSMS.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum BootReasonEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ApplicationReset")]
|
||||
ApplicationReset = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"FirmwareUpdate")]
|
||||
FirmwareUpdate = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"LocalReset")]
|
||||
LocalReset = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"PowerUp")]
|
||||
PowerUp = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"RemoteReset")]
|
||||
RemoteReset = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ScheduledReset")]
|
||||
ScheduledReset = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Triggered")]
|
||||
Triggered = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Unknown")]
|
||||
Unknown = 7,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Watchdog")]
|
||||
Watchdog = 8,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Charge_ Point
|
||||
/// urn:x-oca:ocpp:uid:2:233122
|
||||
/// The physical system where an Electrical Vehicle (EV) can be charged.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class ChargingStationType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Device. Serial_ Number. Serial_ Number
|
||||
/// urn:x-oca:ocpp:uid:1:569324
|
||||
/// Vendor-specific device identifier.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("serialNumber", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(25)]
|
||||
public string SerialNumber { get; set; }
|
||||
|
||||
/// <summary>Device. Model. CI20_ Text
|
||||
/// urn:x-oca:ocpp:uid:1:569325
|
||||
/// Defines the model of the device.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("model", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(20)]
|
||||
public string Model { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("modem", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public ModemType Modem { get; set; }
|
||||
|
||||
/// <summary>Identifies the vendor (not necessarily in a unique manner).
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("vendorName", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(50)]
|
||||
public string VendorName { get; set; }
|
||||
|
||||
/// <summary>This contains the firmware version of the Charging Station.
|
||||
///
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("firmwareVersion", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(50)]
|
||||
public string FirmwareVersion { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Wireless_ Communication_ Module
|
||||
/// urn:x-oca:ocpp:uid:2:233306
|
||||
/// Defines parameters required for initiating and maintaining wireless communication with other devices.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class ModemType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Wireless_ Communication_ Module. ICCID. CI20_ Text
|
||||
/// urn:x-oca:ocpp:uid:1:569327
|
||||
/// This contains the ICCID of the modem’s SIM card.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("iccid", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(20)]
|
||||
public string Iccid { get; set; }
|
||||
|
||||
/// <summary>Wireless_ Communication_ Module. IMSI. CI20_ Text
|
||||
/// urn:x-oca:ocpp:uid:1:569328
|
||||
/// This contains the IMSI of the modem’s SIM card.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("imsi", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(20)]
|
||||
public string Imsi { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class BootNotificationRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("chargingStation", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
public ChargingStationType ChargingStation { get; set; } = new ChargingStationType();
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("reason", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public BootReasonEnumType Reason { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
92
OCPP.Core.Server/Messages_OCPP20/BootNotificationResponse.cs
Normal file
92
OCPP.Core.Server/Messages_OCPP20/BootNotificationResponse.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>This contains whether the Charging Station has been registered
|
||||
/// within the CSMS.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum RegistrationStatusEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Accepted")]
|
||||
Accepted = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Pending")]
|
||||
Pending = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Rejected")]
|
||||
Rejected = 2,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Element providing more information about the status.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class StatusInfoType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>A predefined code for the reason why the status is returned in this response. The string is case-insensitive.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("reasonCode", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(20)]
|
||||
public string ReasonCode { get; set; }
|
||||
|
||||
/// <summary>Additional text to provide detailed information.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("additionalInfo", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(512)]
|
||||
public string AdditionalInfo { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class BootNotificationResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>This contains the CSMS’s current time.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("currentTime", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset CurrentTime { get; set; }
|
||||
|
||||
/// <summary>When &lt;&lt;cmn_registrationstatusenumtype,Status&gt;&gt; is Accepted, this contains the heartbeat interval in seconds. If the CSMS returns something other than Accepted, the value of the interval field indicates the minimum wait time before sending a next BootNotification request.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("interval", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int Interval { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public RegistrationStatusEnumType Status { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("statusInfo", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public StatusInfoType StatusInfo { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>Source of the charging limit.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum ChargingLimitSourceEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EMS")]
|
||||
EMS = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Other")]
|
||||
Other = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SO")]
|
||||
SO = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"CSO")]
|
||||
CSO = 3,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class ClearedChargingLimitRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("chargingLimitSource", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public ChargingLimitSourceEnumType ChargingLimitSource { get; set; }
|
||||
|
||||
/// <summary>EVSE Identifier.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("evseId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int EvseId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class ClearedChargingLimitResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
}
|
||||
}
|
||||
54
OCPP.Core.Server/Messages_OCPP20/DataTransferRequest.cs
Normal file
54
OCPP.Core.Server/Messages_OCPP20/DataTransferRequest.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class DataTransferRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>May be used to indicate a specific message or implementation.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("messageId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(50)]
|
||||
public string MessageId { get; set; }
|
||||
|
||||
/// <summary>Data without specified length or format. This needs to be decided by both parties (Open to implementation).
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("data", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public object Data { get; set; }
|
||||
|
||||
/// <summary>This identifies the Vendor specific implementation
|
||||
///
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("vendorId", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(255)]
|
||||
public string VendorId { get; set; }
|
||||
}
|
||||
}
|
||||
67
OCPP.Core.Server/Messages_OCPP20/DataTransferResponse.cs
Normal file
67
OCPP.Core.Server/Messages_OCPP20/DataTransferResponse.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>This indicates the success or failure of the data transfer.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum DataTransferStatusEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Accepted")]
|
||||
Accepted = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Rejected")]
|
||||
Rejected = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"UnknownMessageId")]
|
||||
UnknownMessageId = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"UnknownVendorId")]
|
||||
UnknownVendorId = 3
|
||||
}
|
||||
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class DataTransferResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public DataTransferStatusEnumType Status { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("statusInfo", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public StatusInfoType StatusInfo { get; set; }
|
||||
|
||||
/// <summary>Data without specified length or format, in response to request.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("data", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public object Data { get; set; }
|
||||
}
|
||||
}
|
||||
77
OCPP.Core.Server/Messages_OCPP20/ErrorCodes.cs
Normal file
77
OCPP.Core.Server/Messages_OCPP20/ErrorCodes.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
/// <summary>
|
||||
/// Defined OCPP error codes
|
||||
/// </summary>
|
||||
public class ErrorCodes
|
||||
{
|
||||
/// <summary>
|
||||
/// Requested Action is recognized but not supported by the receiver
|
||||
/// </summary>
|
||||
public static string NotSupported = "NotSupported";
|
||||
|
||||
/// <summary>
|
||||
/// InternalError An internal error occurred and the receiver was not able to process the requested Action successfully
|
||||
/// </summary>
|
||||
public static string InternalError = "InternalError";
|
||||
|
||||
/// <summary>
|
||||
/// Payload for Action is incomplete
|
||||
/// </summary>
|
||||
public static string ProtocolError = "ProtocolError";
|
||||
|
||||
/// <summary>
|
||||
/// During the processing of Action a security issue occurred preventing receiver from completing the Action successfully
|
||||
/// </summary>
|
||||
public static string SecurityError = "SecurityError";
|
||||
|
||||
/// <summary>
|
||||
/// Payload for Action is syntactically incorrect or not conform the PDU structure for Action
|
||||
/// </summary>
|
||||
public static string FormationViolation = "FormationViolation";
|
||||
|
||||
/// <summary>
|
||||
/// Payload is syntactically correct but at least one field contains an invalid value
|
||||
/// </summary>
|
||||
public static string PropertyConstraintViolation = "PropertyConstraintViolation";
|
||||
|
||||
/// <summary>
|
||||
/// Payload for Action is syntactically correct but at least one of the fields violates occurence constraints
|
||||
/// </summary>
|
||||
public static string OccurenceConstraintViolation = "OccurenceConstraintViolation";
|
||||
|
||||
/// <summary>
|
||||
/// Payload for Action is syntactically correct but at least one of the fields violates data type constraints(e.g. “somestring”: 12)
|
||||
/// </summary>
|
||||
public static string TypeConstraintViolation = "TypeConstraintViolation";
|
||||
|
||||
/// <summary>
|
||||
/// Any other error not covered by the previous ones
|
||||
/// </summary>
|
||||
public static string GenericError = "GenericError";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>This contains the progress status of the firmware installation.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum FirmwareStatusEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Downloaded")]
|
||||
Downloaded = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"DownloadFailed")]
|
||||
DownloadFailed = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Downloading")]
|
||||
Downloading = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"DownloadScheduled")]
|
||||
DownloadScheduled = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"DownloadPaused")]
|
||||
DownloadPaused = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Idle")]
|
||||
Idle = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"InstallationFailed")]
|
||||
InstallationFailed = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Installing")]
|
||||
Installing = 7,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Installed")]
|
||||
Installed = 8,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"InstallRebooting")]
|
||||
InstallRebooting = 9,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"InstallScheduled")]
|
||||
InstallScheduled = 10,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"InstallVerificationFailed")]
|
||||
InstallVerificationFailed = 11,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"InvalidSignature")]
|
||||
InvalidSignature = 12,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SignatureVerified")]
|
||||
SignatureVerified = 13,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class FirmwareStatusNotificationRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public FirmwareStatusEnumType Status { get; set; }
|
||||
|
||||
/// <summary>The request id that was provided in the
|
||||
/// UpdateFirmwareRequest that started this firmware update.
|
||||
/// This field is mandatory, unless the message was triggered by a TriggerMessageRequest AND there is no firmware update ongoing.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("requestId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int RequestId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class FirmwareStatusNotificationResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
}
|
||||
}
|
||||
30
OCPP.Core.Server/Messages_OCPP20/HeartbeatRequest.cs
Normal file
30
OCPP.Core.Server/Messages_OCPP20/HeartbeatRequest.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class HeartbeatRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
}
|
||||
}
|
||||
36
OCPP.Core.Server/Messages_OCPP20/HeartbeatResponse.cs
Normal file
36
OCPP.Core.Server/Messages_OCPP20/HeartbeatResponse.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class HeartbeatResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Contains the current time of the CSMS.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("currentTime", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset CurrentTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>This contains the status of the log upload.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum UploadLogStatusEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"BadMessage")]
|
||||
BadMessage = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Idle")]
|
||||
Idle = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"NotSupportedOperation")]
|
||||
NotSupportedOperation = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"PermissionDenied")]
|
||||
PermissionDenied = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Uploaded")]
|
||||
Uploaded = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"UploadFailure")]
|
||||
UploadFailure = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Uploading")]
|
||||
Uploading = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"AcceptedCanceled")]
|
||||
AcceptedCanceled = 7,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class LogStatusNotificationRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public UploadLogStatusEnumType Status { get; set; }
|
||||
|
||||
/// <summary>The request id that was provided in GetLogRequest that started this log upload. This field is mandatory,
|
||||
/// unless the message was triggered by a TriggerMessageRequest AND there is no log upload ongoing.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("requestId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int RequestId { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class LogStatusNotificationResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
}
|
||||
}
|
||||
368
OCPP.Core.Server/Messages_OCPP20/MeterValuesRequest.cs
Normal file
368
OCPP.Core.Server/Messages_OCPP20/MeterValuesRequest.cs
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>Sampled_ Value. Location. Location_ Code
|
||||
/// urn:x-oca:ocpp:uid:1:569265
|
||||
/// Indicates where the measured value has been sampled. Default = "Outlet"
|
||||
///
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum LocationEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Body")]
|
||||
Body = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Cable")]
|
||||
Cable = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EV")]
|
||||
EV = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Inlet")]
|
||||
Inlet = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Outlet")]
|
||||
Outlet = 4,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Sampled_ Value. Measurand. Measurand_ Code
|
||||
/// urn:x-oca:ocpp:uid:1:569263
|
||||
/// Type of measurement. Default = "Energy.Active.Import.Register"
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum MeasurandEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"")]
|
||||
Missing,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Current.Export")]
|
||||
Current_Export,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Current.Import")]
|
||||
Current_Import,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Current.Offered")]
|
||||
Current_Offered,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Active.Export.Register")]
|
||||
Energy_Active_Export_Register,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Active.Import.Register")]
|
||||
Energy_Active_Import_Register,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Reactive.Export.Register")]
|
||||
Energy_Reactive_Export_Register,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Reactive.Import.Register")]
|
||||
Energy_Reactive_Import_Register,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Active.Export.Interval")]
|
||||
Energy_Active_Export_Interval,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Active.Import.Interval")]
|
||||
Energy_Active_Import_Interval,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Active.Net")]
|
||||
Energy_Active_Net,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Reactive.Export.Interval")]
|
||||
Energy_Reactive_Export_Interval,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Reactive.Import.Interval")]
|
||||
Energy_Reactive_Import_Interval,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Reactive.Net")]
|
||||
Energy_Reactive_Net,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Apparent.Net")]
|
||||
Energy_Apparent_Net,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Apparent.Import")]
|
||||
Energy_Apparent_Import,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Energy.Apparent.Export")]
|
||||
Energy_Apparent_Export,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Frequency")]
|
||||
Frequency,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Power.Active.Export")]
|
||||
Power_Active_Export,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Power.Active.Import")]
|
||||
Power_Active_Import,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Power.Factor")]
|
||||
Power_Factor,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Power.Offered")]
|
||||
Power_Offered,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Power.Reactive.Export")]
|
||||
Power_Reactive_Export,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Power.Reactive.Import")]
|
||||
Power_Reactive_Import,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SoC")]
|
||||
SoC,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Voltage")]
|
||||
Voltage
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Sampled_ Value. Phase. Phase_ Code
|
||||
/// urn:x-oca:ocpp:uid:1:569264
|
||||
/// Indicates how the measured value is to be interpreted. For instance between L1 and neutral (L1-N) Please note that not all values of phase are applicable to all Measurands. When phase is absent, the measured value is interpreted as an overall value.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum PhaseEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L1")]
|
||||
L1 = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L2")]
|
||||
L2 = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L3")]
|
||||
L3 = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"N")]
|
||||
N = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L1-N")]
|
||||
L1N = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L2-N")]
|
||||
L2N = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L3-N")]
|
||||
L3N = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L1-L2")]
|
||||
L1L2 = 7,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L2-L3")]
|
||||
L2L3 = 8,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"L3-L1")]
|
||||
L3L1 = 9,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Sampled_ Value. Context. Reading_ Context_ Code
|
||||
/// urn:x-oca:ocpp:uid:1:569261
|
||||
/// Type of detail value: start, end or sample. Default = "Sample.Periodic"
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum ReadingContextEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Interruption.Begin")]
|
||||
Interruption_Begin = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Interruption.End")]
|
||||
Interruption_End = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Other")]
|
||||
Other = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Sample.Clock")]
|
||||
Sample_Clock = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Sample.Periodic")]
|
||||
Sample_Periodic = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Transaction.Begin")]
|
||||
Transaction_Begin = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Transaction.End")]
|
||||
Transaction_End = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Trigger")]
|
||||
Trigger = 7,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Meter_ Value
|
||||
/// urn:x-oca:ocpp:uid:2:233265
|
||||
/// Collection of one or more sampled values in MeterValuesRequest and TransactionEvent. All sampled values in a MeterValue are sampled at the same point in time.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class MeterValueType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("sampledValue", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
[System.ComponentModel.DataAnnotations.MinLength(1)]
|
||||
public System.Collections.Generic.ICollection<SampledValueType> SampledValue { get; set; } = new System.Collections.ObjectModel.Collection<SampledValueType>();
|
||||
|
||||
/// <summary>Meter_ Value. Timestamp. Date_ Time
|
||||
/// urn:x-oca:ocpp:uid:1:569259
|
||||
/// Timestamp for measured value(s).
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("timestamp", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Sampled_ Value
|
||||
/// urn:x-oca:ocpp:uid:2:233266
|
||||
/// Single sampled value in MeterValues. Each value can be accompanied by optional fields.
|
||||
///
|
||||
/// To save on mobile data usage, default values of all of the optional fields are such that. The value without any additional fields will be interpreted, as a register reading of active import energy in Wh (Watt-hour) units.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class SampledValueType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Sampled_ Value. Value. Measure
|
||||
/// urn:x-oca:ocpp:uid:1:569260
|
||||
/// Indicates the measured value.
|
||||
///
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("value", Required = Newtonsoft.Json.Required.Always)]
|
||||
public double Value { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("context", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public ReadingContextEnumType Context { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("measurand", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public MeasurandEnumType Measurand { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("phase", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public PhaseEnumType Phase { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("location", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public LocationEnumType Location { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("signedMeterValue", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public SignedMeterValueType SignedMeterValue { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("unitOfMeasure", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public UnitOfMeasureType UnitOfMeasure { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Represent a signed version of the meter value.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class SignedMeterValueType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Base64 encoded, contains the signed data which might contain more then just the meter value. It can contain information like timestamps, reference to a customer etc.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("signedMeterData", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(2500)]
|
||||
public string SignedMeterData { get; set; }
|
||||
|
||||
/// <summary>Method used to create the digital signature.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("signingMethod", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(50)]
|
||||
public string SigningMethod { get; set; }
|
||||
|
||||
/// <summary>Method used to encode the meter values before applying the digital signature algorithm.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("encodingMethod", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(50)]
|
||||
public string EncodingMethod { get; set; }
|
||||
|
||||
/// <summary>Base64 encoded, sending depends on configuration variable _PublicKeyWithSignedMeterValue_.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("publicKey", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(2500)]
|
||||
public string PublicKey { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Represents a UnitOfMeasure with a multiplier
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class UnitOfMeasureType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Unit of the value. Default = "Wh" if the (default) measurand is an "Energy" type.
|
||||
/// This field SHALL use a value from the list Standardized Units of Measurements in Part 2 Appendices.
|
||||
/// If an applicable unit is available in that list, otherwise a "custom" unit might be used.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("unit", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(20)]
|
||||
public string Unit { get; set; } = "Wh";
|
||||
|
||||
/// <summary>Multiplier, this value represents the exponent to base 10. I.e. multiplier 3 means 10 raised to the 3rd power. Default is 0.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("multiplier", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int Multiplier { get; set; } = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Request_ Body
|
||||
/// urn:x-enexis:ecdm:uid:2:234744
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class MeterValuesRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Request_ Body. EVSEID. Numeric_ Identifier
|
||||
/// urn:x-enexis:ecdm:uid:1:571101
|
||||
/// This contains a number (&gt;0) designating an EVSE of the Charging Station. ‘0’ (zero) is used to designate the main power meter.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("evseId", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int EvseId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("meterValue", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
[System.ComponentModel.DataAnnotations.MinLength(1)]
|
||||
public System.Collections.Generic.ICollection<MeterValueType> MeterValue { get; set; } = new System.Collections.ObjectModel.Collection<MeterValueType>();
|
||||
}
|
||||
}
|
||||
35
OCPP.Core.Server/Messages_OCPP20/MeterValuesResponse.cs
Normal file
35
OCPP.Core.Server/Messages_OCPP20/MeterValuesResponse.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class MeterValuesResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
}
|
||||
}
|
||||
338
OCPP.Core.Server/Messages_OCPP20/NotifyChargingLimitRequest.cs
Normal file
338
OCPP.Core.Server/Messages_OCPP20/NotifyChargingLimitRequest.cs
Normal file
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>Charging_ Schedule. Charging_ Rate_ Unit. Charging_ Rate_ Unit_ Code
|
||||
/// urn:x-oca:ocpp:uid:1:569238
|
||||
/// The unit of measure Limit is expressed in.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum ChargingRateUnitEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"W")]
|
||||
W = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"A")]
|
||||
A = 1,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Cost. Cost_ Kind. Cost_ Kind_ Code
|
||||
/// urn:x-oca:ocpp:uid:1:569243
|
||||
/// The kind of cost referred to in the message element amount
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum CostKindEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"CarbonDioxideEmission")]
|
||||
CarbonDioxideEmission = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"RelativePricePercentage")]
|
||||
RelativePricePercentage = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"RenewableGenerationPercentage")]
|
||||
RenewableGenerationPercentage = 2,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Charging_ Limit
|
||||
/// urn:x-enexis:ecdm:uid:2:234489
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class ChargingLimitType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("chargingLimitSource", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public ChargingLimitSourceEnumType ChargingLimitSource { get; set; }
|
||||
|
||||
/// <summary>Charging_ Limit. Is_ Grid_ Critical. Indicator
|
||||
/// urn:x-enexis:ecdm:uid:1:570847
|
||||
/// Indicates whether the charging limit is critical for the grid.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("isGridCritical", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public bool IsGridCritical { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Charging_ Schedule_ Period
|
||||
/// urn:x-oca:ocpp:uid:2:233257
|
||||
/// Charging schedule period structure defines a time period in a charging schedule.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class ChargingSchedulePeriodType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Charging_ Schedule_ Period. Start_ Period. Elapsed_ Time
|
||||
/// urn:x-oca:ocpp:uid:1:569240
|
||||
/// Start of the period, in seconds from the start of schedule. The value of StartPeriod also defines the stop time of the previous period.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("startPeriod", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int StartPeriod { get; set; }
|
||||
|
||||
/// <summary>Charging_ Schedule_ Period. Limit. Measure
|
||||
/// urn:x-oca:ocpp:uid:1:569241
|
||||
/// Charging rate limit during the schedule period, in the applicable chargingRateUnit, for example in Amperes (A) or Watts (W). Accepts at most one digit fraction (e.g. 8.1).
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("limit", Required = Newtonsoft.Json.Required.Always)]
|
||||
public double Limit { get; set; }
|
||||
|
||||
/// <summary>Charging_ Schedule_ Period. Number_ Phases. Counter
|
||||
/// urn:x-oca:ocpp:uid:1:569242
|
||||
/// The number of phases that can be used for charging. If a number of phases is needed, numberPhases=3 will be assumed unless another number is given.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("numberPhases", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int NumberPhases { get; set; }
|
||||
|
||||
/// <summary>Values: 1..3, Used if numberPhases=1 and if the EVSE is capable of switching the phase connected to the EV, i.e. ACPhaseSwitchingSupported is defined and true. It’s not allowed unless both conditions above are true. If both conditions are true, and phaseToUse is omitted, the Charging Station / EVSE will make the selection on its own.
|
||||
///
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("phaseToUse", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int PhaseToUse { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Charging_ Schedule
|
||||
/// urn:x-oca:ocpp:uid:2:233256
|
||||
/// Charging schedule structure defines a list of charging periods, as used in: GetCompositeSchedule.conf and ChargingProfile.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class ChargingScheduleType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Identifies the ChargingSchedule.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>Charging_ Schedule. Start_ Schedule. Date_ Time
|
||||
/// urn:x-oca:ocpp:uid:1:569237
|
||||
/// Starting point of an absolute schedule. If absent the schedule will be relative to start of charging.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("startSchedule", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public System.DateTimeOffset StartSchedule { get; set; }
|
||||
|
||||
/// <summary>Charging_ Schedule. Duration. Elapsed_ Time
|
||||
/// urn:x-oca:ocpp:uid:1:569236
|
||||
/// Duration of the charging schedule in seconds. If the duration is left empty, the last period will continue indefinitely or until end of the transaction if chargingProfilePurpose = TxProfile.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("duration", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int Duration { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("chargingRateUnit", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public ChargingRateUnitEnumType ChargingRateUnit { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("chargingSchedulePeriod", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
[System.ComponentModel.DataAnnotations.MinLength(1)]
|
||||
[System.ComponentModel.DataAnnotations.MaxLength(1024)]
|
||||
public System.Collections.Generic.ICollection<ChargingSchedulePeriodType> ChargingSchedulePeriod { get; set; } = new System.Collections.ObjectModel.Collection<ChargingSchedulePeriodType>();
|
||||
|
||||
/// <summary>Charging_ Schedule. Min_ Charging_ Rate. Numeric
|
||||
/// urn:x-oca:ocpp:uid:1:569239
|
||||
/// Minimum charging rate supported by the EV. The unit of measure is defined by the chargingRateUnit. This parameter is intended to be used by a local smart charging algorithm to optimize the power allocation for in the case a charging process is inefficient at lower charging rates. Accepts at most one digit fraction (e.g. 8.1)
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("minChargingRate", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public double MinChargingRate { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("salesTariff", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public SalesTariffType SalesTariff { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Consumption_ Cost
|
||||
/// urn:x-oca:ocpp:uid:2:233259
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class ConsumptionCostType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Consumption_ Cost. Start_ Value. Numeric
|
||||
/// urn:x-oca:ocpp:uid:1:569246
|
||||
/// The lowest level of consumption that defines the starting point of this consumption block. The block interval extends to the start of the next interval.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("startValue", Required = Newtonsoft.Json.Required.Always)]
|
||||
public double StartValue { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("cost", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
[System.ComponentModel.DataAnnotations.MinLength(1)]
|
||||
[System.ComponentModel.DataAnnotations.MaxLength(3)]
|
||||
public System.Collections.Generic.ICollection<CostType> Cost { get; set; } = new System.Collections.ObjectModel.Collection<CostType>();
|
||||
}
|
||||
|
||||
/// <summary>Cost
|
||||
/// urn:x-oca:ocpp:uid:2:233258
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class CostType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("costKind", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public CostKindEnumType CostKind { get; set; }
|
||||
|
||||
/// <summary>Cost. Amount. Amount
|
||||
/// urn:x-oca:ocpp:uid:1:569244
|
||||
/// The estimated or actual cost per kWh
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("amount", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int Amount { get; set; }
|
||||
|
||||
/// <summary>Cost. Amount_ Multiplier. Integer
|
||||
/// urn:x-oca:ocpp:uid:1:569245
|
||||
/// Values: -3..3, The amountMultiplier defines the exponent to base 10 (dec). The final value is determined by: amount * 10 ^ amountMultiplier
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("amountMultiplier", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int AmountMultiplier { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Relative_ Timer_ Interval
|
||||
/// urn:x-oca:ocpp:uid:2:233270
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class RelativeTimeIntervalType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Relative_ Timer_ Interval. Start. Elapsed_ Time
|
||||
/// urn:x-oca:ocpp:uid:1:569279
|
||||
/// Start of the interval, in seconds from NOW.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("start", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int Start { get; set; }
|
||||
|
||||
/// <summary>Relative_ Timer_ Interval. Duration. Elapsed_ Time
|
||||
/// urn:x-oca:ocpp:uid:1:569280
|
||||
/// Duration of the interval, in seconds.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("duration", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int Duration { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Sales_ Tariff_ Entry
|
||||
/// urn:x-oca:ocpp:uid:2:233271
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class SalesTariffEntryType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("relativeTimeInterval", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
public RelativeTimeIntervalType RelativeTimeInterval { get; set; } = new RelativeTimeIntervalType();
|
||||
|
||||
/// <summary>Sales_ Tariff_ Entry. E_ Price_ Level. Unsigned_ Integer
|
||||
/// urn:x-oca:ocpp:uid:1:569281
|
||||
/// Defines the price level of this SalesTariffEntry (referring to NumEPriceLevels). Small values for the EPriceLevel represent a cheaper TariffEntry. Large values for the EPriceLevel represent a more expensive TariffEntry.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("ePriceLevel", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.Range(0, int.MaxValue)]
|
||||
public int EPriceLevel { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("consumptionCost", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.MinLength(1)]
|
||||
[System.ComponentModel.DataAnnotations.MaxLength(3)]
|
||||
public System.Collections.Generic.ICollection<ConsumptionCostType> ConsumptionCost { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Sales_ Tariff
|
||||
/// urn:x-oca:ocpp:uid:2:233272
|
||||
/// NOTE: This dataType is based on dataTypes from &lt;&lt;ref-ISOIEC15118-2,ISO 15118-2&gt;&gt;.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class SalesTariffType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Identified_ Object. MRID. Numeric_ Identifier
|
||||
/// urn:x-enexis:ecdm:uid:1:569198
|
||||
/// SalesTariff identifier used to identify one sales tariff. An SAID remains a unique identifier for one schedule throughout a charging session.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>Sales_ Tariff. Sales. Tariff_ Description
|
||||
/// urn:x-oca:ocpp:uid:1:569283
|
||||
/// A human readable title/short description of the sales tariff e.g. for HMI display purposes.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("salesTariffDescription", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(32)]
|
||||
public string SalesTariffDescription { get; set; }
|
||||
|
||||
/// <summary>Sales_ Tariff. Num_ E_ Price_ Levels. Counter
|
||||
/// urn:x-oca:ocpp:uid:1:569284
|
||||
/// Defines the overall number of distinct price levels used across all provided SalesTariff elements.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("numEPriceLevels", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int NumEPriceLevels { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("salesTariffEntry", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
[System.ComponentModel.DataAnnotations.MinLength(1)]
|
||||
[System.ComponentModel.DataAnnotations.MaxLength(1024)]
|
||||
public System.Collections.Generic.ICollection<SalesTariffEntryType> SalesTariffEntry { get; set; } = new System.Collections.ObjectModel.Collection<SalesTariffEntryType>();
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class NotifyChargingLimitRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("chargingSchedule", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.MinLength(1)]
|
||||
public System.Collections.Generic.ICollection<ChargingScheduleType> ChargingSchedule { get; set; }
|
||||
|
||||
/// <summary>The charging schedule contained in this notification applies to an EVSE. evseId must be &gt; 0.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("evseId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int EvseId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("chargingLimit", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
public ChargingLimitType ChargingLimit { get; set; } = new ChargingLimitType();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class NotifyChargingLimitResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class NotifyEVChargingScheduleRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Periods contained in the charging profile are relative to this point in time.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("timeBase", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset TimeBase { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("chargingSchedule", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
public ChargingScheduleType ChargingSchedule { get; set; } = new ChargingScheduleType();
|
||||
|
||||
/// <summary>The charging schedule contained in this notification applies to an EVSE. EvseId must be &gt; 0.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("evseId", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int EvseId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>Returns whether the CSMS has been able to process the message successfully. It does not imply any approval of the charging schedule.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum GenericStatusEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Accepted")]
|
||||
Accepted = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Rejected")]
|
||||
Rejected = 1,
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class NotifyEVChargingScheduleResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public GenericStatusEnumType Status { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("statusInfo", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public StatusInfoType StatusInfo { get; set; }
|
||||
}
|
||||
}
|
||||
57
OCPP.Core.Server/Messages_OCPP20/ResetRequest.cs
Normal file
57
OCPP.Core.Server/Messages_OCPP20/ResetRequest.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>This contains the type of reset that the Charging Station or EVSE should perform.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum ResetEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Immediate")]
|
||||
Immediate = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"OnIdle")]
|
||||
OnIdle = 1
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class ResetRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public ResetEnumType Type { get; set; }
|
||||
|
||||
/// <summary>This contains the ID of a specific EVSE that needs to be reset, instead of the entire Charging Station.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("evseId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int EvseId { get; set; }
|
||||
}
|
||||
}
|
||||
58
OCPP.Core.Server/Messages_OCPP20/ResetResponse.cs
Normal file
58
OCPP.Core.Server/Messages_OCPP20/ResetResponse.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>This indicates whether the Charging Station is able to perform the reset.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum ResetStatusEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Accepted")]
|
||||
Accepted = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Rejected")]
|
||||
Rejected = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Scheduled")]
|
||||
Scheduled = 2
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class ResetResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public ResetStatusEnumType Status { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("statusInfo", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public StatusInfoType StatusInfo { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>This contains the current status of the Connector.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum ConnectorStatusEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Available")]
|
||||
Available = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Occupied")]
|
||||
Occupied = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Reserved")]
|
||||
Reserved = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Unavailable")]
|
||||
Unavailable = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Faulted")]
|
||||
Faulted = 4,
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class StatusNotificationRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>The time for which the status is reported. If absent time of receipt of the message will be assumed.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("timestamp", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("connectorStatus", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public ConnectorStatusEnumType ConnectorStatus { get; set; }
|
||||
|
||||
/// <summary>The id of the EVSE to which the connector belongs for which the the status is reported.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("evseId", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int EvseId { get; set; }
|
||||
|
||||
/// <summary>The id of the connector within the EVSE for which the status is reported.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("connectorId", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int ConnectorId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class StatusNotificationResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
}
|
||||
}
|
||||
327
OCPP.Core.Server/Messages_OCPP20/TransactionEventRequest.cs
Normal file
327
OCPP.Core.Server/Messages_OCPP20/TransactionEventRequest.cs
Normal file
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>Transaction. State. Transaction_ State_ Code
|
||||
/// urn:x-oca:ocpp:uid:1:569419
|
||||
/// Current charging state, is required when state
|
||||
/// has changed.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum ChargingStateEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Charging")]
|
||||
Charging = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EVConnected")]
|
||||
EVConnected = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SuspendedEV")]
|
||||
SuspendedEV = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SuspendedEVSE")]
|
||||
SuspendedEVSE = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Idle")]
|
||||
Idle = 4,
|
||||
}
|
||||
|
||||
/// <summary>Transaction. Stopped_ Reason. EOT_ Reason_ Code
|
||||
/// urn:x-oca:ocpp:uid:1:569413
|
||||
/// This contains the reason why the transaction was stopped. MAY only be omitted when Reason is "Local".
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum ReasonEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"")]
|
||||
Missing,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"DeAuthorized")]
|
||||
DeAuthorized,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EmergencyStop")]
|
||||
EmergencyStop,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EnergyLimitReached")]
|
||||
EnergyLimitReached,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EVDisconnected")]
|
||||
EVDisconnected,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"GroundFault")]
|
||||
GroundFault,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ImmediateReset")]
|
||||
ImmediateReset,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Local")]
|
||||
Local,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"LocalOutOfCredit")]
|
||||
LocalOutOfCredit,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"MasterPass")]
|
||||
MasterPass,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Other")]
|
||||
Other,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"OvercurrentFault")]
|
||||
OvercurrentFault,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"PowerLoss")]
|
||||
PowerLoss,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"PowerQuality")]
|
||||
PowerQuality,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Reboot")]
|
||||
Reboot,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Remote")]
|
||||
Remote,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SOCLimitReached")]
|
||||
SOCLimitReached,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"StoppedByEV")]
|
||||
StoppedByEV,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"TimeLimitReached")]
|
||||
TimeLimitReached,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Timeout")]
|
||||
Timeout
|
||||
}
|
||||
|
||||
/// <summary>This contains the type of this event.
|
||||
/// The first TransactionEvent of a transaction SHALL contain: "Started" The last TransactionEvent of a transaction SHALL contain: "Ended" All others SHALL contain: "Updated"
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum TransactionEventEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Ended")]
|
||||
Ended = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Started")]
|
||||
Started = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Updated")]
|
||||
Updated = 2,
|
||||
}
|
||||
|
||||
/// <summary>Reason the Charging Station sends this message to the CSMS
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum TriggerReasonEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Authorized")]
|
||||
Authorized = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"CablePluggedIn")]
|
||||
CablePluggedIn = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ChargingRateChanged")]
|
||||
ChargingRateChanged = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ChargingStateChanged")]
|
||||
ChargingStateChanged = 3,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Deauthorized")]
|
||||
Deauthorized = 4,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EnergyLimitReached")]
|
||||
EnergyLimitReached = 5,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EVCommunicationLost")]
|
||||
EVCommunicationLost = 6,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EVConnectTimeout")]
|
||||
EVConnectTimeout = 7,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"MeterValueClock")]
|
||||
MeterValueClock = 8,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"MeterValuePeriodic")]
|
||||
MeterValuePeriodic = 9,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"TimeLimitReached")]
|
||||
TimeLimitReached = 10,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Trigger")]
|
||||
Trigger = 11,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"UnlockCommand")]
|
||||
UnlockCommand = 12,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"StopAuthorized")]
|
||||
StopAuthorized = 13,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EVDeparted")]
|
||||
EVDeparted = 14,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"EVDetected")]
|
||||
EVDetected = 15,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"RemoteStop")]
|
||||
RemoteStop = 16,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"RemoteStart")]
|
||||
RemoteStart = 17,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"AbnormalCondition")]
|
||||
AbnormalCondition = 18,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"SignedDataReceived")]
|
||||
SignedDataReceived = 19,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"ResetCommand")]
|
||||
ResetCommand = 20,
|
||||
}
|
||||
|
||||
/// <summary>EVSE
|
||||
/// urn:x-oca:ocpp:uid:2:233123
|
||||
/// Electric Vehicle Supply Equipment
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class EVSEType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>Identified_ Object. MRID. Numeric_ Identifier
|
||||
/// urn:x-enexis:ecdm:uid:1:569198
|
||||
/// EVSE Identifier. This contains a number (&gt; 0) designating an EVSE of the Charging Station.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>An id to designate a specific connector (on an EVSE) by connector index number.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("connectorId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int ConnectorId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Transaction
|
||||
/// urn:x-oca:ocpp:uid:2:233318
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class TransactionType
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>This contains the Id of the transaction.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("transactionId", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(36)]
|
||||
public string TransactionId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("chargingState", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public ChargingStateEnumType ChargingState { get; set; }
|
||||
|
||||
/// <summary>Transaction. Time_ Spent_ Charging. Elapsed_ Time
|
||||
/// urn:x-oca:ocpp:uid:1:569415
|
||||
/// Contains the total time that energy flowed from EVSE to EV during the transaction (in seconds). Note that timeSpentCharging is smaller or equal to the duration of the transaction.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("timeSpentCharging", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int TimeSpentCharging { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("stoppedReason", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public ReasonEnumType StoppedReason { get; set; }
|
||||
|
||||
/// <summary>The ID given to remote start request (&lt;&lt;requeststarttransactionrequest, RequestStartTransactionRequest&gt;&gt;. This enables to CSMS to match the started transaction to the given start request.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("remoteStartId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int RemoteStartId { get; set; }
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class TransactionEventRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("eventType", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public TransactionEventEnumType EventType { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("meterValue", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.MinLength(1)]
|
||||
public System.Collections.Generic.ICollection<MeterValueType> MeterValue { get; set; }
|
||||
|
||||
/// <summary>The date and time at which this transaction event occurred.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("timestamp", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("triggerReason", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public TriggerReasonEnumType TriggerReason { get; set; }
|
||||
|
||||
/// <summary>Incremental sequence number, helps with determining if all messages of a transaction have been received.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("seqNo", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int SeqNo { get; set; }
|
||||
|
||||
/// <summary>Indication that this transaction event happened when the Charging Station was offline. Default = false, meaning: the event occurred when the Charging Station was online.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("offline", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public bool Offline { get; set; } = false;
|
||||
|
||||
/// <summary>If the Charging Station is able to report the number of phases used, then it SHALL provide it. When omitted the CSMS may be able to determine the number of phases used via device management.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("numberOfPhasesUsed", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int NumberOfPhasesUsed { get; set; }
|
||||
|
||||
/// <summary>The maximum current of the connected cable in Ampere (A).
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("cableMaxCurrent", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int CableMaxCurrent { get; set; }
|
||||
|
||||
/// <summary>This contains the Id of the reservation that terminates as a result of this transaction.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("reservationId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int ReservationId { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("transactionInfo", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
public TransactionType TransactionInfo { get; set; } = new TransactionType();
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("evse", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public EVSEType Evse { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("idToken", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public IdTokenType IdToken { get; set; }
|
||||
}
|
||||
}
|
||||
52
OCPP.Core.Server/Messages_OCPP20/TransactionEventResponse.cs
Normal file
52
OCPP.Core.Server/Messages_OCPP20/TransactionEventResponse.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class TransactionEventResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>SHALL only be sent when charging has ended. Final total cost of this transaction, including taxes. In the currency configured with the Configuration Variable: &lt;&lt;configkey-currency,`Currency`&gt;&gt;. When omitted, the transaction was NOT free. To indicate a free transaction, the CSMS SHALL send 0.00.
|
||||
///
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("totalCost", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public double TotalCost { get; set; }
|
||||
|
||||
/// <summary>Priority from a business point of view. Default priority is 0, The range is from -9 to 9. Higher values indicate a higher priority. The chargingPriority in &lt;&lt;transactioneventresponse,TransactionEventResponse&gt;&gt; is temporarily, so it may not be set in the &lt;&lt;cmn_idtokeninfotype,IdTokenInfoType&gt;&gt; afterwards. Also the chargingPriority in &lt;&lt;transactioneventresponse,TransactionEventResponse&gt;&gt; overrules the one in &lt;&lt;cmn_idtokeninfotype,IdTokenInfoType&gt;&gt;.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("chargingPriority", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public int ChargingPriority { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("idTokenInfo", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public IdTokenInfoType IdTokenInfo { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("updatedPersonalMessage", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public MessageContentType UpdatedPersonalMessage { get; set; }
|
||||
}
|
||||
}
|
||||
45
OCPP.Core.Server/Messages_OCPP20/UnlockConnectorRequest.cs
Normal file
45
OCPP.Core.Server/Messages_OCPP20/UnlockConnectorRequest.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class UnlockConnectorRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
/// <summary>This contains the identifier of the EVSE for which a connector needs to be unlocked.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("evseId", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int EvseId { get; set; }
|
||||
|
||||
/// <summary>This contains the identifier of the connector that needs to be unlocked.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("connectorId", Required = Newtonsoft.Json.Required.Always)]
|
||||
public int ConnectorId { get; set; }
|
||||
}
|
||||
}
|
||||
61
OCPP.Core.Server/Messages_OCPP20/UnlockConnectorResponse.cs
Normal file
61
OCPP.Core.Server/Messages_OCPP20/UnlockConnectorResponse.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server.Messages_OCPP20
|
||||
{
|
||||
#pragma warning disable // Disable all warnings
|
||||
|
||||
/// <summary>This indicates whether the Charging Station has unlocked the connector.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public enum UnlockStatusEnumType
|
||||
{
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"Unlocked")]
|
||||
Unlocked = 0,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"UnlockFailed")]
|
||||
UnlockFailed = 1,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"OngoingAuthorizedTransaction")]
|
||||
OngoingAuthorizedTransaction = 2,
|
||||
|
||||
[System.Runtime.Serialization.EnumMember(Value = @"UnknownConnector")]
|
||||
UnknownConnector = 3
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.3.1.0 (Newtonsoft.Json v9.0.0.0)")]
|
||||
public partial class UnlockConnectorResponse
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("customData", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public CustomDataType CustomData { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public UnlockStatusEnumType Status { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("statusInfo", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
public StatusInfoType StatusInfo { get; set; }
|
||||
}
|
||||
}
|
||||
49
OCPP.Core.Server/OCPP.Core.Server.csproj
Normal file
49
OCPP.Core.Server/OCPP.Core.Server.csproj
Normal file
@@ -0,0 +1,49 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Version>1.3.2</Version>
|
||||
<Company>dallmann consulting GmbH</Company>
|
||||
<Product>OCPP.Core</Product>
|
||||
<Authors>Ulrich Dallmann</Authors>
|
||||
<UserSecretsId>7dbe7593-03ad-445f-a179-41649d06f32e</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="logs\**" />
|
||||
<Content Remove="logs\**" />
|
||||
<EmbeddedResource Remove="logs\**" />
|
||||
<None Remove="logs\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="localhost.pfx" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="localhost.pfx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Karambolo.Extensions.Logging.File" Version="3.5.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.15" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OCPP.Core.Database\OCPP.Core.Database.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Schema20\" />
|
||||
<Folder Include="Schema16\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
||||
86
OCPP.Core.Server/OCPPMessage.cs
Normal file
86
OCPP.Core.Server/OCPPMessage.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
/// <summary>
|
||||
/// Warpper object for OCPP Message
|
||||
/// </summary>
|
||||
public class OCPPMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Message type
|
||||
/// </summary>
|
||||
public string MessageType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Message ID
|
||||
/// </summary>
|
||||
public string UniqueId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action
|
||||
/// </summary>
|
||||
public string Action { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// JSON-Payload
|
||||
/// </summary>
|
||||
public string JsonPayload { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Error-Code
|
||||
/// </summary>
|
||||
public string ErrorCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Error-Description
|
||||
/// </summary>
|
||||
public string ErrorDescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// TaskCompletionSource for asynchronous API result
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public TaskCompletionSource<string> TaskCompletionSource { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Empty constructor
|
||||
/// </summary>
|
||||
public OCPPMessage()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public OCPPMessage(string messageType, string uniqueId, string action, string jsonPayload)
|
||||
{
|
||||
MessageType = messageType;
|
||||
UniqueId = uniqueId;
|
||||
Action = action;
|
||||
JsonPayload = jsonPayload;
|
||||
}
|
||||
}
|
||||
}
|
||||
247
OCPP.Core.Server/OCPPMiddleware.OCPP16.cs
Normal file
247
OCPP.Core.Server/OCPPMiddleware.OCPP16.cs
Normal file
@@ -0,0 +1,247 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class OCPPMiddleware
|
||||
{
|
||||
/// <summary>
|
||||
/// Waits for new OCPP V1.6 messages on the open websocket connection and delegates processing to a controller
|
||||
/// </summary>
|
||||
private async Task Receive16(ChargePointStatus chargePointStatus, HttpContext context, OCPPCoreContext dbContext)
|
||||
{
|
||||
ILogger logger = _logFactory.CreateLogger("OCPPMiddleware.OCPP16");
|
||||
ControllerOCPP16 controller16 = new ControllerOCPP16(_configuration, _logFactory, chargePointStatus, dbContext);
|
||||
|
||||
int maxMessageSizeBytes = _configuration.GetValue<int>("MaxMessageSize", 0);
|
||||
|
||||
byte[] buffer = new byte[1024 * 4];
|
||||
MemoryStream memStream = new MemoryStream(buffer.Length);
|
||||
|
||||
while (chargePointStatus.WebSocket.State == WebSocketState.Open)
|
||||
{
|
||||
WebSocketReceiveResult result = await chargePointStatus.WebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
||||
if (result != null && result.MessageType != WebSocketMessageType.Close)
|
||||
{
|
||||
logger.LogTrace("OCPPMiddleware.Receive16 => Receiving segment: {0} bytes (EndOfMessage={1} / MsgType={2})", result.Count, result.EndOfMessage, result.MessageType);
|
||||
memStream.Write(buffer, 0, result.Count);
|
||||
|
||||
// max. allowed message size NOT exceeded - or limit deactivated?
|
||||
if (maxMessageSizeBytes == 0 || memStream.Length <= maxMessageSizeBytes)
|
||||
{
|
||||
if (result.EndOfMessage)
|
||||
{
|
||||
// read complete message into byte array
|
||||
byte[] bMessage = memStream.ToArray();
|
||||
// reset memory stream für next message
|
||||
memStream = new MemoryStream(buffer.Length);
|
||||
|
||||
string dumpDir = _configuration.GetValue<string>("MessageDumpDir");
|
||||
if (!string.IsNullOrWhiteSpace(dumpDir))
|
||||
{
|
||||
string path = Path.Combine(dumpDir, string.Format("{0}_ocpp16-in.txt", DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss-ffff")));
|
||||
try
|
||||
{
|
||||
// Write incoming message into dump directory
|
||||
File.WriteAllBytes(path, bMessage);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
logger.LogError(exp, "OCPPMiddleware.Receive16 => Error dumping incoming message to path: '{0}'", path);
|
||||
}
|
||||
}
|
||||
|
||||
string ocppMessage = UTF8Encoding.UTF8.GetString(bMessage);
|
||||
|
||||
Match match = Regex.Match(ocppMessage, MessageRegExp);
|
||||
if (match != null && match.Groups != null && match.Groups.Count >= 3)
|
||||
{
|
||||
string messageTypeId = match.Groups[1].Value;
|
||||
string uniqueId = match.Groups[2].Value;
|
||||
string action = match.Groups[3].Value;
|
||||
string jsonPaylod = match.Groups[4].Value;
|
||||
logger.LogInformation("OCPPMiddleware.Receive16 => OCPP-Message: Type={0} / ID={1} / Action={2})", messageTypeId, uniqueId, action);
|
||||
|
||||
OCPPMessage msgIn = new OCPPMessage(messageTypeId, uniqueId, action, jsonPaylod);
|
||||
if (msgIn.MessageType == "2")
|
||||
{
|
||||
// Request from chargepoint to OCPP server
|
||||
OCPPMessage msgOut = controller16.ProcessRequest(msgIn);
|
||||
|
||||
// Send OCPP message with optional logging/dump
|
||||
await SendOcpp16Message(msgOut, logger, chargePointStatus.WebSocket);
|
||||
}
|
||||
else if (msgIn.MessageType == "3" || msgIn.MessageType == "4")
|
||||
{
|
||||
// Process answer from chargepoint
|
||||
if (_requestQueue.ContainsKey(msgIn.UniqueId))
|
||||
{
|
||||
controller16.ProcessAnswer(msgIn, _requestQueue[msgIn.UniqueId]);
|
||||
_requestQueue.Remove(msgIn.UniqueId);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogError("OCPPMiddleware.Receive16 => HttpContext from caller not found / Msg: {0}", ocppMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown message type
|
||||
logger.LogError("OCPPMiddleware.Receive16 => Unknown message type: {0} / Msg: {1}", msgIn.MessageType, ocppMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning("OCPPMiddleware.Receive16 => Error in RegEx-Matching: Msg={0})", ocppMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// max. allowed message size exceeded => close connection (DoS attack?)
|
||||
logger.LogInformation("OCPPMiddleware.Receive16 => Allowed message size exceeded - close connection");
|
||||
await chargePointStatus.WebSocket.CloseOutputAsync(WebSocketCloseStatus.MessageTooBig, string.Empty, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInformation("OCPPMiddleware.Receive16 => WebSocket Closed: CloseStatus={0} / MessageType={1}", result?.CloseStatus, result?.MessageType);
|
||||
await chargePointStatus.WebSocket.CloseOutputAsync((WebSocketCloseStatus)3001, string.Empty, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
logger.LogInformation("OCPPMiddleware.Receive16 => Websocket closed: State={0} / CloseStatus={1}", chargePointStatus.WebSocket.State, chargePointStatus.WebSocket.CloseStatus);
|
||||
ChargePointStatus dummy;
|
||||
_chargePointStatusDict.Remove(chargePointStatus.Id, out dummy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits for new OCPP V1.6 messages on the open websocket connection and delegates processing to a controller
|
||||
/// </summary>
|
||||
private async Task Reset16(ChargePointStatus chargePointStatus, HttpContext apiCallerContext, OCPPCoreContext dbContext)
|
||||
{
|
||||
ILogger logger = _logFactory.CreateLogger("OCPPMiddleware.OCPP16");
|
||||
ControllerOCPP16 controller16 = new ControllerOCPP16(_configuration, _logFactory, chargePointStatus, dbContext);
|
||||
|
||||
Messages_OCPP16.ResetRequest resetRequest = new Messages_OCPP16.ResetRequest();
|
||||
resetRequest.Type = Messages_OCPP16.ResetRequestType.Soft;
|
||||
string jsonResetRequest = JsonConvert.SerializeObject(resetRequest);
|
||||
|
||||
OCPPMessage msgOut = new OCPPMessage();
|
||||
msgOut.MessageType = "2";
|
||||
msgOut.Action = "Reset";
|
||||
msgOut.UniqueId = Guid.NewGuid().ToString("N");
|
||||
msgOut.JsonPayload = jsonResetRequest;
|
||||
msgOut.TaskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
// store HttpContext with MsgId for later answer processing (=> send anwer to API caller)
|
||||
_requestQueue.Add(msgOut.UniqueId, msgOut);
|
||||
|
||||
// Send OCPP message with optional logging/dump
|
||||
await SendOcpp16Message(msgOut, logger, chargePointStatus.WebSocket);
|
||||
|
||||
// Wait for asynchronous chargepoint response and processing
|
||||
string apiResult = await msgOut.TaskCompletionSource.Task;
|
||||
|
||||
//
|
||||
apiCallerContext.Response.StatusCode = 200;
|
||||
apiCallerContext.Response.ContentType = "application/json";
|
||||
await apiCallerContext.Response.WriteAsync(apiResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a Unlock-Request to the chargepoint
|
||||
/// </summary>
|
||||
private async Task UnlockConnector16(ChargePointStatus chargePointStatus, HttpContext apiCallerContext, OCPPCoreContext dbContext)
|
||||
{
|
||||
ILogger logger = _logFactory.CreateLogger("OCPPMiddleware.OCPP16");
|
||||
ControllerOCPP16 controller16 = new ControllerOCPP16(_configuration, _logFactory, chargePointStatus, dbContext);
|
||||
|
||||
Messages_OCPP16.UnlockConnectorRequest unlockConnectorRequest = new Messages_OCPP16.UnlockConnectorRequest();
|
||||
unlockConnectorRequest.ConnectorId = 0;
|
||||
|
||||
string jsonResetRequest = JsonConvert.SerializeObject(unlockConnectorRequest);
|
||||
|
||||
OCPPMessage msgOut = new OCPPMessage();
|
||||
msgOut.MessageType = "2";
|
||||
msgOut.Action = "UnlockConnector";
|
||||
msgOut.UniqueId = Guid.NewGuid().ToString("N");
|
||||
msgOut.JsonPayload = jsonResetRequest;
|
||||
msgOut.TaskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
// store HttpContext with MsgId for later answer processing (=> send anwer to API caller)
|
||||
_requestQueue.Add(msgOut.UniqueId, msgOut);
|
||||
|
||||
// Send OCPP message with optional logging/dump
|
||||
await SendOcpp16Message(msgOut, logger, chargePointStatus.WebSocket);
|
||||
|
||||
// Wait for asynchronous chargepoint response and processing
|
||||
string apiResult = await msgOut.TaskCompletionSource.Task;
|
||||
|
||||
//
|
||||
apiCallerContext.Response.StatusCode = 200;
|
||||
apiCallerContext.Response.ContentType = "application/json";
|
||||
await apiCallerContext.Response.WriteAsync(apiResult);
|
||||
}
|
||||
|
||||
private async Task SendOcpp16Message(OCPPMessage msg, ILogger logger, WebSocket webSocket)
|
||||
{
|
||||
string ocppTextMessage = null;
|
||||
|
||||
if (string.IsNullOrEmpty(msg.ErrorCode))
|
||||
{
|
||||
if (msg.MessageType == "2")
|
||||
{
|
||||
// OCPP-Request
|
||||
ocppTextMessage = string.Format("[{0},\"{1}\",\"{2}\",{3}]", msg.MessageType, msg.UniqueId, msg.Action, msg.JsonPayload);
|
||||
}
|
||||
else
|
||||
{
|
||||
// OCPP-Response
|
||||
ocppTextMessage = string.Format("[{0},\"{1}\",{2}]", msg.MessageType, msg.UniqueId, msg.JsonPayload);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ocppTextMessage = string.Format("[{0},\"{1}\",\"{2}\",\"{3}\",{4}]", msg.MessageType, msg.UniqueId, msg.ErrorCode, msg.ErrorDescription, "{}");
|
||||
}
|
||||
logger.LogTrace("OCPPMiddleware.OCPP16 => SendOcppMessage: {0}", ocppTextMessage);
|
||||
|
||||
if (string.IsNullOrEmpty(ocppTextMessage))
|
||||
{
|
||||
// invalid message
|
||||
ocppTextMessage = string.Format("[{0},\"{1}\",\"{2}\",\"{3}\",{4}]", "4", string.Empty, Messages_OCPP16.ErrorCodes.ProtocolError, string.Empty, "{}");
|
||||
}
|
||||
|
||||
string dumpDir = _configuration.GetValue<string>("MessageDumpDir");
|
||||
if (!string.IsNullOrWhiteSpace(dumpDir))
|
||||
{
|
||||
// Write outgoing message into dump directory
|
||||
string path = Path.Combine(dumpDir, string.Format("{0}_ocpp16-out.txt", DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss-ffff")));
|
||||
try
|
||||
{
|
||||
File.WriteAllText(path, ocppTextMessage);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
logger.LogError(exp, "OCPPMiddleware.SendOcpp16Message=> Error dumping message to path: '{0}'", path);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] binaryMessage = UTF8Encoding.UTF8.GetBytes(ocppTextMessage);
|
||||
await webSocket.SendAsync(new ArraySegment<byte>(binaryMessage, 0, binaryMessage.Length), WebSocketMessageType.Text, true, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
252
OCPP.Core.Server/OCPPMiddleware.OCPP20.cs
Normal file
252
OCPP.Core.Server/OCPPMiddleware.OCPP20.cs
Normal file
@@ -0,0 +1,252 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using OCPP.Core.Server.Messages_OCPP20;
|
||||
using OCPP.Core.Database;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class OCPPMiddleware
|
||||
{
|
||||
/// <summary>
|
||||
/// Waits for new OCPP V2.0 messages on the open websocket connection and delegates processing to a controller
|
||||
/// </summary>
|
||||
private async Task Receive20(ChargePointStatus chargePointStatus, HttpContext httpContext, OCPPCoreContext dbContext)
|
||||
{
|
||||
ILogger logger = _logFactory.CreateLogger("OCPPMiddleware.OCPP20");
|
||||
ControllerOCPP20 controller20 = new ControllerOCPP20(_configuration, _logFactory, chargePointStatus, dbContext);
|
||||
|
||||
int maxMessageSizeBytes = _configuration.GetValue<int>("MaxMessageSize", 0);
|
||||
|
||||
byte[] buffer = new byte[1024 * 4];
|
||||
MemoryStream memStream = new MemoryStream(buffer.Length);
|
||||
|
||||
while (chargePointStatus.WebSocket.State == WebSocketState.Open)
|
||||
{
|
||||
WebSocketReceiveResult result = await chargePointStatus.WebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
||||
if (result != null && result.MessageType != WebSocketMessageType.Close)
|
||||
{
|
||||
logger.LogTrace("OCPPMiddleware.Receive20 => Receiving segment: {0} bytes (EndOfMessage={1} / MsgType={2})", result.Count, result.EndOfMessage, result.MessageType);
|
||||
memStream.Write(buffer, 0, result.Count);
|
||||
|
||||
// max. allowed message size NOT exceeded - or limit deactivated?
|
||||
if (maxMessageSizeBytes == 0 || memStream.Length <= maxMessageSizeBytes)
|
||||
{
|
||||
if (result.EndOfMessage)
|
||||
{
|
||||
// read complete message into byte array
|
||||
byte[] bMessage = memStream.ToArray();
|
||||
// reset memory stream für next message
|
||||
memStream = new MemoryStream(buffer.Length);
|
||||
|
||||
string dumpDir = _configuration.GetValue<string>("MessageDumpDir");
|
||||
if (!string.IsNullOrWhiteSpace(dumpDir))
|
||||
{
|
||||
string path = Path.Combine(dumpDir, string.Format("{0}_ocpp20-in.txt", DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss-ffff")));
|
||||
try
|
||||
{
|
||||
// Write incoming message into dump directory
|
||||
File.WriteAllBytes(path, bMessage);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
logger.LogError(exp, "OCPPMiddleware.Receive20 => Error dumping incoming message to path: '{0}'", path);
|
||||
}
|
||||
}
|
||||
|
||||
string ocppMessage = UTF8Encoding.UTF8.GetString(bMessage);
|
||||
|
||||
Match match = Regex.Match(ocppMessage, MessageRegExp);
|
||||
if (match != null && match.Groups != null && match.Groups.Count >= 3)
|
||||
{
|
||||
string messageTypeId = match.Groups[1].Value;
|
||||
string uniqueId = match.Groups[2].Value;
|
||||
string action = match.Groups[3].Value;
|
||||
string jsonPaylod = match.Groups[4].Value;
|
||||
logger.LogInformation("OCPPMiddleware.Receive20 => OCPP-Message: Type={0} / ID={1} / Action={2})", messageTypeId, uniqueId, action);
|
||||
|
||||
OCPPMessage msgIn = new OCPPMessage(messageTypeId, uniqueId, action, jsonPaylod);
|
||||
if (msgIn.MessageType == "2")
|
||||
{
|
||||
// Request from chargepoint to OCPP server
|
||||
OCPPMessage msgOut = controller20.ProcessRequest(msgIn);
|
||||
|
||||
// Send OCPP message with optional logging/dump
|
||||
await SendOcpp20Message(msgOut, logger, chargePointStatus.WebSocket);
|
||||
}
|
||||
else if (msgIn.MessageType == "3" || msgIn.MessageType == "4")
|
||||
{
|
||||
// Process answer from chargepoint
|
||||
if (_requestQueue.ContainsKey(msgIn.UniqueId))
|
||||
{
|
||||
controller20.ProcessAnswer(msgIn, _requestQueue[msgIn.UniqueId]);
|
||||
_requestQueue.Remove(msgIn.UniqueId);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogError("OCPPMiddleware.Receive20 => HttpContext from caller not found / Msg: {0}", ocppMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown message type
|
||||
logger.LogError("OCPPMiddleware.Receive20 => Unknown message type: {0} / Msg: {1}", msgIn.MessageType, ocppMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning("OCPPMiddleware.Receive20 => Error in RegEx-Matching: Msg={0})", ocppMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// max. allowed message size exceeded => close connection (DoS attack?)
|
||||
logger.LogInformation("OCPPMiddleware.Receive20 => Allowed message size exceeded - close connection");
|
||||
await chargePointStatus.WebSocket.CloseOutputAsync(WebSocketCloseStatus.MessageTooBig, string.Empty, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInformation("OCPPMiddleware.Receive20 => Receive: unexpected result: CloseStatus={0} / MessageType={1}", result?.CloseStatus, result?.MessageType);
|
||||
await chargePointStatus.WebSocket.CloseOutputAsync((WebSocketCloseStatus)3001, string.Empty, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
logger.LogInformation("OCPPMiddleware.Receive20 => Websocket closed: State={0} / CloseStatus={1}", chargePointStatus.WebSocket.State, chargePointStatus.WebSocket.CloseStatus);
|
||||
ChargePointStatus dummy;
|
||||
_chargePointStatusDict.Remove(chargePointStatus.Id, out dummy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a (Soft-)Reset to the chargepoint
|
||||
/// </summary>
|
||||
private async Task Reset20(ChargePointStatus chargePointStatus, HttpContext apiCallerContext, OCPPCoreContext dbContext)
|
||||
{
|
||||
ILogger logger = _logFactory.CreateLogger("OCPPMiddleware.OCPP20");
|
||||
ControllerOCPP20 controller20 = new ControllerOCPP20(_configuration, _logFactory, chargePointStatus, dbContext);
|
||||
|
||||
Messages_OCPP20.ResetRequest resetRequest = new Messages_OCPP20.ResetRequest();
|
||||
resetRequest.Type = Messages_OCPP20.ResetEnumType.OnIdle;
|
||||
resetRequest.CustomData = new CustomDataType();
|
||||
resetRequest.CustomData.VendorId = ControllerOCPP20.VendorId;
|
||||
|
||||
string jsonResetRequest = JsonConvert.SerializeObject(resetRequest);
|
||||
|
||||
OCPPMessage msgOut = new OCPPMessage();
|
||||
msgOut.MessageType = "2";
|
||||
msgOut.Action = "Reset";
|
||||
msgOut.UniqueId = Guid.NewGuid().ToString("N");
|
||||
msgOut.JsonPayload = jsonResetRequest;
|
||||
msgOut.TaskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
// store HttpContext with MsgId for later answer processing (=> send anwer to API caller)
|
||||
_requestQueue.Add(msgOut.UniqueId, msgOut);
|
||||
|
||||
// Send OCPP message with optional logging/dump
|
||||
await SendOcpp20Message(msgOut, logger, chargePointStatus.WebSocket);
|
||||
|
||||
// Wait for asynchronous chargepoint response and processing
|
||||
string apiResult = await msgOut.TaskCompletionSource.Task;
|
||||
|
||||
//
|
||||
apiCallerContext.Response.StatusCode = 200;
|
||||
apiCallerContext.Response.ContentType = "application/json";
|
||||
await apiCallerContext.Response.WriteAsync(apiResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a Unlock-Request to the chargepoint
|
||||
/// </summary>
|
||||
private async Task UnlockConnector20(ChargePointStatus chargePointStatus, HttpContext apiCallerContext, OCPPCoreContext dbContext)
|
||||
{
|
||||
ILogger logger = _logFactory.CreateLogger("OCPPMiddleware.OCPP20");
|
||||
ControllerOCPP20 controller20 = new ControllerOCPP20(_configuration, _logFactory, chargePointStatus, dbContext);
|
||||
|
||||
Messages_OCPP20.UnlockConnectorRequest unlockConnectorRequest = new Messages_OCPP20.UnlockConnectorRequest();
|
||||
unlockConnectorRequest.EvseId = 0;
|
||||
unlockConnectorRequest.CustomData = new CustomDataType();
|
||||
unlockConnectorRequest.CustomData.VendorId = ControllerOCPP20.VendorId;
|
||||
|
||||
string jsonResetRequest = JsonConvert.SerializeObject(unlockConnectorRequest);
|
||||
|
||||
OCPPMessage msgOut = new OCPPMessage();
|
||||
msgOut.MessageType = "2";
|
||||
msgOut.Action = "UnlockConnector";
|
||||
msgOut.UniqueId = Guid.NewGuid().ToString("N");
|
||||
msgOut.JsonPayload = jsonResetRequest;
|
||||
msgOut.TaskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
// store HttpContext with MsgId for later answer processing (=> send anwer to API caller)
|
||||
_requestQueue.Add(msgOut.UniqueId, msgOut);
|
||||
|
||||
// Send OCPP message with optional logging/dump
|
||||
await SendOcpp20Message(msgOut, logger, chargePointStatus.WebSocket);
|
||||
|
||||
// Wait for asynchronous chargepoint response and processing
|
||||
string apiResult = await msgOut.TaskCompletionSource.Task;
|
||||
|
||||
//
|
||||
apiCallerContext.Response.StatusCode = 200;
|
||||
apiCallerContext.Response.ContentType = "application/json";
|
||||
await apiCallerContext.Response.WriteAsync(apiResult);
|
||||
}
|
||||
|
||||
private async Task SendOcpp20Message(OCPPMessage msg, ILogger logger, WebSocket webSocket)
|
||||
{
|
||||
string ocppTextMessage = null;
|
||||
|
||||
if (string.IsNullOrEmpty(msg.ErrorCode))
|
||||
{
|
||||
if (msg.MessageType == "2")
|
||||
{
|
||||
// OCPP-Request
|
||||
ocppTextMessage = string.Format("[{0},\"{1}\",\"{2}\",{3}]", msg.MessageType, msg.UniqueId, msg.Action, msg.JsonPayload);
|
||||
}
|
||||
else
|
||||
{
|
||||
// OCPP-Response
|
||||
ocppTextMessage = string.Format("[{0},\"{1}\",{2}]", msg.MessageType, msg.UniqueId, msg.JsonPayload);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ocppTextMessage = string.Format("[{0},\"{1}\",\"{2}\",\"{3}\",{4}]", msg.MessageType, msg.UniqueId, msg.ErrorCode, msg.ErrorDescription, "{}");
|
||||
}
|
||||
logger.LogTrace("OCPPMiddleware.OCPP20 => SendOcppMessage: {0}", ocppTextMessage);
|
||||
|
||||
if (string.IsNullOrEmpty(ocppTextMessage))
|
||||
{
|
||||
// invalid message
|
||||
ocppTextMessage = string.Format("[{0},\"{1}\",\"{2}\",\"{3}\",{4}]", "4", string.Empty, Messages_OCPP20.ErrorCodes.ProtocolError, string.Empty, "{}");
|
||||
}
|
||||
|
||||
string dumpDir = _configuration.GetValue<string>("MessageDumpDir");
|
||||
if (!string.IsNullOrWhiteSpace(dumpDir))
|
||||
{
|
||||
// Write outgoing message into dump directory
|
||||
string path = Path.Combine(dumpDir, string.Format("{0}_ocpp20-out.txt", DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss-ffff")));
|
||||
try
|
||||
{
|
||||
File.WriteAllText(path, ocppTextMessage);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
logger.LogError(exp, "OCPPMiddleware.SendOcpp20Message=> Error dumping message to path: '{0}'", path);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] binaryMessage = UTF8Encoding.UTF8.GetBytes(ocppTextMessage);
|
||||
await webSocket.SendAsync(new ArraySegment<byte>(binaryMessage, 0, binaryMessage.Length), WebSocketMessageType.Text, true, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
428
OCPP.Core.Server/OCPPMiddleware.cs
Normal file
428
OCPP.Core.Server/OCPPMiddleware.cs
Normal file
@@ -0,0 +1,428 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using OCPP.Core.Database;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.WebSockets;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public partial class OCPPMiddleware
|
||||
{
|
||||
// Supported OCPP protocols (in order)
|
||||
private const string Protocol_OCPP16 = "ocpp1.6";
|
||||
private const string Protocol_OCPP20 = "ocpp2.0";
|
||||
private static readonly string[] SupportedProtocols = { Protocol_OCPP20, Protocol_OCPP16 /*, "ocpp1.5" */};
|
||||
|
||||
// RegExp for splitting ocpp message parts
|
||||
// ^\[\s*(\d)\s*,\s*\"([^"]*)\"\s*,(?:\s*\"(\w*)\"\s*,)?\s*(.*)\s*\]$
|
||||
// Third block is optional, because responses don't have an action
|
||||
private static string MessageRegExp = "^\\[\\s*(\\d)\\s*,\\s*\"([^\"]*)\"\\s*,(?:\\s*\"(\\w*)\"\\s*,)?\\s*(.*)\\s*\\]$";
|
||||
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly ILoggerFactory _logFactory;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
// Dictionary with status objects for each charge point
|
||||
private static Dictionary<string, ChargePointStatus> _chargePointStatusDict = new Dictionary<string, ChargePointStatus>();
|
||||
|
||||
// Dictionary for processing asynchronous API calls
|
||||
private Dictionary<string, OCPPMessage> _requestQueue = new Dictionary<string, OCPPMessage>();
|
||||
|
||||
public OCPPMiddleware(RequestDelegate next, ILoggerFactory logFactory, IConfiguration configuration)
|
||||
{
|
||||
_next = next;
|
||||
_logFactory = logFactory;
|
||||
_configuration = configuration;
|
||||
|
||||
_logger = logFactory.CreateLogger("OCPPMiddleware");
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context, OCPPCoreContext dbContext)
|
||||
{
|
||||
_logger.LogTrace("OCPPMiddleware => Websocket request: Path='{0}'", context.Request.Path);
|
||||
|
||||
ChargePointStatus chargePointStatus = null;
|
||||
|
||||
if (context.Request.Path.StartsWithSegments("/OCPP"))
|
||||
{
|
||||
string chargepointIdentifier;
|
||||
string[] parts = context.Request.Path.Value.Split('/');
|
||||
if (string.IsNullOrWhiteSpace(parts[parts.Length - 1]))
|
||||
{
|
||||
// (Last part - 1) is chargepoint identifier
|
||||
chargepointIdentifier = parts[parts.Length - 2];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Last part is chargepoint identifier
|
||||
chargepointIdentifier = parts[parts.Length - 1];
|
||||
}
|
||||
_logger.LogInformation("OCPPMiddleware => Connection request with chargepoint identifier = '{0}'", chargepointIdentifier);
|
||||
|
||||
// Known chargepoint?
|
||||
if (!string.IsNullOrWhiteSpace(chargepointIdentifier))
|
||||
{
|
||||
ChargePoint chargePoint = dbContext.Find<ChargePoint>(chargepointIdentifier);
|
||||
if (chargePoint != null)
|
||||
{
|
||||
_logger.LogInformation("OCPPMiddleware => SUCCESS: Found chargepoint with identifier={0}", chargePoint.ChargePointId);
|
||||
|
||||
// Check optional chargepoint authentication
|
||||
if (!string.IsNullOrWhiteSpace(chargePoint.Username))
|
||||
{
|
||||
// Chargepoint MUST send basic authentication header
|
||||
|
||||
bool basicAuthSuccess = false;
|
||||
string authHeader = context.Request.Headers["Authorization"];
|
||||
if (!string.IsNullOrEmpty(authHeader))
|
||||
{
|
||||
string[] cred = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(authHeader.Substring(6))).Split(':');
|
||||
if (cred.Length == 2 && chargePoint.Username == cred[0] && chargePoint.Password == cred[1])
|
||||
{
|
||||
// Authentication match => OK
|
||||
_logger.LogInformation("OCPPMiddleware => SUCCESS: Basic authentication for chargepoint '{0}' match", chargePoint.ChargePointId);
|
||||
basicAuthSuccess = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Authentication does NOT match => Failure
|
||||
_logger.LogWarning("OCPPMiddleware => FAILURE: Basic authentication for chargepoint '{0}' does NOT match", chargePoint.ChargePointId);
|
||||
}
|
||||
}
|
||||
if (basicAuthSuccess == false)
|
||||
{
|
||||
context.Response.Headers.Append("WWW-Authenticate", "Basic realm=\"OCPP.Core\"");
|
||||
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(chargePoint.ClientCertThumb))
|
||||
{
|
||||
// Chargepoint MUST send basic authentication header
|
||||
|
||||
bool certAuthSuccess = false;
|
||||
X509Certificate2 clientCert = context.Connection.ClientCertificate;
|
||||
if (clientCert != null)
|
||||
{
|
||||
if (clientCert.Thumbprint.Equals(chargePoint.ClientCertThumb, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
// Authentication match => OK
|
||||
_logger.LogInformation("OCPPMiddleware => SUCCESS: Certificate authentication for chargepoint '{0}' match", chargePoint.ChargePointId);
|
||||
certAuthSuccess = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Authentication does NOT match => Failure
|
||||
_logger.LogWarning("OCPPMiddleware => FAILURE: Certificate authentication for chargepoint '{0}' does NOT match", chargePoint.ChargePointId);
|
||||
}
|
||||
}
|
||||
if (certAuthSuccess == false)
|
||||
{
|
||||
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogInformation("OCPPMiddleware => No authentication for chargepoint '{0}' configured", chargePoint.ChargePointId);
|
||||
}
|
||||
|
||||
// Store chargepoint data
|
||||
chargePointStatus = new ChargePointStatus(chargePoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("OCPPMiddleware => FAILURE: Found no chargepoint with identifier={0}", chargepointIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
if (chargePointStatus != null)
|
||||
{
|
||||
if (context.WebSockets.IsWebSocketRequest)
|
||||
{
|
||||
// Match supported sub protocols
|
||||
string subProtocol = null;
|
||||
foreach (string supportedProtocol in SupportedProtocols)
|
||||
{
|
||||
if (context.WebSockets.WebSocketRequestedProtocols.Contains(supportedProtocol))
|
||||
{
|
||||
subProtocol = supportedProtocol;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrEmpty(subProtocol))
|
||||
{
|
||||
// Not matching protocol! => failure
|
||||
string protocols = string.Empty;
|
||||
foreach (string p in context.WebSockets.WebSocketRequestedProtocols)
|
||||
{
|
||||
if (string.IsNullOrEmpty(protocols)) protocols += ",";
|
||||
protocols += p;
|
||||
}
|
||||
_logger.LogWarning("OCPPMiddleware => No supported sub-protocol in '{0}' from charge station '{1}'", protocols, chargepointIdentifier);
|
||||
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||
}
|
||||
else
|
||||
{
|
||||
chargePointStatus.Protocol = subProtocol;
|
||||
|
||||
bool statusSuccess = false;
|
||||
try
|
||||
{
|
||||
_logger.LogTrace("OCPPMiddleware => Store/Update status object");
|
||||
|
||||
lock (_chargePointStatusDict)
|
||||
{
|
||||
// Check if this chargepoint already/still hat a status object
|
||||
if (_chargePointStatusDict.ContainsKey(chargepointIdentifier))
|
||||
{
|
||||
// exists => check status
|
||||
if (_chargePointStatusDict[chargepointIdentifier].WebSocket.State != WebSocketState.Open)
|
||||
{
|
||||
// Closed or aborted => remove
|
||||
_chargePointStatusDict.Remove(chargepointIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
_chargePointStatusDict.Add(chargepointIdentifier, chargePointStatus);
|
||||
statusSuccess = true;
|
||||
}
|
||||
}
|
||||
catch(Exception exp)
|
||||
{
|
||||
_logger.LogError(exp, "OCPPMiddleware => Error storing status object in dictionary => refuse connection");
|
||||
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
}
|
||||
|
||||
if (statusSuccess)
|
||||
{
|
||||
// Handle socket communication
|
||||
_logger.LogTrace("OCPPMiddleware => Waiting for message...");
|
||||
|
||||
using (WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(subProtocol))
|
||||
{
|
||||
_logger.LogTrace("OCPPMiddleware => WebSocket connection with charge point '{0}'", chargepointIdentifier);
|
||||
chargePointStatus.WebSocket = webSocket;
|
||||
|
||||
if (subProtocol == Protocol_OCPP20)
|
||||
{
|
||||
// OCPP V2.0
|
||||
await Receive20(chargePointStatus, context, dbContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
// OCPP V1.6
|
||||
await Receive16(chargePointStatus, context, dbContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no websocket request => failure
|
||||
_logger.LogWarning("OCPPMiddleware => Non-Websocket request");
|
||||
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// unknown chargepoint
|
||||
_logger.LogTrace("OCPPMiddleware => no chargepoint: http 412");
|
||||
context.Response.StatusCode = (int)HttpStatusCode.PreconditionFailed;
|
||||
}
|
||||
}
|
||||
else if (context.Request.Path.StartsWithSegments("/API"))
|
||||
{
|
||||
// Check authentication (X-API-Key)
|
||||
string apiKeyConfig = _configuration.GetValue<string>("ApiKey");
|
||||
if (!string.IsNullOrWhiteSpace(apiKeyConfig))
|
||||
{
|
||||
// ApiKey specified => check request
|
||||
string apiKeyCaller = context.Request.Headers["X-API-Key"].FirstOrDefault();
|
||||
if (apiKeyConfig == apiKeyCaller)
|
||||
{
|
||||
// API-Key matches
|
||||
_logger.LogInformation("OCPPMiddleware => Success: X-API-Key matches");
|
||||
}
|
||||
else
|
||||
{
|
||||
// API-Key does NOT matches => authentication failure!!!
|
||||
_logger.LogWarning("OCPPMiddleware => Failure: Wrong X-API-Key! Caller='{0}'", apiKeyCaller);
|
||||
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No API-Key configured => no authenticatiuon
|
||||
_logger.LogWarning("OCPPMiddleware => No X-API-Key configured!");
|
||||
}
|
||||
|
||||
// format: /API/<command>[/chargepointId]
|
||||
string[] urlParts = context.Request.Path.Value.Split('/');
|
||||
|
||||
if (urlParts.Length >= 3)
|
||||
{
|
||||
string cmd = urlParts[2];
|
||||
string urlChargePointId = (urlParts.Length >= 4) ? urlParts[3] : null;
|
||||
_logger.LogTrace("OCPPMiddleware => cmd='{0}' / id='{1}' / FullPath='{2}')", cmd, urlChargePointId, context.Request.Path.Value);
|
||||
|
||||
if (cmd == "Status")
|
||||
{
|
||||
try
|
||||
{
|
||||
List<ChargePointStatus> statusList = new List<ChargePointStatus>();
|
||||
foreach (ChargePointStatus status in _chargePointStatusDict.Values)
|
||||
{
|
||||
statusList.Add(status);
|
||||
}
|
||||
string jsonStatus = JsonConvert.SerializeObject(statusList);
|
||||
context.Response.ContentType = "application/json";
|
||||
await context.Response.WriteAsync(jsonStatus);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
_logger.LogError(exp, "OCPPMiddleware => Error: {0}", exp.Message);
|
||||
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
}
|
||||
}
|
||||
else if (cmd == "Reset")
|
||||
{
|
||||
if (!string.IsNullOrEmpty(urlChargePointId))
|
||||
{
|
||||
try
|
||||
{
|
||||
ChargePointStatus status = null;
|
||||
if (_chargePointStatusDict.TryGetValue(urlChargePointId, out status))
|
||||
{
|
||||
// Send message to chargepoint
|
||||
if (status.Protocol == Protocol_OCPP20)
|
||||
{
|
||||
// OCPP V2.0
|
||||
await Reset20(status, context, dbContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
// OCPP V1.6
|
||||
await Reset16(status, context, dbContext);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Chargepoint offline
|
||||
_logger.LogError("OCPPMiddleware SoftReset => Chargepoint offline: {0}", urlChargePointId);
|
||||
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
_logger.LogError(exp, "OCPPMiddleware SoftReset => Error: {0}", exp.Message);
|
||||
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("OCPPMiddleware SoftReset => Missing chargepoint ID");
|
||||
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||
}
|
||||
}
|
||||
else if (cmd == "UnlockConnector")
|
||||
{
|
||||
if (!string.IsNullOrEmpty(urlChargePointId))
|
||||
{
|
||||
try
|
||||
{
|
||||
ChargePointStatus status = null;
|
||||
if (_chargePointStatusDict.TryGetValue(urlChargePointId, out status))
|
||||
{
|
||||
// Send message to chargepoint
|
||||
if (status.Protocol == Protocol_OCPP20)
|
||||
{
|
||||
// OCPP V2.0
|
||||
await UnlockConnector20(status, context, dbContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
// OCPP V1.6
|
||||
await UnlockConnector16(status, context, dbContext);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Chargepoint offline
|
||||
_logger.LogError("OCPPMiddleware UnlockConnector => Chargepoint offline: {0}", urlChargePointId);
|
||||
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
_logger.LogError(exp, "OCPPMiddleware UnlockConnector => Error: {0}", exp.Message);
|
||||
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("OCPPMiddleware UnlockConnector => Missing chargepoint ID");
|
||||
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown action/function
|
||||
_logger.LogWarning("OCPPMiddleware => action/function: {0}", cmd);
|
||||
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (context.Request.Path.StartsWithSegments("/"))
|
||||
{
|
||||
try
|
||||
{
|
||||
bool showIndexInfo = _configuration.GetValue<bool>("ShowIndexInfo");
|
||||
if (showIndexInfo)
|
||||
{
|
||||
_logger.LogTrace("OCPPMiddleware => Index status page");
|
||||
|
||||
context.Response.ContentType = "text/plain";
|
||||
await context.Response.WriteAsync(string.Format("Running...\r\n\r\n{0} chargepoints connected", _chargePointStatusDict.Values.Count));
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogInformation("OCPPMiddleware => Root path with deactivated index page");
|
||||
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
_logger.LogError(exp, "OCPPMiddleware => Error: {0}", exp.Message);
|
||||
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("OCPPMiddleware => Bad path request");
|
||||
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class OCPPMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseOCPPMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<OCPPMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
||||
58
OCPP.Core.Server/Program.cs
Normal file
58
OCPP.Core.Server/Program.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* OCPP.Core - https://github.com/dallmann-consulting/OCPP.Core
|
||||
* Copyright (C) 2020-2021 dallmann consulting GmbH.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OCPP.Core.Database;
|
||||
|
||||
namespace OCPP.Core.Server
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
IConfiguration config = new ConfigurationBuilder()
|
||||
.AddJsonFile("appsettings.json", optional: false)
|
||||
.Build();
|
||||
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder
|
||||
.ConfigureLogging((ctx, builder) =>
|
||||
{
|
||||
builder.AddConfiguration(ctx.Configuration.GetSection("Logging"));
|
||||
builder.AddFile(o => o.RootPath = ctx.HostingEnvironment.ContentRootPath);
|
||||
})
|
||||
.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
}
|
||||
29
OCPP.Core.Server/Properties/launchSettings.json
Normal file
29
OCPP.Core.Server/Properties/launchSettings.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:8081",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"OCPP.Core.Server": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "weatherforecast",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "http://localhost:8081"
|
||||
}
|
||||
}
|
||||
}
|
||||
16
OCPP.Core.Server/Schema16/AuthorizeRequest.json
Normal file
16
OCPP.Core.Server/Schema16/AuthorizeRequest.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "urn:OCPP:1.6:2019:12:AuthorizeRequest",
|
||||
"title": "AuthorizeRequest",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"idTag": {
|
||||
"type": "string",
|
||||
"maxLength": 20
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"idTag"
|
||||
]
|
||||
}
|
||||
49
OCPP.Core.Server/Schema16/BootNotificationRequest.json
Normal file
49
OCPP.Core.Server/Schema16/BootNotificationRequest.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "urn:OCPP:1.6:2019:12:BootNotificationRequest",
|
||||
"title": "BootNotificationRequest",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"chargePointVendor": {
|
||||
"type": "string",
|
||||
"maxLength": 20
|
||||
},
|
||||
"chargePointModel": {
|
||||
"type": "string",
|
||||
"maxLength": 20
|
||||
},
|
||||
"chargePointSerialNumber": {
|
||||
"type": "string",
|
||||
"maxLength": 25
|
||||
},
|
||||
"chargeBoxSerialNumber": {
|
||||
"type": "string",
|
||||
"maxLength": 25
|
||||
},
|
||||
"firmwareVersion": {
|
||||
"type": "string",
|
||||
"maxLength": 50
|
||||
},
|
||||
"iccid": {
|
||||
"type": "string",
|
||||
"maxLength": 20
|
||||
},
|
||||
"imsi": {
|
||||
"type": "string",
|
||||
"maxLength": 20
|
||||
},
|
||||
"meterType": {
|
||||
"type": "string",
|
||||
"maxLength": 25
|
||||
},
|
||||
"meterSerialNumber": {
|
||||
"type": "string",
|
||||
"maxLength": 25
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"chargePointVendor",
|
||||
"chargePointModel"
|
||||
]
|
||||
}
|
||||
23
OCPP.Core.Server/Schema16/DataTransferRequest.json
Normal file
23
OCPP.Core.Server/Schema16/DataTransferRequest.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "urn:OCPP:1.6:2019:12:DataTransferRequest",
|
||||
"title": "DataTransferRequest",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"vendorId": {
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"messageId": {
|
||||
"type": "string",
|
||||
"maxLength": 50
|
||||
},
|
||||
"data": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"vendorId"
|
||||
]
|
||||
}
|
||||
8
OCPP.Core.Server/Schema16/HeartbeatRequest.json
Normal file
8
OCPP.Core.Server/Schema16/HeartbeatRequest.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "urn:OCPP:1.6:2019:12:HeartbeatRequest",
|
||||
"title": "HeartbeatRequest",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
}
|
||||
151
OCPP.Core.Server/Schema16/MeterValuesRequest.json
Normal file
151
OCPP.Core.Server/Schema16/MeterValuesRequest.json
Normal file
@@ -0,0 +1,151 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "urn:OCPP:1.6:2019:12:MeterValuesRequest",
|
||||
"title": "MeterValuesRequest",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"connectorId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"transactionId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"meterValue": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"sampledValue": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"context": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Interruption.Begin",
|
||||
"Interruption.End",
|
||||
"Sample.Clock",
|
||||
"Sample.Periodic",
|
||||
"Transaction.Begin",
|
||||
"Transaction.End",
|
||||
"Trigger",
|
||||
"Other"
|
||||
]
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Raw",
|
||||
"SignedData"
|
||||
]
|
||||
},
|
||||
"measurand": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Energy.Active.Export.Register",
|
||||
"Energy.Active.Import.Register",
|
||||
"Energy.Reactive.Export.Register",
|
||||
"Energy.Reactive.Import.Register",
|
||||
"Energy.Active.Export.Interval",
|
||||
"Energy.Active.Import.Interval",
|
||||
"Energy.Reactive.Export.Interval",
|
||||
"Energy.Reactive.Import.Interval",
|
||||
"Power.Active.Export",
|
||||
"Power.Active.Import",
|
||||
"Power.Offered",
|
||||
"Power.Reactive.Export",
|
||||
"Power.Reactive.Import",
|
||||
"Power.Factor",
|
||||
"Current.Import",
|
||||
"Current.Export",
|
||||
"Current.Offered",
|
||||
"Voltage",
|
||||
"Frequency",
|
||||
"Temperature",
|
||||
"SoC",
|
||||
"RPM"
|
||||
]
|
||||
},
|
||||
"phase": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"L1",
|
||||
"L2",
|
||||
"L3",
|
||||
"N",
|
||||
"L1-N",
|
||||
"L2-N",
|
||||
"L3-N",
|
||||
"L1-L2",
|
||||
"L2-L3",
|
||||
"L3-L1"
|
||||
]
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Cable",
|
||||
"EV",
|
||||
"Inlet",
|
||||
"Outlet",
|
||||
"Body"
|
||||
]
|
||||
},
|
||||
"unit": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Wh",
|
||||
"kWh",
|
||||
"varh",
|
||||
"kvarh",
|
||||
"W",
|
||||
"kW",
|
||||
"VA",
|
||||
"kVA",
|
||||
"var",
|
||||
"kvar",
|
||||
"A",
|
||||
"V",
|
||||
"K",
|
||||
"Celcius",
|
||||
"Celsius",
|
||||
"Fahrenheit",
|
||||
"Percent"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"value"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"timestamp",
|
||||
"sampledValue"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"connectorId",
|
||||
"meterValue"
|
||||
]
|
||||
}
|
||||
20
OCPP.Core.Server/Schema16/ResetResponse.json
Normal file
20
OCPP.Core.Server/Schema16/ResetResponse.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "urn:OCPP:1.6:2019:12:ResetResponse",
|
||||
"title": "ResetResponse",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Accepted",
|
||||
"Rejected"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
}
|
||||
32
OCPP.Core.Server/Schema16/StartTransactionRequest.json
Normal file
32
OCPP.Core.Server/Schema16/StartTransactionRequest.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "urn:OCPP:1.6:2019:12:StartTransactionRequest",
|
||||
"title": "StartTransactionRequest",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"connectorId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"idTag": {
|
||||
"type": "string",
|
||||
"maxLength": 20
|
||||
},
|
||||
"meterStart": {
|
||||
"type": "integer"
|
||||
},
|
||||
"reservationId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"connectorId",
|
||||
"idTag",
|
||||
"meterStart",
|
||||
"timestamp"
|
||||
]
|
||||
}
|
||||
70
OCPP.Core.Server/Schema16/StatusNotificationRequest.json
Normal file
70
OCPP.Core.Server/Schema16/StatusNotificationRequest.json
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "urn:OCPP:1.6:2019:12:StatusNotificationRequest",
|
||||
"title": "StatusNotificationRequest",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"connectorId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"errorCode": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"ConnectorLockFailure",
|
||||
"EVCommunicationError",
|
||||
"GroundFailure",
|
||||
"HighTemperature",
|
||||
"InternalError",
|
||||
"LocalListConflict",
|
||||
"NoError",
|
||||
"OtherError",
|
||||
"OverCurrentFailure",
|
||||
"PowerMeterFailure",
|
||||
"PowerSwitchFailure",
|
||||
"ReaderFailure",
|
||||
"ResetFailure",
|
||||
"UnderVoltage",
|
||||
"OverVoltage",
|
||||
"WeakSignal"
|
||||
]
|
||||
},
|
||||
"info": {
|
||||
"type": "string",
|
||||
"maxLength": 50
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Available",
|
||||
"Preparing",
|
||||
"Charging",
|
||||
"SuspendedEVSE",
|
||||
"SuspendedEV",
|
||||
"Finishing",
|
||||
"Reserved",
|
||||
"Unavailable",
|
||||
"Faulted"
|
||||
]
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"vendorId": {
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"vendorErrorCode": {
|
||||
"type": "string",
|
||||
"maxLength": 50
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"connectorId",
|
||||
"errorCode",
|
||||
"status"
|
||||
]
|
||||
}
|
||||
176
OCPP.Core.Server/Schema16/StopTransactionRequest.json
Normal file
176
OCPP.Core.Server/Schema16/StopTransactionRequest.json
Normal file
@@ -0,0 +1,176 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "urn:OCPP:1.6:2019:12:StopTransactionRequest",
|
||||
"title": "StopTransactionRequest",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"idTag": {
|
||||
"type": "string",
|
||||
"maxLength": 20
|
||||
},
|
||||
"meterStop": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"transactionId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"EmergencyStop",
|
||||
"EVDisconnected",
|
||||
"HardReset",
|
||||
"Local",
|
||||
"Other",
|
||||
"PowerLoss",
|
||||
"Reboot",
|
||||
"Remote",
|
||||
"SoftReset",
|
||||
"UnlockCommand",
|
||||
"DeAuthorized"
|
||||
]
|
||||
},
|
||||
"transactionData": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"sampledValue": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"context": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Interruption.Begin",
|
||||
"Interruption.End",
|
||||
"Sample.Clock",
|
||||
"Sample.Periodic",
|
||||
"Transaction.Begin",
|
||||
"Transaction.End",
|
||||
"Trigger",
|
||||
"Other"
|
||||
]
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Raw",
|
||||
"SignedData"
|
||||
]
|
||||
},
|
||||
"measurand": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Energy.Active.Export.Register",
|
||||
"Energy.Active.Import.Register",
|
||||
"Energy.Reactive.Export.Register",
|
||||
"Energy.Reactive.Import.Register",
|
||||
"Energy.Active.Export.Interval",
|
||||
"Energy.Active.Import.Interval",
|
||||
"Energy.Reactive.Export.Interval",
|
||||
"Energy.Reactive.Import.Interval",
|
||||
"Power.Active.Export",
|
||||
"Power.Active.Import",
|
||||
"Power.Offered",
|
||||
"Power.Reactive.Export",
|
||||
"Power.Reactive.Import",
|
||||
"Power.Factor",
|
||||
"Current.Import",
|
||||
"Current.Export",
|
||||
"Current.Offered",
|
||||
"Voltage",
|
||||
"Frequency",
|
||||
"Temperature",
|
||||
"SoC",
|
||||
"RPM"
|
||||
]
|
||||
},
|
||||
"phase": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"L1",
|
||||
"L2",
|
||||
"L3",
|
||||
"N",
|
||||
"L1-N",
|
||||
"L2-N",
|
||||
"L3-N",
|
||||
"L1-L2",
|
||||
"L2-L3",
|
||||
"L3-L1"
|
||||
]
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Cable",
|
||||
"EV",
|
||||
"Inlet",
|
||||
"Outlet",
|
||||
"Body"
|
||||
]
|
||||
},
|
||||
"unit": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Wh",
|
||||
"kWh",
|
||||
"varh",
|
||||
"kvarh",
|
||||
"W",
|
||||
"kW",
|
||||
"VA",
|
||||
"kVA",
|
||||
"var",
|
||||
"kvar",
|
||||
"A",
|
||||
"V",
|
||||
"K",
|
||||
"Celcius",
|
||||
"Fahrenheit",
|
||||
"Percent"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"value"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"timestamp",
|
||||
"sampledValue"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"transactionId",
|
||||
"timestamp",
|
||||
"meterStop"
|
||||
]
|
||||
}
|
||||
21
OCPP.Core.Server/Schema16/UnlockConnectorResponse.json
Normal file
21
OCPP.Core.Server/Schema16/UnlockConnectorResponse.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "urn:OCPP:1.6:2019:12:UnlockConnectorResponse",
|
||||
"title": "UnlockConnectorResponse",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Unlocked",
|
||||
"UnlockFailed",
|
||||
"NotSupported"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
}
|
||||
171
OCPP.Core.Server/Schema20/AuthorizeRequest.json
Normal file
171
OCPP.Core.Server/Schema20/AuthorizeRequest.json
Normal file
@@ -0,0 +1,171 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-06/schema#",
|
||||
"$id": "urn:OCPP:Cp:2:2020:3:AuthorizeRequest",
|
||||
"comment": "OCPP 2.0.1 FINAL",
|
||||
"definitions": {
|
||||
"CustomDataType": {
|
||||
"description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.",
|
||||
"javaType": "CustomData",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"vendorId": {
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"vendorId"
|
||||
]
|
||||
},
|
||||
"HashAlgorithmEnumType": {
|
||||
"description": "Used algorithms for the hashes provided.\r\n",
|
||||
"javaType": "HashAlgorithmEnum",
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"SHA256",
|
||||
"SHA384",
|
||||
"SHA512"
|
||||
]
|
||||
},
|
||||
"IdTokenEnumType": {
|
||||
"description": "Enumeration of possible idToken types.\r\n",
|
||||
"javaType": "IdTokenEnum",
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"Central",
|
||||
"eMAID",
|
||||
"ISO14443",
|
||||
"ISO15693",
|
||||
"KeyCode",
|
||||
"Local",
|
||||
"MacAddress",
|
||||
"NoAuthorization"
|
||||
]
|
||||
},
|
||||
"AdditionalInfoType": {
|
||||
"description": "Contains a case insensitive identifier to use for the authorization and the type of authorization to support multiple forms of identifiers.\r\n",
|
||||
"javaType": "AdditionalInfo",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"customData": {
|
||||
"$ref": "#/definitions/CustomDataType"
|
||||
},
|
||||
"additionalIdToken": {
|
||||
"description": "This field specifies the additional IdToken.\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 36
|
||||
},
|
||||
"type": {
|
||||
"description": "This defines the type of the additionalIdToken. This is a custom type, so the implementation needs to be agreed upon by all involved parties.\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 50
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"additionalIdToken",
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"IdTokenType": {
|
||||
"description": "Contains a case insensitive identifier to use for the authorization and the type of authorization to support multiple forms of identifiers.\r\n",
|
||||
"javaType": "IdToken",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"customData": {
|
||||
"$ref": "#/definitions/CustomDataType"
|
||||
},
|
||||
"additionalInfo": {
|
||||
"type": "array",
|
||||
"additionalItems": false,
|
||||
"items": {
|
||||
"$ref": "#/definitions/AdditionalInfoType"
|
||||
},
|
||||
"minItems": 1
|
||||
},
|
||||
"idToken": {
|
||||
"description": "IdToken is case insensitive. Might hold the hidden id of an RFID tag, but can for example also contain a UUID.\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 36
|
||||
},
|
||||
"type": {
|
||||
"$ref": "#/definitions/IdTokenEnumType"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"idToken",
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"OCSPRequestDataType": {
|
||||
"javaType": "OCSPRequestData",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"customData": {
|
||||
"$ref": "#/definitions/CustomDataType"
|
||||
},
|
||||
"hashAlgorithm": {
|
||||
"$ref": "#/definitions/HashAlgorithmEnumType"
|
||||
},
|
||||
"issuerNameHash": {
|
||||
"description": "Hashed value of the Issuer DN (Distinguished Name).\r\n\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
},
|
||||
"issuerKeyHash": {
|
||||
"description": "Hashed value of the issuers public key\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
},
|
||||
"serialNumber": {
|
||||
"description": "The serial number of the certificate.\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 40
|
||||
},
|
||||
"responderURL": {
|
||||
"description": "This contains the responder URL (Case insensitive). \r\n\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 512
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"hashAlgorithm",
|
||||
"issuerNameHash",
|
||||
"issuerKeyHash",
|
||||
"serialNumber",
|
||||
"responderURL"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"customData": {
|
||||
"$ref": "#/definitions/CustomDataType"
|
||||
},
|
||||
"idToken": {
|
||||
"$ref": "#/definitions/IdTokenType"
|
||||
},
|
||||
"certificate": {
|
||||
"description": "The X.509 certificated presented by EV and encoded in PEM format.\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 5500
|
||||
},
|
||||
"iso15118CertificateHashData": {
|
||||
"type": "array",
|
||||
"additionalItems": false,
|
||||
"items": {
|
||||
"$ref": "#/definitions/OCSPRequestDataType"
|
||||
},
|
||||
"minItems": 1,
|
||||
"maxItems": 4
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"idToken"
|
||||
]
|
||||
}
|
||||
114
OCPP.Core.Server/Schema20/BootNotificationRequest.json
Normal file
114
OCPP.Core.Server/Schema20/BootNotificationRequest.json
Normal file
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-06/schema#",
|
||||
"$id": "urn:OCPP:Cp:2:2020:3:BootNotificationRequest",
|
||||
"comment": "OCPP 2.0.1 FINAL",
|
||||
"definitions": {
|
||||
"CustomDataType": {
|
||||
"description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.",
|
||||
"javaType": "CustomData",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"vendorId": {
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"vendorId"
|
||||
]
|
||||
},
|
||||
"BootReasonEnumType": {
|
||||
"description": "This contains the reason for sending this message to the CSMS.\r\n",
|
||||
"javaType": "BootReasonEnum",
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"ApplicationReset",
|
||||
"FirmwareUpdate",
|
||||
"LocalReset",
|
||||
"PowerUp",
|
||||
"RemoteReset",
|
||||
"ScheduledReset",
|
||||
"Triggered",
|
||||
"Unknown",
|
||||
"Watchdog"
|
||||
]
|
||||
},
|
||||
"ChargingStationType": {
|
||||
"description": "Charge_ Point\r\nurn:x-oca:ocpp:uid:2:233122\r\nThe physical system where an Electrical Vehicle (EV) can be charged.\r\n",
|
||||
"javaType": "ChargingStation",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"customData": {
|
||||
"$ref": "#/definitions/CustomDataType"
|
||||
},
|
||||
"serialNumber": {
|
||||
"description": "Device. Serial_ Number. Serial_ Number\r\nurn:x-oca:ocpp:uid:1:569324\r\nVendor-specific device identifier.\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 25
|
||||
},
|
||||
"model": {
|
||||
"description": "Device. Model. CI20_ Text\r\nurn:x-oca:ocpp:uid:1:569325\r\nDefines the model of the device.\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 20
|
||||
},
|
||||
"modem": {
|
||||
"$ref": "#/definitions/ModemType"
|
||||
},
|
||||
"vendorName": {
|
||||
"description": "Identifies the vendor (not necessarily in a unique manner).\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 50
|
||||
},
|
||||
"firmwareVersion": {
|
||||
"description": "This contains the firmware version of the Charging Station.\r\n\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 50
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"model",
|
||||
"vendorName"
|
||||
]
|
||||
},
|
||||
"ModemType": {
|
||||
"description": "Wireless_ Communication_ Module\r\nurn:x-oca:ocpp:uid:2:233306\r\nDefines parameters required for initiating and maintaining wireless communication with other devices.\r\n",
|
||||
"javaType": "Modem",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"customData": {
|
||||
"$ref": "#/definitions/CustomDataType"
|
||||
},
|
||||
"iccid": {
|
||||
"description": "Wireless_ Communication_ Module. ICCID. CI20_ Text\r\nurn:x-oca:ocpp:uid:1:569327\r\nThis contains the ICCID of the modem’s SIM card.\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 20
|
||||
},
|
||||
"imsi": {
|
||||
"description": "Wireless_ Communication_ Module. IMSI. CI20_ Text\r\nurn:x-oca:ocpp:uid:1:569328\r\nThis contains the IMSI of the modem’s SIM card.\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"customData": {
|
||||
"$ref": "#/definitions/CustomDataType"
|
||||
},
|
||||
"chargingStation": {
|
||||
"$ref": "#/definitions/ChargingStationType"
|
||||
},
|
||||
"reason": {
|
||||
"$ref": "#/definitions/BootReasonEnumType"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"reason",
|
||||
"chargingStation"
|
||||
]
|
||||
}
|
||||
50
OCPP.Core.Server/Schema20/ClearedChargingLimitRequest.json
Normal file
50
OCPP.Core.Server/Schema20/ClearedChargingLimitRequest.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-06/schema#",
|
||||
"$id": "urn:OCPP:Cp:2:2020:3:ClearedChargingLimitRequest",
|
||||
"comment": "OCPP 2.0.1 FINAL",
|
||||
"definitions": {
|
||||
"CustomDataType": {
|
||||
"description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.",
|
||||
"javaType": "CustomData",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"vendorId": {
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"vendorId"
|
||||
]
|
||||
},
|
||||
"ChargingLimitSourceEnumType": {
|
||||
"description": "Source of the charging limit.\r\n",
|
||||
"javaType": "ChargingLimitSourceEnum",
|
||||
"type": "string",
|
||||
"additionalProperties": false,
|
||||
"enum": [
|
||||
"EMS",
|
||||
"Other",
|
||||
"SO",
|
||||
"CSO"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"customData": {
|
||||
"$ref": "#/definitions/CustomDataType"
|
||||
},
|
||||
"chargingLimitSource": {
|
||||
"$ref": "#/definitions/ChargingLimitSourceEnumType"
|
||||
},
|
||||
"evseId": {
|
||||
"description": "EVSE Identifier.\r\n",
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"chargingLimitSource"
|
||||
]
|
||||
}
|
||||
44
OCPP.Core.Server/Schema20/DataTransferRequest.json
Normal file
44
OCPP.Core.Server/Schema20/DataTransferRequest.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-06/schema#",
|
||||
"$id": "urn:OCPP:Cp:2:2020:3:DataTransferRequest",
|
||||
"comment": "OCPP 2.0.1 FINAL",
|
||||
"definitions": {
|
||||
"CustomDataType": {
|
||||
"description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.",
|
||||
"javaType": "CustomData",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"vendorId": {
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"vendorId"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"customData": {
|
||||
"$ref": "#/definitions/CustomDataType"
|
||||
},
|
||||
"messageId": {
|
||||
"description": "May be used to indicate a specific message or implementation.\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 50
|
||||
},
|
||||
"data": {
|
||||
"description": "Data without specified length or format. This needs to be decided by both parties (Open to implementation).\r\n"
|
||||
},
|
||||
"vendorId": {
|
||||
"description": "This identifies the Vendor specific implementation\r\n\r\n",
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"vendorId"
|
||||
]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user