GithubHelp home page GithubHelp logo

sandervandevelde / advantech.wise4012e.modbus.simulation Goto Github PK

View Code? Open in Web Editor NEW
2.0 6.0 1.0 210 KB

Application which simulates an Advantech Wise 4012e IO module. The application is written in .Net Core.

License: MIT License

C# 100.00%

advantech.wise4012e.modbus.simulation's Introduction

Advantech Wise4012e Modbus Simulation

Application which simulates an Advantech Wise 4012e IO module. The application is written in .Net Core.

Purpose

It runs a Modbus service at [127.0.0.1] (configurable):

  • Switch 1 on Discrete coil 1 (read/write) 0 or 1
  • Switch 2 on Discrete coil 2 (read/write) 0 or 1
  • Relay 1 on Discrete coil 17 (read/write) 0 or 1
  • Relay 2 on Discrete coil 18 (read/write) 0 or 1
  • Knob 1 on Holding Register 40001 (read/write) 0 - 4500
  • Knob 2 on Holding Register 40002 (read/write) 0 - 4500

Usage

This is a .Net Core application.

Select a local folder (eg. c:\dev) in which the project will be put for execution. (please select a short path to prevent a path with has too many characters).

In Github clone the code or extract is as a ZIP file.

Compile and run this application in Visual studio Code.

Execute the following steps:

  1. Install .Net Core SDK.

  2. Open the folder of the project in VS Code. Select 'program.cs'. Accept any suggestions regarding debugger and packages.

  3. Compile the application

    Note: the Debug Console is read-only. We will need to run the app outside VS Code.

  4. Go to \bin\Debug\netcoreapp2.0 folder of the project. Here you will find the \bin\Debug\netcoreapp2.0\Advantech.Wise4012e.Modbus.SimulationApp.dll

    Note: Do not expect an executable.

  5. run the dll on the command line using the command 'dotnet Advantech.Wise4012e.Modbus.SimulationApp.dll'.

You can now read and write Modbus using this simulation in Modbus clients like CAS Modbus Scanner or Azure IoT Edge.

alt tag

IoT Edge Microsoft Modbus Module

It is confirmed this simulation can be used together with the Microsoft Azure IoT Edge Modbus Module

To get it working:

  1. Go to 'settings.json' and replace the localhost address by your specific local IP Address (you can look it up using 'ipconfig')
  2. Start the app as described above
  3. Confirm changes to the firewall for this app and port
  4. Use this IP address in the Module Twin of the Modbus module

The configuration of the device twin will look like:

