写在前面
这篇文章主要讲解在实现之前几个服务模块的过程中,遇到了什么问题,最后是怎么解决的。
Q&A
Q1
在实际项目中,不同的设备点位是不一样的,就算是同样的设备,点位也有可能不一样,如果都在程序中定义出来的话,不同项目就需要不同的代码,这不利于我们管理项目,应该如何避免这种情况?
A1
使用配置文件(.csv)来存储设备的点位表,下面展示一下我定义的电表的点位表:
FunctionCode | Address | PropertyName |
---|---|---|
3 | 100 | Vol |
3 | 101 | Cur |
3 | 102 | Power |
3 | 103 | PowerRate |
其他设备(只要是遵守Modbus协议的设备)都可以使用这种方式来表示点位表,在代码中只需要通过读取配置文件并转换成数组,我们就知道了该设备的点位表,然后通过点位表就可以从该设备上采集相应的状态值。
T1(Think1)
思考一下,还有什么功能是可以使用上述的点位表来实现,从而不用在代码中写死。
- 单位,不同属性的单位肯定是不同的,比如电压的单位是V,电流的单位是A,功率的单位是W,功率因数的单位是%,如果我们想把这些数据显示到前端,不管是WPF,还是提供接口,单位是必不可少的,那么点位表可以改为如下样式:
FunctionCode | Address | PropertyName | Unit |
---|---|---|---|
3 | 100 | Vol | V |
3 | 101 | Cur | A |
3 | 102 | Power | W |
3 | 103 | PowerRate | % |
- 精度,不同属性的精度可能会不同,比如电压值是要将小数点往前移2位的,也就是*0.01;但是功率因数是不用的,那么点位表可以改为如下样式:
FunctionCode | Address | PropertyName | Unit | Calculation |
---|---|---|---|---|
3 | 100 | Vol | V | 0.01 |
3 | 101 | Cur | A | 0.01 |
3 | 102 | Power | W | 0.01 |
3 | 103 | PowerRate | % | 1 |
ps:留给大家思考还有那些功能是可以使用点位表来实现的。
Q2
如果按我们之前的方案来实现EMS数据采集,在实际项目中,会因为设备的点位太多且不连续从而导致采集速度很慢。但是EMS又是一个对实时性要求比较高的系统,这个应该怎么处理呢?
A2
熟悉Modbus协议后我们可以知道,Modbus协议是一种问答式的协议,必须有一方发出请求,另一方才会响应,且单次请求的字节长度也是有限制的。据我所知单次可采集的点位数量是128个,也就是说单次可以传输的点位数据是256个字节(Byte),也就是256*8个比特(bits)。一旦超过这个数量,就会报错,且两次请求之间需要一定的间隔,我一般会设置成100ms,那么点位数量过多的情况下采集速度必然下降。这个Modbus协议的规则我们没有办法打破。但是我们可以从其他方面来提升采集速度。
- 我们要对点位表进行分组,将尽可能长的连续点位放在一个请求当中。这样我们就可以最大程度上利用我们的Modbus协议。
- 存在不连续的点位时,我们还有一种办法来采集数据,就是假设点位连续法,通过假设法采集连续的点位,然后从其中获取需要的数据。但是这种方式在某些场景是不适用的,有些设备会将没有点的点位屏蔽掉,这种情况如果你采集的点位中包含被屏蔽的点位就会报错。所以请谨慎使用。
写在结尾
这篇文章我们主要讲解了两个在采集过程中会遇到的问题和疑惑,希望能给大家带来帮助,如果你有其他问题或者疑惑也可以在评论区讨论。天道酬勤,与君共勉!