Skip to content

Commit

Permalink
Merge pull request #35 from JMolenkamp/feat-simulator-support
Browse files Browse the repository at this point in the history
feat: add simulator driver support
  • Loading branch information
perkops authored Jun 20, 2024
2 parents 5828858 + 023c932 commit b3f760b
Show file tree
Hide file tree
Showing 19 changed files with 436 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Atc.Kepware.Configuration.Contracts.Connectivity.Drivers.Simulator;

public sealed class SimulatorChannel : ChannelBase, ISimulatorChannel
{
public bool ItemPersistence { get; set; }

public string ItemPersistenceDataFile { get; set; } = string.Empty;

public override string ToString()
=> $"{base.ToString()}, {nameof(ItemPersistence)}: {ItemPersistence}, {nameof(ItemPersistenceDataFile)}: {ItemPersistenceDataFile}";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Atc.Kepware.Configuration.Contracts.Connectivity.Drivers.Simulator;

/// <summary>
/// Channel properties for the Simulator driver.
/// </summary>
public sealed class SimulatorChannelRequest : ChannelRequestBase, ISimulatorChannelRequest
{
public SimulatorChannelRequest()
: base(DriverType.Simulator)
{
}

/// <inheritdoc />
public bool ItemPersistence { get; set; }

/// <inheritdoc />
public string? ItemPersistenceDataFile { get; set; }

/// <inheritdoc />
public override string ToString()
=> $"{base.ToString()}, {nameof(ItemPersistence)}: {ItemPersistence}, {nameof(ItemPersistenceDataFile)}: {ItemPersistenceDataFile}";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Atc.Kepware.Configuration.Contracts.Connectivity.Drivers.Simulator;

public sealed class SimulatorDevice : DeviceBase, ISimulatorDevice
{
public SimulatorDevice()
{
// The driver does not actually support this property, simulating a simulator makes no sense.
Simulated = true;
}

public SimulatorDeviceModel? Model { get; set; }

public int Id { get; set; } = 1;

public SimulatorDeviceIdFormat IdFormat { get; set; } = SimulatorDeviceIdFormat.Decimal;

public override string ToString()
=> $"{base.ToString()}, {nameof(Model)}: {Model}, {nameof(Id)}: {Id}, {nameof(IdFormat)}: {IdFormat}";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace Atc.Kepware.Configuration.Contracts.Connectivity.Drivers.Simulator;

public sealed class SimulatorDeviceRequest : DeviceRequestBase, ISimulatorDeviceRequest
{
public SimulatorDeviceRequest()
: base(DriverType.Simulator)
{
// The driver does not actually support this property, simulating a simulator makes no sense.
Simulated = true;
}

/// <inheritdoc />
public SimulatorDeviceModel Model { get; set; } = SimulatorDeviceModel.SixteenBit;

/// <inheritdoc />
[Range(1, 999)]
public int Id { get; set; } = 1;

/// <inheritdoc />
public SimulatorDeviceIdFormat IdFormat { get; set; } = SimulatorDeviceIdFormat.Decimal;

// <inheritdoc />
public override string ToString()
=> $"{base.ToString()}, {nameof(Model)}: {Model}, {nameof(Id)}: {Id}, {nameof(IdFormat)}: {IdFormat}";
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ public enum DriverType

[Description("OPC UA Client")]
OpcUaClient,

[Description("Simulator")]
Simulator,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// ReSharper disable CheckNamespace
namespace Atc.Kepware.Configuration.Contracts;

/// <summary>
/// Indicate the format of the device ID (set by the driver by default).
/// </summary>
/// <remarks>
/// Ref: https://{ip}:{port}/config/v1/doc/drivers/Simulator/devices
/// Section: servermain.DEVICE_ID_FORMAT
/// </remarks>
[SuppressMessage("Naming", "CA1720:Identifier contains type name", Justification = "Actually means that an integer is formatted as a decimal value")]
public enum SimulatorDeviceIdFormat
{
/// <summary>
/// Format the device ID as an octal value.
/// </summary>
Octal = 0,

/// <summary>
/// Format the device ID as a decimal value.
/// </summary>
Decimal = 1,

/// <summary>
/// Format the device ID as a hexadecimal value.
/// </summary>
Hexadecimal = 2,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// ReSharper disable CheckNamespace
namespace Atc.Kepware.Configuration.Contracts;

/// <summary>
/// Select the specific type of device associated with this ID. Options depend on the type of communications in use.
/// </summary>
/// <remarks>
/// Ref: https://{ip}:{port}/config/v1/doc/drivers/Simulator/devices
/// Section: servermain.DEVICE_MODEL
/// </remarks>
public enum SimulatorDeviceModel
{
/// <summary>
/// 16 bit device
/// </summary>
SixteenBit = 0,

/// <summary>
/// 8 bit device
/// </summary>
EightBit = 1,
}
1 change: 1 addition & 0 deletions src/Atc.Kepware.Configuration.Contracts/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
global using Atc.Kepware.Configuration.Contracts.Interfaces.Connectivity;
global using Atc.Kepware.Configuration.Contracts.Interfaces.Connectivity.EuroMap63;
global using Atc.Kepware.Configuration.Contracts.Interfaces.Connectivity.OpcUaClient;
global using Atc.Kepware.Configuration.Contracts.Interfaces.Connectivity.Simulator;
global using Atc.Kepware.Configuration.Contracts.Interfaces.IotGateway;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Atc.Kepware.Configuration.Contracts.Interfaces.Connectivity.Simulator;

public interface ISimulatorChannel : IChannelBase
{
bool ItemPersistence { get; set; }

string ItemPersistenceDataFile { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Atc.Kepware.Configuration.Contracts.Interfaces.Connectivity.Simulator;

/// <summary>
/// Channel properties for the Simulator driver.
/// </summary>
public interface ISimulatorChannelRequest : IChannelRequestBase
{
/// <summary>
/// Enable this option to save on shutdown and restore on startup of R, K, and S address contents.
/// </summary>
bool ItemPersistence { get; set; }

/// <summary>
/// The path and file name where item persistence data should be saved.
/// </summary>
string? ItemPersistenceDataFile { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Atc.Kepware.Configuration.Contracts.Interfaces.Connectivity.Simulator;

public interface ISimulatorDevice : IDeviceBase
{
SimulatorDeviceModel? Model { get; set; }

int Id { get; set; }

SimulatorDeviceIdFormat IdFormat { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace Atc.Kepware.Configuration.Contracts.Interfaces.Connectivity.Simulator;

public interface ISimulatorDeviceRequest
{
/// <summary>
/// The specific type of device.
/// </summary>
SimulatorDeviceModel Model { get; set; }

/// <summary>
/// Device identifier within the channel.
/// </summary>
/// <remarks>
/// It is possible to have multiple devices with the same identifier within a channel. The <see cref="Model"/>
/// for those devices must be the same. Devices within a channel having the same identifier will share the same
/// address space.
/// </remarks>
int Id { get; set; }

/// <summary>
/// The format of the device identifier.
/// </summary>
/// <remarks>
/// Does not seem to serve any other purpose than for display in the device properties in the configurator.
/// </remarks>
SimulatorDeviceIdFormat IdFormat { get; set; }
}
2 changes: 2 additions & 0 deletions src/Atc.Kepware.Configuration/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
global using Atc.Kepware.Configuration.Contracts.Connectivity;
global using Atc.Kepware.Configuration.Contracts.Connectivity.Drivers.EuroMap63;
global using Atc.Kepware.Configuration.Contracts.Connectivity.Drivers.OpcUaClient;
global using Atc.Kepware.Configuration.Contracts.Connectivity.Drivers.Simulator;
global using Atc.Kepware.Configuration.Contracts.Interfaces.Connectivity;
global using Atc.Kepware.Configuration.Contracts.Interfaces.Connectivity.EuroMap63;
global using Atc.Kepware.Configuration.Contracts.Interfaces.Connectivity.OpcUaClient;
global using Atc.Kepware.Configuration.Contracts.Interfaces.Connectivity.Simulator;
global using Atc.Kepware.Configuration.Contracts.Interfaces.IotGateway;
global using Atc.Kepware.Configuration.Contracts.IotGateway;
global using Atc.Serialization;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Atc.Kepware.Configuration.KepwareContracts.Connectivity.Simulator;

/// <summary>
/// Channel properties for the Simulator driver.
/// </summary>
internal class SimulatorChannel : ChannelBase, ISimulatorChannel
{
/// <inheritdoc />
[JsonPropertyName("simulator.CHANNEL_ITEM_PERSISTENCE")]
public bool ItemPersistence { get; set; }

/// <inheritdoc />
[JsonPropertyName("simulator.CHANNEL_ITEM_PERSISTENCE_DATA_FILE")]
public string ItemPersistenceDataFile { get; set; } = string.Empty;

public override string ToString()
=> $"{base.ToString()}, {nameof(ItemPersistence)}: {ItemPersistence}, {nameof(ItemPersistenceDataFile)}: {ItemPersistenceDataFile}";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Atc.Kepware.Configuration.KepwareContracts.Connectivity.Simulator;

/// <summary>
/// Channel properties for the Simulator driver.
/// </summary>
internal class SimulatorChannelRequest : ChannelRequestBase, ISimulatorChannelRequest
{
public SimulatorChannelRequest()
: base(DriverType.Simulator)
{
}

[JsonPropertyName("simulator.CHANNEL_ITEM_PERSISTENCE")]
public bool ItemPersistence { get; set; }

[JsonPropertyName("simulator.CHANNEL_ITEM_PERSISTENCE_DATA_FILE")]
public string? ItemPersistenceDataFile { get; set; }

/// <inheritdoc />
public override string ToString()
=> $"{base.ToString()}, {nameof(ItemPersistence)}: {ItemPersistence}, {nameof(ItemPersistenceDataFile)}: {ItemPersistenceDataFile}";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace Atc.Kepware.Configuration.KepwareContracts.Connectivity.Simulator;

internal class SimulatorDevice : DeviceBase, ISimulatorDevice
{
public SimulatorDevice()
{
// The driver does not actually support this property, simulating a simulator makes no sense.
Simulated = true;
}

/// <inheritdoc />
[JsonPropertyName("servermain.DEVICE_MODEL")]
public SimulatorDeviceModel? Model { get; set; }

/// <inheritdoc />
[JsonPropertyName("servermain.DEVICE_ID_DECIMAL")]
public int Id { get; set; } = 1;

/// <inheritdoc />
[JsonPropertyName("servermain.DEVICE_ID_FORMAT")]
public SimulatorDeviceIdFormat IdFormat { get; set; } = SimulatorDeviceIdFormat.Decimal;

public override string ToString()
=> $"{base.ToString()}, {nameof(Model)}: {Model}, {nameof(Id)}: {Id}, {nameof(IdFormat)}: {IdFormat}";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace Atc.Kepware.Configuration.KepwareContracts.Connectivity.Simulator;

internal class SimulatorDeviceRequest : DeviceRequestBase, ISimulatorDeviceRequest
{
public SimulatorDeviceRequest()
: base(DriverType.Simulator)
{
// The driver does not actually support this property, simulating a simulator makes no sense.
Simulated = true;
}

/// <inheritdoc />
[JsonPropertyName("servermain.DEVICE_MODEL")]
public SimulatorDeviceModel Model { get; set; } = SimulatorDeviceModel.SixteenBit;

/// <inheritdoc />
[Range(1, 999)]
[JsonIgnore]
public int Id { get; set; } = 1;

[JsonPropertyName("servermain.DEVICE_ID_FORMAT")]
public SimulatorDeviceIdFormat IdFormat { get; set; } = SimulatorDeviceIdFormat.Decimal;

[JsonPropertyName("servermain.DEVICE_ID_OCTAL")]
public int OctalId => Id;

[JsonPropertyName("servermain.DEVICE_ID_DECIMAL")]
public int DecimalId => Id;

[JsonPropertyName("servermain.DEVICE_ID_HEXADECIMAL")]
public int HexadecimalId => Id;

public override string ToString()
=> $"{base.ToString()}, {nameof(Model)}: {Model}, {nameof(Id)}: {Id}, {nameof(IdFormat)}: {IdFormat}";
}
Loading

0 comments on commit b3f760b

Please sign in to comment.