add more checking in configuration, fix issue #55
This commit is contained in:
Stephen Chen (ManPower) 2018-09-11 12:13:01 +08:00
Родитель fdcf70df2c
Коммит 582bf225a8
5 изменённых файлов: 111 добавлений и 58 удалений

Просмотреть файл

@ -1,4 +1,4 @@
FROM microsoft/dotnet:2.0-sdk AS build-env
FROM microsoft/dotnet:2.1-sdk AS build-env
WORKDIR /app
COPY *.csproj ./
@ -17,7 +17,7 @@ COPY *.h ./
# build
RUN gcc -shared -o libcomWrapper.so -fPIC comWrapper.c
FROM microsoft/dotnet:2.0-runtime
FROM microsoft/dotnet:2.1-runtime
WORKDIR /app
COPY --from=build-env /app/out ./
COPY --from=build-env-2 /app/libcomWrapper.so /usr/lib/

Просмотреть файл

@ -8,7 +8,7 @@ RUN useradd -ms /bin/bash moduleuser
USER moduleuser
RUN curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l ~/vsdbg
FROM microsoft/dotnet:2.0-sdk AS build-env
FROM microsoft/dotnet:2.1-sdk AS build-env
WORKDIR /app
COPY *.csproj ./

Просмотреть файл