...
"desired": {
  "PublishInterval": "5000",
  "SlaveConfigs": {
    "Slave01": {
      "SlaveConnection": "[IP address in settings.json]",
      "HwId": "Wise4012E-142ext",
      "Operations": {
        "Op01": {
          "PollingInterval": "5000",
          "UnitId": "1",
          "StartAddress": "40001",
          "Count": "1",
          "DisplayName": "KnobOne"
        },
        "Op02": {
          "PollingInterval": "5000",
          "UnitId": "1",
          "StartAddress": "40002",
          "Count": "1",
          "DisplayName": "KnobTwo"
        },
        "Op03": {
          "PollingInterval": "5000",
          "UnitId": "1",
          "StartAddress": "00001",
          "Count": "1",
          "DisplayName": "SwitchOne"
        },
        "Op04": {
          "PollingInterval": "5000",
          "UnitId": "1",
          "StartAddress": "00002",
          "Count": "1",
          "DisplayName": "SwitchTwo"
        },
        "Op05": {
          "PollingInterval": "5000",
          "UnitId": "1",
          "StartAddress": "00017",
          "Count": "1",
          "DisplayName": "RelayOne"
        },
        "Op06": {
          "PollingInterval": "5000",
          "UnitId": "1",
          "StartAddress": "00018",
          "Count": "1",
          "DisplayName": "RelayTwo"
        }
      }
    }
  },
  "$metadata": {
  ...

Alter the behaviour of your simulation

When running the application, you can alter the values of the simulation.

Just enter:

  • 1 0 (switch 1 to false)
  • 1 1 (switch 1 to true)
  • 2 0 (switch 2 to false)
  • 2 1 (switch 2 to true)
  • 17 0 (relay 1 to false)
  • 17 1 (relay 1 to true)
  • 18 0 (relay 2 to false)
  • 18 1 (relay 2 to true)
  • 40001 0-4500 (pick a value between 0 and 4500)
  • 40002 0-4500 (pick a value between 0 and 4500)

Note: The relays can not be changed

NModbus4 library

This simulation is making use of the Nuget package NModbus4. Great work!

Contribute

This logic is licenced under the MIT license.

Want to contribute? Throw me a pull request....

Want to know more about me? Check out my blog.

advantech.wise4012e.modbus.simulation's People

Contributors

sandervandevelde avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

rploeg

advantech.wise4012e.modbus.simulation's Issues

Issue connecting Emulator

Hi Sander, @sandervandevelde
When I start the emulator it looks to be running.
Start Advantech Wise4012e Modbus simulation at 127.0.0.1
Slave 1 supports switch 1, switch 2, relay 17, relay 18, knob 40001, knob 40002

False False False False 0000 0000 - Write '1 [bit]' '2 [bit]' '17 [bit]' '18 [bit]' '40001 [int]' '40002 [int]' or Q to exit
1 1
True False False False 0000 0000 - Write '1 [bit]' '2 [bit]' '17 [bit]' '18 [bit]' '40001 [int]' '40002 [int]' or Q to exit
1 0
False False False False 0000 0000 - Write '1 [bit]' '2 [bit]' '17 [bit]' '18 [bit]' '40001 [int]' '40002 [int]' or Q to exit
1 1
True False False False 0000 0000 - Write '1 [bit]' '2 [bit]' '17 [bit]' '18 [bit]' '40001 [int]' '40002 [int]' or Q to exit

But the IoT client cannot connect.. Please advise :) Thanks!

docker logs -f msftmodbus

Connect Slave failed
Connection refused 127.0.0.1:502
Connection lost, reconnecting...
Connect Slave failed
Connection refused 127.0.0.1:502
Connection lost, reconnecting...
Connect Slave failed
Connection refused 127.0.0.1:502
Connection lost, reconnecting...
Connect Slave failed
Connection refused 127.0.0.1:502
Connection lost, reconnecting...
Connect Slave failed
Connection refused 127.0.0.1:502
Connection lost, reconnecting...
Connect Slave failed
Connection refused 127.0.0.1:502

JSON:

{
"deviceId": "mytemperaturemeter",
"moduleId": "msftmodbus",
"etag": "AAAAAAAAAAM=",
"deviceEtag": "Nzg5ODU3NDgw",
"status": "enabled",
"statusUpdateTime": "0001-01-01T00:00:00",
"connectionState": "Connected",
"lastActivityTime": "2019-03-13T13:41:16.2208709",
"cloudToDeviceMessageCount": 0,
"authenticationType": "sas",
"x509Thumbprint": {
"primaryThumbprint": null,
"secondaryThumbprint": null
},
"version": 7,
"properties": {
"desired": {
"PublishInterval": "5000",
"Version": "1",
"SlaveConfigs": {
"Slave01": {
"SlaveConnection": "127.0.0.1",
"HwId": "Wise4012E",
"Operations": {
"Op01": {
"PollingInterval": "5000",
"UnitId": "1",
"StartAddress": "40001",
"Count": "1",
"DisplayName": "KnobOne"
},
"Op02": {
"PollingInterval": "5000",
"UnitId": "1",
"StartAddress": "40002",
"Count": "1",
"DisplayName": "KnobTwo"
},
"Op03": {
"PollingInterval": "5000",
"UnitId": "1",
"StartAddress": "00001",
"Count": "1",
"DisplayName": "SwitchOne"
},
"Op04": {
"PollingInterval": "5000",
"UnitId": "1",
"StartAddress": "00002",
"Count": "1",
"DisplayName": "SwitchTwo"
},
"Op05": {
"PollingInterval": "5000",
"UnitId": "1",
"StartAddress": "00017",
"Count": "1",
"DisplayName": "RelayOne"
},
"Op06": {
"PollingInterval": "5000",
"UnitId": "1",
"StartAddress": "00018",
"Count": "1",
"DisplayName": "RelayTwo"
}
}
}
},
"$metadata": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3,
"PublishInterval": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"Version": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"SlaveConfigs": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3,
"Slave01": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3,
"SlaveConnection": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"HwId": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"Operations": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3,
"Op01": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3,
"PollingInterval": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"UnitId": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"StartAddress": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"Count": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"DisplayName": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
}
},
"Op02": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3,
"PollingInterval": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"UnitId": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"StartAddress": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"Count": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"DisplayName": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
}
},
"Op03": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3,
"PollingInterval": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"UnitId": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"StartAddress": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"Count": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"DisplayName": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
}
},
"Op04": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3,
"PollingInterval": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"UnitId": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"StartAddress": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"Count": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"DisplayName": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
}
},
"Op05": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3,
"PollingInterval": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"UnitId": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"StartAddress": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"Count": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"DisplayName": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
}
},
"Op06": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3,
"PollingInterval": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"UnitId": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"StartAddress": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"Count": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
},
"DisplayName": {
"$lastUpdated": "2019-03-14T15:44:52.8504242Z",
"$lastUpdatedVersion": 3
}
}
}
}
}
},
"$version": 3
},
"reported": {
"PublishInterval": 5000,
"SlaveConfigs": {
"Slave01": {
"Operations": {
"Op01": {
"PollingInterval": 5000,
"UnitId": 1,
"StartAddress": "40001",
"Count": 1,
"DisplayName": "KnobOne",
"CorrelationId": "DefaultCorrelationId"
},
"Op02": {
"PollingInterval": 5000,
"UnitId": 1,
"StartAddress": "40002",
"Count": 1,
"DisplayName": "KnobTwo",
"CorrelationId": "DefaultCorrelationId"
},
"Op03": {
"PollingInterval": 5000,
"UnitId": 1,
"StartAddress": "00001",
"Count": 1,
"DisplayName": "SwitchOne",
"CorrelationId": "DefaultCorrelationId"
},
"Op04": {
"PollingInterval": 5000,
"UnitId": 1,
"StartAddress": "00002",
"Count": 1,
"DisplayName": "SwitchTwo",
"CorrelationId": "DefaultCorrelationId"
},
"Op05": {
"PollingInterval": 5000,
"UnitId": 1,
"StartAddress": "00017",
"Count": 1,
"DisplayName": "RelayOne",
"CorrelationId": "DefaultCorrelationId"
},
"Op06": {
"PollingInterval": 5000,
"UnitId": 1,
"StartAddress": "00018",
"Count": 1,
"DisplayName": "RelayTwo",
"CorrelationId": "DefaultCorrelationId"
}
},
"SlaveConnection": "10.10.61.161",
"RetryCount": 10,
"RetryInterval": 50,
"TcpPort": 502,
"HwId": "Wise4012E"
}
},
"$metadata": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z",
"PublishInterval": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"SlaveConfigs": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z",
"Slave01": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z",
"Operations": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z",
"Op01": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z",
"PollingInterval": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"UnitId": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"StartAddress": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"Count": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"DisplayName": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"CorrelationId": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
}
},
"Op02": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z",
"PollingInterval": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"UnitId": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"StartAddress": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"Count": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"DisplayName": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"CorrelationId": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
}
},
"Op03": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z",
"PollingInterval": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"UnitId": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"StartAddress": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"Count": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"DisplayName": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"CorrelationId": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
}
},
"Op04": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z",
"PollingInterval": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"UnitId": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"StartAddress": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"Count": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"DisplayName": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"CorrelationId": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
}
},
"Op05": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z",
"PollingInterval": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"UnitId": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"StartAddress": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"Count": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"DisplayName": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"CorrelationId": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
}
},
"Op06": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z",
"PollingInterval": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"UnitId": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"StartAddress": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"Count": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"DisplayName": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"CorrelationId": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
}
}
},
"SlaveConnection": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"RetryCount": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"RetryInterval": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"TcpPort": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
},
"HwId": {
"$lastUpdated": "2019-03-14T15:30:12.6537423Z"
}
}
}
},
"$version": 4
}
}
}

