Skip to content

Instantly share code, notes, and snippets.

@snobu
Last active July 11, 2018 15:25
Show Gist options
  • Select an option

  • Save snobu/81358b2f0d78b9e1e8e4bc443273bd60 to your computer and use it in GitHub Desktop.

Select an option

Save snobu/81358b2f0d78b9e1e8e4bc443273bd60 to your computer and use it in GitHub Desktop.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<RootNamespace>iothub_serviceclient</RootNamespace>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Devices" Version="1.16.0" />
<PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.17.0" />
<PackageReference Include="ModbusTcp" Version="1.0.3" />
</ItemGroup>
</Project>
using System;
using System.Text;
using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Shared;
using Newtonsoft.Json;
using ModbusTcp;
using System.Threading.Tasks;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
namespace modbus_notmodbus
{
class Program
{
public static uint pollingInterval = 11; // seconds
public static string deviceId = "ModbusCollector";
public static string modbusHost = "127.0.0.1";
public static int modbusPort = 502;
public static string deviceConnStr = ".........................";
static DeviceClient c;
static async Task Main(string[] args)
{
ModbusClient m = new ModbusClient(modbusHost, modbusPort);
m.Init();
c = DeviceClient.CreateFromConnectionString(deviceConnStr);
Twin twin = await c.GetTwinAsync();
if (twin.Properties.Desired["pollingInterval"] != Program.pollingInterval)
{
Console.WriteLine("[DEBUG] Setting new pollingInterval: " +
$"{twin.Properties.Desired["pollingInterval"]} seconds");
try
{
Program.pollingInterval = twin.Properties.Desired["pollingInterval"];
}
catch (Exception ex)
{
Console.WriteLine($"[EXCEPTION] Unable to set pollingInterval: {ex.Message}");
}
}
await c.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChanged, null);
while (true)
{
object telemetryObject = await GetModbusData(m);
Console.WriteLine("[DEBUG] Serialized telemetry object:\n" +
JsonConvert.SerializeObject(telemetryObject, Formatting.Indented));
byte[] payload = Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(telemetryObject));
Message message = new Message(payload);
Console.WriteLine("Sending message to Azure IoT Hub...");
await c.SendEventAsync(message);
Console.WriteLine("OK");
await SleepSpinner(pollingInterval);
}
}
static async Task<object> GetModbusData(ModbusClient m)
{
Console.WriteLine("Fetching MODBUS data...");
// Reading might throw System.IO.IOException. Handle it.
// Fingers crossed for a short int
short[] voltage = await m.ReadRegistersAsync(40001, 3);
short[] current = await m.ReadRegistersAsync(41001, 3);
string hardwareId = "Function Code 0x2b (43)";
return new
{
deviceId = deviceId,
voltage = voltage,
current = current,
hardwareId = hardwareId
};
}
static async Task SleepSpinner(uint pollingInterval)
{
Console.Write($"Sleeping for {pollingInterval} seconds ");
for (byte i = 0; i < pollingInterval; i++)
{
foreach (string s in new string[] { "|", "/", "-", "\\" })
{
await Task.Delay(250);
Console.Write($"\b{s}");
}
}
Console.Write("\n");
}
static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext)
{
Console.WriteLine();
foreach (var prop in desiredProperties)
{
var pair = (KeyValuePair<string, object>)prop;
var value = pair.Value as JValue;
Console.WriteLine($"[DEBUG] desiredProp: {pair.Key} = {pair.Value.ToString()}");
}
if (desiredProperties["pollingInterval"] != Program.pollingInterval)
{
Console.WriteLine($"[DEBUG] Setting new pollingInterval: {desiredProperties["pollingInterval"]}");
try
{
Program.pollingInterval = desiredProperties["pollingInterval"];
}
catch (Exception ex)
{
Console.WriteLine($"[EXCEPTION] Unable to set pollingInterval: {ex.Message}");
}
}
TwinCollection reportedProperties = new TwinCollection();
reportedProperties["pollingInterval"] = Program.pollingInterval;
await c.UpdateReportedPropertiesAsync(reportedProperties);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment