脚本说明
在Modbus Slave Emulator中,可以使用自定义C#脚本。编写脚本时,你需要实现下面这个抽象类,当主站(客户端)发起读写寄存器请求时,执行脚本中对应的方法。
namespace ModbusSlaveEmulator.Script
{
public abstract class DefaultHandler
{
// 下面四种数组,代表了用户在UI上配置的每种类型的寄存器
// 从站配置了多个就访问多少,数组索引不要超限
// 比如,配置保持寄存器,起始地址10 (base 0),数量为100
// 那么应该使用HoldingRegisters[10],HoldingRegisters[11],...,HoldingRegisters[109]
public ModbusSlaveEmulator.Script.ReadOnlyArray<bool> Coils; //线圈状态
public ModbusSlaveEmulator.Script.ReadOnlyArray<bool> DiscreteInputs; //离散输入状态
public ModbusSlaveEmulator.Script.ReadOnlyArray<ushort> HoldingRegisters; //保持寄存器
public ModbusSlaveEmulator.Script.ReadOnlyArray<ushort> InputRegisters; //输入寄存器
/// <summary>
/// 读线圈状态
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="numberOfPoints">读取的数量</param>
/// <returns>返回的数组长度应该为numberOfPoints</returns>
public virtual bool[] ReadCoils(ushort startAddress, ushort numberOfPoints)
{
return null;
}
/// <summary>
/// 写线圈状态
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="points">要写入的数据</param>
public virtual void WriteCoils(ushort startAddress, bool[] points)
{
}
/// <summary>
/// 读离散输入状态
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="numberOfPoints">读取的数量</param>
/// <returns>返回的数组长度应该为numberOfPoints</returns>
public virtual bool[] ReadDiscreteInputs(ushort startAddress, ushort numberOfPoints)
{
return null;
}
/// <summary>
/// 读保持寄存器
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="numberOfPoints">读取的数量</param>
/// <returns>返回的数组长度应该为numberOfPoints</returns>
public virtual ushort[] ReadHoldingRegisters(ushort startAddress, ushort numberOfPoints)
{
return null;
}
/// <summary>
/// 写保持寄存器
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="points">要写入的数据</param>
public virtual void WriteHoldingRegisters(ushort startAddress, ushort[] points)
{
}
/// <summary>
/// 读输入寄存器
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="numberOfPoints">读取的数量</param>
/// <returns>返回的数组长度应该为numberOfPoints</returns>
public virtual ushort[] ReadInputRegisters(ushort startAddress, ushort numberOfPoints)
{
return null;
}
}
}
DefaultHandler
的实现类必须命名为Handler
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.ObjectModel;
/// <summary>
/// ModbusSlaveEmulator.Script.DefaultHandler 实现示例
/// </summary>
public class Handler : ModbusSlaveEmulator.Script.DefaultHandler
{
/// <summary>
/// 读线圈状态
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="numberOfPoints">读取的数量</param>
/// <returns>返回的数组长度应该为numberOfPoints</returns>
public override bool[] ReadCoils(ushort startAddress, ushort numberOfPoints)
{
bool[] array = new bool[numberOfPoints];
for (int i = 0; i < array.Length; i++)
{
if (i % 2 == 0)
{
//返回在UI表格里配置的数据值,并取反
array[i] = !Coils[startAddress + i];
}
else
{
array[i] = false;
}
}
return array;
}
/// <summary>
/// 写线圈状态
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="points">要写入的数据</param>
public override void WriteCoils(ushort startAddress, bool[] points)
{
//ignore
}
/// <summary>
/// 读离散输入状态
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="numberOfPoints">读取的数量</param>
/// <returns>返回的数组长度应该为numberOfPoints</returns>
public override bool[] ReadDiscreteInputs(ushort startAddress, ushort numberOfPoints)
{
bool[] array = new bool[numberOfPoints];
for (int i = 0; i < array.Length; i++)
{
array[i] = true;
}
return array;
}
/// <summary>
/// 读保持寄存器
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="numberOfPoints">读取的数量</param>
/// <returns>返回的数组长度应该为numberOfPoints</returns>
public override ushort[] ReadHoldingRegisters(ushort startAddress, ushort numberOfPoints)
{
ushort[] array = new ushort[numberOfPoints];
for (int i = 0; i < array.Length; i++)
{
//返回在UI表格里配置的数据值,并+3
array[i] = (ushort) (HoldingRegisters[startAddress + i] + 3);
}
return array;
}
/// <summary>
/// 写保持寄存器
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="points">要写入的数据</param>
public override void WriteHoldingRegisters(ushort startAddress, ushort[] points)
{
//ignore
}
/// <summary>
/// 读输入寄存器
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="numberOfPoints">读取的数量</param>
/// <returns>返回的数组长度应该为numberOfPoints</returns>
public override ushort[] ReadInputRegisters(ushort startAddress, ushort numberOfPoints)
{
ushort[] array = new ushort[numberOfPoints];
for (int i = 0; i < array.Length; i++)
{
//返回在UI表格里配置的数据值,并+1
array[i] = (ushort) (InputRegisters[startAddress + i] + 1);
}
return array;
}
}