Skip to content

Commit

Permalink
Add read and write array support to sandbox
Browse files Browse the repository at this point in the history
  • Loading branch information
Vectron committed Oct 15, 2024
1 parent 9f03e67 commit 9ab8690
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 19 deletions.
17 changes: 16 additions & 1 deletion src/PlcInterface.Sandbox/PLCCommands/AdsWriteCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,22 @@ protected override object ConvertToValidInputValue(string symbolName, string val

if (symbolInfo.IsArray)
{
throw new InvalidOperationException("Arrays are not supported");
if (!value.StartsWith('[') || !value.EndsWith(']'))
{
throw new InvalidOperationException("Arrays must have the following syntax: ['values']");
}

if (symbolInfo.Symbol is not IArrayInstance arrayInstance
|| arrayInstance.ElementType is not TwinCAT.Ads.TypeSystem.DataType elementDataType
|| elementDataType.ManagedType == null)
{
throw new InvalidOperationException("Unable to read data type.");
}

return value[1..^1]
.Split(',')
.Select(x => typeConverter.Convert(x, elementDataType.ManagedType))
.ToArray();
}

if (symbolInfo.IsBigType)
Expand Down
25 changes: 17 additions & 8 deletions src/PlcInterface.Sandbox/PLCCommands/OpcWriteCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,30 @@ protected override object ConvertToValidInputValue(string symbolName, string val

if (symbolInfo.IsArray)
{
throw new InvalidOperationException("Arrays are not supported");
if (!value.StartsWith('[') || !value.EndsWith(']'))
{
throw new InvalidOperationException("Arrays must have the following syntax: ['values']");
}

return value[1..^1]
.Split(',')
.Select(x => ConvertToManagedType(symbolInfo.BuiltInType, x))
.ToArray();
}

if (symbolInfo.IsBigType)
{
throw new InvalidOperationException("object types are not supported");
}

var boxedValue = symbolInfo.BuiltInType switch
return ConvertToManagedType(symbolInfo.BuiltInType, value)
?? throw new InvalidOperationException("Unknown data type");
}

private object? ConvertToManagedType(Opc.Ua.BuiltInType builtInType, object value)
=> builtInType switch
{
Opc.Ua.BuiltInType.Boolean => (object)typeConverter.Convert<bool>(value),
Opc.Ua.BuiltInType.Boolean => typeConverter.Convert<bool>(value),
Opc.Ua.BuiltInType.SByte => typeConverter.Convert<sbyte>(value),
Opc.Ua.BuiltInType.Byte => typeConverter.Convert<byte>(value),
Opc.Ua.BuiltInType.Int16 => typeConverter.Convert<short>(value),
Expand All @@ -60,11 +73,7 @@ protected override object ConvertToValidInputValue(string symbolName, string val
Opc.Ua.BuiltInType.Variant => null,
Opc.Ua.BuiltInType.DiagnosticInfo => null,
Opc.Ua.BuiltInType.Number => null,
Opc.Ua.BuiltInType.Enumeration => typeConverter.Convert<int>(value),
Opc.Ua.BuiltInType.Enumeration => null,
_ => null,
};

return boxedValue
?? throw new InvalidOperationException("Unknown data type");
}
}
63 changes: 53 additions & 10 deletions src/PlcInterface.Sandbox/PLCCommands/PlcReadCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,19 @@ public void Execute(string[] arguments)
var builder = new StringBuilder()
.Append(symbolName)
.Append(": ");
_ = value is IDictionary<string, object?> multiValues
? builder.AppendLine().Append(ObjectToString(multiValues, 1))
: builder.Append(value);

if (value is IDictionary<string, object?> multiValues)
{
ObjectToString(builder, multiValues, 1);
}
else if (value is Array array)
{
ArrayToString(builder, array, 1);
}
else
{
_ = builder.Append(value);
}

Console.WriteLine(builder);
}
Expand All @@ -62,26 +72,59 @@ public void Execute(string[] arguments)
}
}

private static string ObjectToString(IDictionary<string, object?> parameters, int indentation = 0)
private static void ArrayToString(StringBuilder builder, Array array, int indentation = 0)
{
var prefix = string.Join(string.Empty, Enumerable.Repeat(" ", indentation));
foreach (var indices in IndicesHelper.GetIndices(array))
{
_ = builder
.AppendLine()
.Append(prefix)
.Append('[')
.Append(indices[0]);

for (var i = 1; i < indices.Length; i++)
{
_ = builder
.Append(", ")
.Append(indices[i]);
}

_ = builder
.Append("]: ");

try
{
var itemValue = array.GetValue(indices)?.ToString() ?? "Null";
_ = builder.Append(itemValue);
}
catch (IndexOutOfRangeException)
{
_ = builder.Append("Out of range");
}
}
}

private static void ObjectToString(StringBuilder builder, IDictionary<string, object?> parameters, int indentation = 0)
{
var builder = new StringBuilder();
var prefix = string.Join(string.Empty, Enumerable.Repeat(" ", indentation));
foreach (var (key, value) in parameters)
{
_ = builder.Append(prefix)
_ = builder
.Append(prefix)
.Append(key)
.Append(": ");

if (value is IDictionary<string, object?> dictionary)
{
_ = builder.AppendLine()
.Append(ObjectToString(dictionary, indentation + 1));
_ = builder
.AppendLine();

ObjectToString(builder, dictionary, indentation + 1);
continue;
}

_ = builder.AppendLine(value?.ToString());
}

return builder.ToString();
}
}
4 changes: 4 additions & 0 deletions src/PlcInterface.Sandbox/PlcInterface.Sandbox.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<Compile Include="$(CommonDirectory)\IndicesHelper.cs" LinkBase="Common" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Vectron.Extensions.Logging.Console.Formatter" Version="1.0.48" />
<PackageReference Include="Vectron.InteractiveConsole" Version="1.0.68" />
Expand Down

0 comments on commit 9ab8690

Please sign in to comment.