常见问题
一、通用问题
1. Modbus地址可以只写地址0吗,一定要写成类似400001?
按照PLC Modbus寄存器的格式,需要以区域号为起始字符,后续加上(寄存器地址+1)。这是因为Modbus协议规定了不同类型寄存器的地址范围:
- 线圈寄存器:地址范围 00001-09999,格式为 0xxxx
- 离散输入寄存器:地址范围 10001-19999,格式为 1xxxx
- 输入寄存器:地址范围 30001-39999,格式为 3xxxx
- 保持寄存器:地址范围 40001-49999,格式为 4xxxx
所以,保持寄存器地址0必须写成400001。
2. 数据如何设置小数位
网关提供灵活的脚本式配置转换,可以在变量的读取表达式中进行配置转换。以下是几种常见的小数位设置方法:
方法一:使用Math.Round函数
// 设置小数位为2
Math.Round(raw.ToDecimal(), 2)
// 设置小数位为1
Math.Round(raw.ToDecimal(), 1)
方法二:使用乘法和除法
// 将整数转换为小数(例如,原值乘以0.01)
raw.ToDecimal() * 0.01
// 将整数转换为小数(例如,原值除以100)
raw.ToDecimal() / 100
方法三:使用字符串格式化
// 格式化为2位小数
raw.ToDecimal().ToString("F2")
3. 源码打开razor文件时,不出现智能提示,有waring警告(波浪线)
这是Visual Studio的常见问题,可能由多种原因导致。可以尝试以下解决方案:
- 升级Visual Studio:确保使用最新版本的Visual Studio
- 清理项目文件:
- 删除工程目录下的.vs文件夹、bin文件夹和obj文件夹
- 重新打开解决方案
- 重置Visual Studio设置:
- 打开Visual Studio命令提示符(以管理员身份运行)
- 执行命令:
devenv /ResetSettings
- 修复Visual Studio:
- 在控制面板中选择"修复Visual Studio"
- 等待修复完成后重新启动
- 检查项目引用:确保所有项目引用都正确,没有缺失或错误的引用
4. 报警属性中的报警约束如何定义
报警约束和变量表达式类似,填入脚本,返回值为true时,报警生效。报警约束可以实现 更复杂的报警逻辑,例如基于多个变量的组合条件。
示例1:基于单个变量的约束
// 当温度变量大于25度时,湿度报警才生效
GlobalData.GetVariable("环境监控", "温度").Value.ToDecimal() > 25
示例2:基于多个变量的约束
// 新建testInt1,testInt2两个变量
// 在testInt1的高高报警值为1,开启使能
// 在testInt1的高高报警约束中定义testInt2>10
// testInt1为8,testInt2为11时,产生testInt1报警
// testInt1为8,testInt2为10时,不会产生testInt1报警
// 复杂约束示例:当testInt2>10且testInt3<5时,报警生效
GlobalData.GetVariable("设备名称", "testInt2").Value.ToInt() > 10 &&
GlobalData.GetVariable("设备名称", "testInt3").Value.ToInt() < 5
5. 启动项目之后,驱动调试页面没有任何信息,设备选择插件时也不出现任何选择项
这通常是因为网关插件未正确编译或部署。解决方案:
-
编译解决方案:
- 在Visual Studio中打开解决方案
- 选择"生成" > "生成解决方案"
- 确保编译过程没有错误
-
检查插件目录:
- 确保插件DLL文件已成功拷贝到插件目录(Plugins)
- 对于开发环境,插件会自动复制到输出目录
- 对于部署环境,需要手动复制插件到Plugins目录
-
检查插件依赖:
- 确保插件所需的依赖项都已正确安装
- 检查插件的目标框架是否与网关一致
-
查看日志:
- 查看网关日志文件,了解插件加载过程中的错误信息
6. Linux部署时发现无法启动,报错:The type initializer for 'Microsoft.Data.sqlite.Sqliteconnection' threw an exception.
这是因为Linux系统缺少SQLite所需的依赖库。解决方案:
-
检查操作系统版本:
- 根据微软官方提供的.NET 8.0 支持的操作系统列表,确保使用支持的Linux版本
-
安装SQLite依赖:
- 在Ubuntu/Debian系统上:
sudo apt-get update
sudo apt-get install libsqlite3-dev - 在CentOS/RHEL系统上:
sudo yum install sqlite-devel
- 在Ubuntu/Debian系统上:
-
升级SQLite版本:
- 参考博客 Linux系统下解决SQLite连接问题
-
使用.NET 6发布:
- 如果上述方法都无法解决,可以考虑使用.NET 6发布ThingsGateway项目
二、变量配置
7. 我想在当前设备中添加变 量,该变量表示设备是否在线,不参与通讯
在变量地址中填写DeviceStatus,固定值为DeviceStatusEnum类型。可以通过读取表达式进行类型转换:
// 转换为布尔类型
(DeviceStatusEnum)raw == DeviceStatusEnum.OnLine
// 转换为字符串类型
((DeviceStatusEnum)raw).ToString()
// 转换为整数类型
((int)(DeviceStatusEnum)raw)
8. 我想在当前设备中添加变量,该变量作为计算点,不参与通讯
在变量地址中填写ScriptRead,在读取表达式中填写所需计算过程。计算点变量可以实现各种复杂的计算逻辑:
示例1:两个变量相加
// 不限制是否当前设备,只要变量名称存在,就可以正常运算
GlobalData.GetVariable("设备名称1", "变量名称1").Value.ToInt() +
GlobalData.GetVariable("设备名称2", "变量名称2").Value.ToInt()
示例2:计算平均值
// 计算多个变量的平均值
(GlobalData.GetVariable("设备名称", "变量1").Value.ToDecimal() +
GlobalData.GetVariable("设备名称", "变量2").Value.ToDecimal() +
GlobalData.GetVariable("设备名称", "变量3").Value.ToDecimal()) / 3
示例3:条件计算
// 根据条件返回不同的值
if (GlobalData.GetVariable("设备名称", "温度").Value.ToDecimal() > 30)
{
return "高温";
}
else if (GlobalData.GetVariable("设备名称", "温度").Value.ToDecimal() < 0)
{
return "低温";
}
else
{
return "正常";
}
9. 变量单独设置大小端解析顺序
在变量地址中添加DATA=参数,可以设置变量的大小端解析顺序:
- DATA=ABCD:大端顺序(高位在前,低位在后)
- DATA=DCBA:小端顺序(低位在前,高位在后)
- DATA=BADC:混合端顺序1
- DATA=CDAB:混合端顺序2
示例1:Modbus读取浮点数,保持寄存器0,大 端顺序
400001;DATA=ABCD;
示例2:Modbus读取双字整数,保持寄存器2,小端顺序
400003;DATA=DCBA;
三、部署问题
10. Windows服务部署时无法启动
可能的原因及解决方案:
-
服务权限不足:
- 确保服务以管理员身份运行
- 在服务属性中设置"登录"选项卡的账户为管理员账户
-
配置文件路径问题:
- 确保配置文件在正确的位置(与可执行文件同目录)
- 检查配置文件的权限是否正确
-
端口被占用:
- 检查默认端口5000是否被其他程序占用
- 使用命令
netstat -ano | findstr :5000查看端口占用情况 - 修改App.json配置文件中的端口号
-
依赖项缺失:
- 确保所有必要的依赖项都已安装
- 检查.NET运行时是否正确安装
-
日志查看:
- 查看Windows事件日志,了解具体错误信息
- 查看网关日志文件,了解启动过程中的错误
11. Docker部署时如何配置网络
Docker部署时,有多种网络配置方式:
方法一:使用主机网络
docker run --name thingsgateway --network host --restart=always -d thingsgateway:latest
优点:容器与主机共享网络,无需端口映射,适用于需要访问局域网设备的场景 缺点:可能会与主机网络产生冲突
方法二:使用端口映射
docker run --name thingsgateway -p 5000:5000 -p 5001:5001 --restart=always -d thingsgateway:latest
优点:网络隔离,安全性高 缺点:需要手动映射所有需要的端口
方法三:使用自定义网络
# 创建自定义网络
docker network create tg-network
# 运行容器
docker run --name thingsgateway --network tg-network -p 5000:5000 --restart=always -d thingsgateway:latest
优点:可以在多个容器之间创建隔离的网络环境 缺点:配置相对复杂