脚本说明
在Modbus Slave Emulator中,可以使用自定义C#脚本。编写脚本时,你需要实现下面这个抽象类,当主站(客户端)发起读写寄存器请求时,执行脚本中对应的方法。
namespace ModbusSlave.Script
{
public abstract class DefaultHandler
{
/// <summary>
/// 下面四种数组,代表了用户在UI上配置的每种类型的寄存器
/// 注意:这些数组都是只读的,不要写入数据
/// 从站配置了多个就访问多少,数组索引不要超限
/// 比如,配置保持寄存器,起始地址10 (base 0),数量为100
/// 那么应该使用HoldingRegisters[10],HoldingRegisters[11],...,HoldingRegisters[109]
/// </summary>
public ModbusSlave.Script.ReadOnlyArray<bool> CoilDiscretes; //线圈状态数组
public ModbusSlave.Script.ReadOnlyArray<bool> CoilInputs; //离散输入状态
public ModbusSlave.Script.ReadOnlyArray<ushort> HoldingRegisters; //保持寄存器
public ModbusSlave.Script.ReadOnlyArray<ushort> InputRegisters; //输入寄存器
/// <summary>
/// 读线圈状态
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="numberOfPoints">读取的数量</param>
/// <returns>如果返回null,则返回用户配置的寄存器数据;如果不是null,则返回脚本提供的数据</returns>
public virtual bool[] ReadCoilDiscretes(ushort startAddress, ushort numberOfPoints)
{
return null;
}
/// <summary>
/// 写线圈状态
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="points">要写入的数据</param>
public virtual void WriteCoilDiscretes(ushort startAddress, bool[] points)
{
}
/// <summary>
/// 读离散输入状态
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="numberOfPoints">读取的数量</param>
/// <returns>如果返回null,则返回用户配置的寄存器数据;如果不是null,则返回脚本提供的数据</returns>
public virtual bool[] ReadCoilInputs(ushort startAddress, ushort numberOfPoints)
{
return null;
}
/// <summary>
/// 读保持寄存器
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="numberOfPoints">读取的数量</param>
/// <returns>如果返回null,则返回用户配置的寄存器数据;如果不是null,则返回脚本提供的数据</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>如果返回null,则返回用户配置的寄存器数据;如果不是null,则返回脚本提供的数据</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>
/// ModbusSlave.Script.DefaultHandler实现示例
/// </summary>
public class Handler : ModbusSlave.Script.DefaultHandler
{
/// <summary>
/// 读线圈状态
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="numberOfPoints">读取的数量</param>
/// <returns>如果返回null,则返回用户配置的寄存器数据;如果不是null,则返回脚本提供的数据</returns>
public override bool[] ReadCoilDiscretes(ushort startAddress, ushort numberOfPoints)
{
bool[] array = new bool[numberOfPoints];
for (int i = 0; i < array.Length; i++)
{
if (i % 2 == 0)
{
//返回在UI表格里配置的数据值,并取反
array[i] = !CoilDiscretes[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 WriteCoilDiscretes(ushort startAddress, bool[] points)
{
//ignore
}
/// <summary>
/// 读离散输入状态
/// </summary>
/// <param name="startAddress">寄存器起始地址(Protocol Address Base 0)</param>
/// <param name="numberOfPoints">读取的数量</param>
/// <returns>如果返回null,则返回用户配置的寄存器数据;如果不是null,则返回脚本提供的数据</returns>
public override bool[] ReadCoilInputs(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>如果返回null,则返回用户配置的寄存器数据;如果不是null,则返回脚本提供的数据</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></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;
}
}