Report properties back to IoT Hub on change. (#54)

* Report properties back to IoT Hub on change.

* Adds use of base classes instead of duplicate code for reported properties.
This commit is contained in:
Kevin Benton 2018-08-06 20:48:44 -05:00 коммит произвёл Stephen
Родитель e691ee5cf4
Коммит 947a1ec8ec
2 изменённых файлов: 86 добавлений и 10 удалений

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

@ -2,6 +2,7 @@
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
@ -780,9 +781,9 @@
}
/// <summary>
/// This class contains the configuration for a Modbus session.
/// The base data for a Modbus session used so that reported properties can be echoed back to the IoT Hub.
/// </summary>
class ModbusSlaveConfig
class BaseModbusSlaveConfig
{
public string SlaveConnection { get; set; }
public int RetryCount { get; set; }
@ -794,7 +795,16 @@
public byte DataBits { get; set; }
public Parity Parity { get; set; }
//public byte FlowControl { get; set; }
public Dictionary<string, ReadOperation> Operations = null;
public Dictionary<string, BaseReadOperation> Operations = null;
}
/// <summary>
/// This class contains the configuration for a Modbus session.
/// </summary>
class ModbusSlaveConfig : BaseModbusSlaveConfig
{
public new Dictionary<string, ReadOperation> Operations = null;
public ModbusConstants.ConnectionType GetConnectionType()
{
if (IPAddress.TryParse(SlaveConnection, out IPAddress address))
@ -805,26 +815,64 @@
return ModbusConstants.ConnectionType.Unknown;
}
public BaseModbusSlaveConfig AsBase()
{
// Unfortunately we need to create new objects since simple polymorphism will still keep the same fields of the child classes.
BaseModbusSlaveConfig baseConfig = new BaseModbusSlaveConfig
{
SlaveConnection = this.SlaveConnection,
RetryCount = this.RetryCount,
RetryInterval = this.RetryInterval,
TcpPort = this.TcpPort,
HwId = this.HwId,
BaudRate = this.BaudRate,
StopBits = this.StopBits,
DataBits = this.DataBits,
Parity = this.Parity
};
baseConfig.Operations = this.Operations.ToDictionary(
pair => pair.Key,
pair => new BaseReadOperation
{
PollingInterval = pair.Value.PollingInterval,
UnitId = pair.Value.UnitId,
StartAddress = pair.Value.StartAddress,
Count = pair.Value.Count,
DisplayName = pair.Value.DisplayName,
CorrelationId = pair.Value.CorrelationId,
});
return baseConfig;
}
}
/// <summary>
/// The base data for a read operation used so that reported properties can be echoed back to the IoT Hub.
/// </summary>
class BaseReadOperation
{
public int PollingInterval { get; set; }
public byte UnitId { get; set; }
public string StartAddress { get; set; }
public UInt16 Count { get; set; }
public string DisplayName { get; set; }
public string CorrelationId { get; set; }
}
/// <summary>
/// This class contains the configuration for a single Modbus read request.
/// </summary>
class ReadOperation
class ReadOperation : BaseReadOperation
{
public byte[] Request;
public byte[] Response;
public int RequestLen;
public byte EntityType { get; set; }
public string OutFormat { get; set; }
public int PollingInterval { get; set; }
public byte UnitId { get; set; }
public byte FunctionCode { get; set; }
public string StartAddress { get; set; }
public UInt16 Address { get; set; }
public UInt16 Count { get; set; }
public string DisplayName { get; set; }
public string CorrelationId { get; set; }
}
static class ModbusConstants
@ -1015,4 +1063,20 @@
public string PublishTimestamp { get; set; }
public List<object> Content { get; set; }
}
/// <summary>
/// This class creates a container to easily serialize the configuration so that the reported
/// properties can be updated.
/// </summary>
class ModuleTwinProperties
{
public ModuleTwinProperties(int? publishInterval, ModuleConfig moduleConfig)
{
PublishInterval = publishInterval;
SlaveConfigs = moduleConfig?.SlaveConfigs.ToDictionary(pair => pair.Key, pair => pair.Value.AsBase());
}
public int? PublishInterval { get; set; }
public Dictionary<string, BaseModbusSlaveConfig> SlaveConfigs { get; set; }
}
}

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

@ -23,6 +23,7 @@ namespace Modbus.Containers
static List<Task> m_task_list = new List<Task>();
static bool m_run = true;
static ModbusPushInterval m_interval = null;
static ModuleConfig m_existingConfig = null;
static object message_lock = new object();
static List<ModbusOutMessage> result = new List<ModbusOutMessage>();
@ -254,9 +255,20 @@ namespace Modbus.Containers
PipeMessage,
userContext);
m_task_list.Add(Start(userContext));
// Save the new existing config for reporting.
m_existingConfig = config;
}
}
}
// Always report the change in properties. This keeps the reported properties in the module twin up to date even if none of the properties
// actually change. It will also report the property changes if only the publish interval or slave configs change.
ModuleTwinProperties moduleReportedProperties = new ModuleTwinProperties(m_interval?.PublishInterval, m_existingConfig);
string reportedPropertiesJson = JsonConvert.SerializeObject(moduleReportedProperties);
Console.WriteLine("Saving reported properties: " + reportedPropertiesJson);
TwinCollection reportedProperties = new TwinCollection(reportedPropertiesJson);
await ioTHubModuleClient.UpdateReportedPropertiesAsync(reportedProperties);
}
/// <summary>