@ -357,7 +357,7 @@
{
ReceiveTimeout = 100
};
await m_socket.ConnectAsync(m_address, config.TcpPort);
await m_socket.ConnectAsync(m_address, config.TcpPort.Value);
}
catch (Exception e)
{
@ -499,7 +499,7 @@
while(m_socket.Available <= 0 && retry < config.RetryCount)
{
retry++;
Task.Delay(config.RetryInterval).Wait();
Task.Delay(config.RetryInterval.Value).Wait();
}
while (header_len < m_dataBodyOffset && retry < config.RetryCount)
@ -577,7 +577,6 @@
ReleaseOperations();
if (m_serialPort != null)
{
m_serialPort.Close();
m_serialPort.Dispose();
m_serialPort = null;
}
@ -593,7 +592,7 @@
{
Console.WriteLine($"Opening...{config.SlaveConnection}");
m_serialPort = SerialDeviceFactory.CreateSerialDevice(config.SlaveConnection, (int)config.BaudRate, config.Parity, (int)config.DataBits, config.StopBits);
m_serialPort = SerialDeviceFactory.CreateSerialDevice(config.SlaveConnection, (int)config.BaudRate.Value, config.Parity.Value, (int)config.DataBits.Value, config.StopBits.Value);
m_serialPort.Open();
//m_serialPort.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
@ -685,7 +684,6 @@
{
Console.WriteLine("Something wrong with the connection, disposing...");
Console.WriteLine(e.Message);
m_serialPort.Close();
m_serialPort.Dispose();
m_serialPort = null;
Console.WriteLine("Connection lost, reconnecting...");
@ -721,7 +719,7 @@
else
{
retry++;
Task.Delay(config.RetryInterval).Wait();
Task.Delay(config.RetryInterval.Value).Wait();
}
}
@ -736,7 +734,7 @@
else
{
retry++;
Task.Delay(config.RetryInterval).Wait();
Task.Delay(config.RetryInterval.Value).Wait();
}
}
@ -786,14 +784,14 @@
class BaseModbusSlaveConfig
{
public string SlaveConnection { get; set; }
public int RetryCount { get; set; }
public int RetryInterval { get; set; }
public int TcpPort { get; set; }
public int? RetryCount { get; set; }
public int? RetryInterval { get; set; }
public int? TcpPort { get; set; }
public string HwId { get; set; }
public uint BaudRate { get; set; }
public StopBits StopBits { get; set; }
public byte DataBits { get; set; }
public Parity Parity { get; set; }
public uint? BaudRate { get; set; }
public StopBits? StopBits { get; set; }
public byte? DataBits { get; set; }
public Parity? Parity { get; set; }
//public byte FlowControl { get; set; }
public Dictionary<string, BaseReadOperation> Operations = null;
}
@ -942,63 +940,86 @@
{
SlaveConfigs = slaves;
}
public bool IsValidate()
public void Validate()
{
bool ret = true;
List<string> invalidConfigs = new List<string>();
foreach (var config_pair in SlaveConfigs)
{
ModbusSlaveConfig slaveConfig = config_pair.Value;
if (slaveConfig.TcpPort <= 0)
if(slaveConfig == null)
{
Console.WriteLine($"{config_pair.Key} is null, remove from dictionary...");
invalidConfigs.Add(config_pair.Key);
continue;
}
if (slaveConfig.TcpPort == null || slaveConfig.TcpPort <= 0)
{
Console.WriteLine($"Invalid TcpPort: {slaveConfig.TcpPort}, set to DefaultTcpPort: {ModbusConstants.DefaultTcpPort}");
slaveConfig.TcpPort = ModbusConstants.DefaultTcpPort;
}
if (slaveConfig.RetryCount <= 0)
if (slaveConfig.RetryCount == null || slaveConfig.RetryCount <= 0)
{
Console.WriteLine($"Invalid RetryCount: {slaveConfig.RetryCount}, set to DefaultRetryCount: {ModbusConstants.DefaultRetryCount}");
slaveConfig.RetryCount = ModbusConstants.DefaultRetryCount;
}
if (slaveConfig.RetryInterval <= 0)
if (slaveConfig.RetryInterval == null || slaveConfig.RetryInterval <= 0)
{
Console.WriteLine($"Invalid RetryInterval: {slaveConfig.RetryInterval}, set to DefaultRetryInterval: {ModbusConstants.DefaultRetryInterval}");
slaveConfig.RetryInterval = ModbusConstants.DefaultRetryInterval;
}
List<string> invalidOperations = new List<string>();
foreach (var operation_pair in slaveConfig.Operations)
{
ReadOperation operation = operation_pair.Value;
if(operation == null)
{
Console.WriteLine($"{operation_pair.Key} is null, remove from dictionary...");
invalidOperations.Add(operation_pair.Key);
continue;
}
if(operation.StartAddress.Length < 5)
{
Console.WriteLine($"{operation_pair.Key} has invalid StartAddress {operation.StartAddress}, remove from dictionary...");
invalidOperations.Add(operation_pair.Key);
continue;
}
ParseEntity(operation.StartAddress, true, out ushort address_int16, out byte function_code, out byte entity_type);
if (operation.Count <= 0)
{
Console.WriteLine($"Invalid Count: {operation.Count}");
ret = false;
Console.WriteLine($"{operation_pair.Key} has invalid Count {operation.Count}, remove from dictionary...");
invalidOperations.Add(operation_pair.Key);
continue;
}
if (operation.Count > 127 && ((char)entity_type == (char)ModbusConstants.EntityType.HoldingRegister || (char)entity_type == (char)ModbusConstants.EntityType.InputRegister))
{
Console.WriteLine($"Invalid Count: {operation.Count}, must be 1~127");
ret = false;
Console.WriteLine($"{operation_pair.Key} has invalid Count, must be 1~127, {operation.Count}, remove from dictionary...");
invalidOperations.Add(operation_pair.Key);
continue;
}
if(operation.CorrelationId == "" || operation.CorrelationId == null)
{
Console.WriteLine($"Empty CorrelationId: {operation.CorrelationId}, set to DefaultCorrelationId: {ModbusConstants.DefaultCorrelationId}");
operation.CorrelationId = ModbusConstants.DefaultCorrelationId;
}
if (ret)
{
operation.EntityType = entity_type;
operation.Address = address_int16;
operation.FunctionCode = function_code;
//output format
if (operation.StartAddress.Length == 5)
operation.OutFormat = "{0}{1:0000}";
else if (operation.StartAddress.Length == 6)
operation.OutFormat = "{0}{1:00000}";
}
operation.EntityType = entity_type;
operation.Address = address_int16;
operation.FunctionCode = function_code;
//output format
if (operation.StartAddress.Length == 5)
operation.OutFormat = "{0}{1:0000}";
else if (operation.StartAddress.Length == 6)
operation.OutFormat = "{0}{1:00000}";
}
foreach(var in_op in invalidOperations)
{
slaveConfig.Operations.Remove(in_op);
}
}
return ret;
foreach(var in_slave in invalidConfigs)
{
SlaveConfigs.Remove(in_slave);
}
}
public static bool ParseEntity(string startAddress, bool isRead, out ushort outAddress, out byte functionCode, out byte entityType)
{

Просмотреть файл

@ -242,23 +242,21 @@ namespace Modbus.Containers
m_interval = new ModbusPushInterval(DefaultPushInterval);
}
if (config.IsValidate())
config.Validate();
moduleHandle = await Slaves.ModuleHandle.CreateHandleFromConfiguration(config);
if (moduleHandle != null)
{
moduleHandle = await Slaves.ModuleHandle.CreateHandleFromConfiguration(config);
var userContext = new Tuple<ModuleClient, Slaves.ModuleHandle>(ioTHubModuleClient, moduleHandle);
// Register callback to be called when a message is received by the module
await ioTHubModuleClient.SetInputMessageHandlerAsync(
"input1",
PipeMessage,
userContext);
m_task_list.Add(Start(userContext));
if (moduleHandle != null)
{
var userContext = new Tuple<ModuleClient, Slaves.ModuleHandle>(ioTHubModuleClient, moduleHandle);
// Register callback to be called when a message is received by the module
await ioTHubModuleClient.SetInputMessageHandlerAsync(
"input1",
PipeMessage,
userContext);
m_task_list.Add(Start(userContext));
// Save the new existing config for reporting.
m_existingConfig = config;
}
// Save the new existing config for reporting.
m_existingConfig = config;
}
}
@ -287,14 +285,26 @@ namespace Modbus.Containers
ModuleClient ioTHubModuleClient = userContextValues.Item1;
Slaves.ModuleHandle moduleHandle = userContextValues.Item2;
if(moduleHandle.ModbusSessionList.Count == 0)
{
Console.WriteLine("No valid modbus session available!!");
}
foreach (ModbusSlaveSession s in moduleHandle.ModbusSessionList)
{
s.ProcessOperations();
if(s.config.Operations.Count == 0)
{
Console.WriteLine("No valid operation in modbus session available!!");
}
else
{
s.ProcessOperations();
}
}
while (m_run)
{
Message message = null;
Message sqliteMessage = null;
List<object> result = moduleHandle.CollectAndResetOutMessageFromSessions();
@ -305,15 +315,29 @@ namespace Modbus.Containers
PublishTimestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
Content = result
};
SQLiteCommandMessage sqlite_out_message = new SQLiteCommandMessage
{
RequestId = 0,
RequestModule = "modbus";
DbName = "/app/db/test.db",
Command = "select * from test;"
};
message = new Message(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(out_message)));
message.Properties.Add("content-type", "application/edge-modbus-json");
sqliteMessage = new Message(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(sqlite_out_message)));
sqliteMessage.Properties.Add("command-type", "SQLiteCmd");
}
if (message != null)
{
await ioTHubModuleClient.SendEventAsync("modbusOutput", message);
}
if (sqliteMessage != null)
{
await ioTHubModuleClient.SendEventAsync("modbusOutput", sqliteMessage);
}
if (!m_run)
{
break;
@ -323,4 +347,12 @@ namespace Modbus.Containers
moduleHandle.Release();
}
}
class SQLiteCommandMessage
{
public int RequestId;
public string RequestModule;
public string DbName;
public string Command;
}
}

Просмотреть файл

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netcoreapp2.0|AnyCPU'">
@ -10,7 +10,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.17.0" />
<PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.18.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.0.0" />