I think, there is something with AsyncListen. But still, it has issues.

using Microsoft.Extensions.Configuration;
using Modbus.Data;
using Modbus.Device;
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;

namespace Advantech.Wise4012e.Modbus.SimulationApp
{
internal class Program
{
public static IConfiguration Configuration { get; set; }
private static readonly CancellationTokenSource token = new CancellationTokenSource();

    private const byte SlaveID = 1;

    private static void Main(string[] args)
    {
        var builder = new ConfigurationBuilder()
                          .SetBasePath(Directory.GetCurrentDirectory())
                          .AddJsonFile("settings.json");

        Configuration = builder.Build();

        var address = Configuration["address"];

        Console.WriteLine($"Start Advantech Wise4012e Modbus simulation at {address}");

        var slaveTcpListener = new TcpListener(IPAddress.Parse(address), 502);





        slaveTcpListener.Start();
        var slave = ModbusTcpSlave.CreateTcp(SlaveID, slaveTcpListener);
        slave.DataStore = DataStoreFactory.CreateDefaultDataStore();

        slave.DataStore.DataStoreReadFrom += DataStore_DataStoreReadFrom;
        slave.DataStore.DataStoreWrittenTo += DataStore_DataStoreWrittenTo;

        slave.DataStore.HoldingRegisters[1] = (ushort)0;
        slave.DataStore.HoldingRegisters[2] = (ushort)0;

        slave.DataStore.CoilDiscretes[1] = false;
        slave.DataStore.CoilDiscretes[2] = false;
        slave.DataStore.CoilDiscretes[17] = false;
        slave.DataStore.CoilDiscretes[18] = false;
        Task.Run(() => Loop(slave));
        try
        {
            slave.ListenAsync().Wait(token.Token);
        }
        catch (OperationCanceledException)
        {

        }
        slave.Dispose();


    }
    private static void Loop(object slaveObj)
    {
        var slave = (ModbusTcpSlave)slaveObj;
         
         Console.WriteLine($"Slave {SlaveID} supports switch 1, switch 2, relay 17, relay 18, knob 40001, knob 40002");
       
        while (true)
        {
            Console.WriteLine($"> {slave.DataStore.CoilDiscretes[1]} {slave.DataStore.CoilDiscretes[2]} {slave.DataStore.CoilDiscretes[17]} {slave.DataStore.CoilDiscretes[18]} {slave.DataStore.HoldingRegisters[1]:0000} {slave.DataStore.HoldingRegisters[2]:0000} - Write '1 [bit]' '2 [bit]' '17 [bit]' '18 [bit]' '40001 [int]' '40002 [int]' or Q to exit");
            Console.Write("> ");

            var input = Console.ReadLine();

            if (input.ToUpper() == "Q")
            {
                token.Cancel();
                break;
            }

            var fields = input.Split(' ');

            switch (fields[0])
            {
                case "1":
                    slave.DataStore.CoilDiscretes[1] = Convert.ToBoolean(Convert.ToInt16(fields[1]));
                    break;

                case "2":
                    slave.DataStore.CoilDiscretes[2] = Convert.ToBoolean(Convert.ToInt16(fields[1]));
                    break;

                case "17":
                    slave.DataStore.CoilDiscretes[17] = Convert.ToBoolean(Convert.ToInt16(fields[1]));
                    break;

                case "18":
                    slave.DataStore.CoilDiscretes[18] = Convert.ToBoolean(Convert.ToInt16(fields[1]));
                    break;

                case "40001":
                    var value1 = Math.Abs(Convert.ToInt32(fields[1]));
                    slave.DataStore.HoldingRegisters[1] = value1 > 4500 ? (ushort)4500 : (ushort)value1;
                    break;

                case "40002":
                    var value2 = Math.Abs(Convert.ToInt32(fields[1]));
                    slave.DataStore.HoldingRegisters[2] = value2 > 4500 ? (ushort)4500 : (ushort)value2;
                    break;
            }
        }
    }
    private static void DataStore_DataStoreReadFrom(object sender, DataStoreEventArgs e)
    {
        {
            if (e.ModbusDataType == ModbusDataType.HoldingRegister)
            {
                Console.WriteLine($"\nClient reads {e.ModbusDataType} address {e.StartAddress + 40001} - read {e.Data.B[0]}");
                Console.Write("> ");
            }
            else
            {
                Console.WriteLine($"\nClient reads {e.ModbusDataType} address {e.StartAddress + 1} - read {e.Data.A[0]}");
                Console.Write("> ");
            }
        }
    }

    private static void DataStore_DataStoreWrittenTo(object sender, DataStoreEventArgs e)
    {
        Console.WriteLine($"\nClient writes {e.ModbusDataType} address {e.StartAddress + 1} - write {e.Data.A[0]}");
        Console.Write("> ");
    }
}

}

Local IP

Hi
The instruction Go to 'settings.json' and replace the localhost address by your specific local IP Address (you can look it up using 'ipconfig') suggests that you can only interact with this module if it is installed on the IoT edge device (local IP) or in same network?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.