2023-12-13 11:22:30 +08:00
|
|
|
package cidcmodbus
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2023-12-18 16:26:17 +08:00
|
|
|
"log/slog"
|
2023-12-13 11:22:30 +08:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"joylink.club/bj-rtsts-server/config"
|
|
|
|
"joylink.club/bj-rtsts-server/ts/simulation/wayside/memory"
|
2023-12-20 14:13:23 +08:00
|
|
|
"joylink.club/iot/dto"
|
2023-12-13 11:22:30 +08:00
|
|
|
"joylink.club/iot/service"
|
|
|
|
"joylink.club/rtsssimulation/component"
|
|
|
|
"joylink.club/rtsssimulation/entity"
|
|
|
|
)
|
|
|
|
|
|
|
|
// 联锁驱采Modbus服务
|
|
|
|
type CidcModbusService interface {
|
|
|
|
Stop()
|
|
|
|
}
|
|
|
|
|
|
|
|
var serviceManage = &cidcModbusServiceManage{}
|
|
|
|
|
|
|
|
type cidcModbusServiceManage struct {
|
|
|
|
services []*cidcModbusService
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *cidcModbusServiceManage) Stop() {
|
|
|
|
for _, s := range m.services {
|
|
|
|
s.Stop()
|
|
|
|
}
|
|
|
|
m.services = nil
|
|
|
|
}
|
|
|
|
|
2023-12-13 11:24:22 +08:00
|
|
|
func Stop() {
|
2023-12-13 11:22:30 +08:00
|
|
|
serviceManage.Stop()
|
|
|
|
}
|
|
|
|
|
2023-12-13 11:24:22 +08:00
|
|
|
func Start(vs *memory.VerifySimulation) error {
|
2023-12-13 11:22:30 +08:00
|
|
|
for _, cmc := range vs.GetCidcModbusConfig() {
|
|
|
|
if cmc.Open {
|
|
|
|
cms, err := newCidcModbusService(vs, &cmc)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
serviceManage.services = append(serviceManage.services, cms)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type cidcModbusService struct {
|
2023-12-18 16:26:17 +08:00
|
|
|
vs *memory.VerifySimulation // 仿真对象
|
|
|
|
modbusConfig *config.CidcModbusConfig // modbus驱采配置
|
|
|
|
ecsUid string // 联锁集中站uid
|
|
|
|
qcms service.IotQcMappingService // modbus驱采映射服务
|
2023-12-13 11:22:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *cidcModbusService) update() {
|
|
|
|
wd := entity.GetWorldData(s.vs.World)
|
|
|
|
qce := wd.FindQcEntityByEcsId(s.ecsUid)
|
|
|
|
if qce == nil {
|
|
|
|
panic(fmt.Sprintf("联锁驱采Modbus服务查询状态失败,仿真不存在集中站联锁: %s", s.ecsUid))
|
|
|
|
}
|
|
|
|
qcs := component.CiQcStateType.Get(qce)
|
|
|
|
if qcs == nil {
|
|
|
|
panic(fmt.Sprintf("联锁驱采Modbus服务查询状态失败,集中站联锁驱采状态不存在: %s", s.ecsUid))
|
|
|
|
}
|
2023-12-18 17:59:56 +08:00
|
|
|
// 写采集数据
|
2023-12-18 16:26:17 +08:00
|
|
|
err := s.qcms.WriteCjBytes(qcs.Cbs)
|
|
|
|
if err != nil {
|
|
|
|
slog.Error("联锁驱采Modbus服务写采集数据失败", err)
|
|
|
|
}
|
2023-12-18 17:59:56 +08:00
|
|
|
// 读驱动数据
|
2023-12-18 16:26:17 +08:00
|
|
|
qs := s.qcms.GetQdBytes()
|
2023-12-13 11:22:30 +08:00
|
|
|
qcs.Qbs = qs
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop implements CidcModbusService.
|
|
|
|
func (s *cidcModbusService) Stop() {
|
2023-12-18 16:26:17 +08:00
|
|
|
s.qcms.Stop()
|
2023-12-13 11:22:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func newCidcModbusService(vs *memory.VerifySimulation, modbusConfig *config.CidcModbusConfig) (*cidcModbusService, error) {
|
|
|
|
station := vs.Repo.FindStationByStationName(modbusConfig.Ecs)
|
|
|
|
if station == nil {
|
|
|
|
return nil, fmt.Errorf("联锁驱采Modbus服务创建失败,未找到联锁集中站: %s", modbusConfig.Ecs)
|
|
|
|
}
|
|
|
|
ecsId := station.Id()
|
|
|
|
// 获取
|
|
|
|
wd := entity.GetWorldData(vs.World)
|
|
|
|
qce := wd.FindQcEntityByEcsId(ecsId)
|
|
|
|
if qce == nil {
|
|
|
|
return nil, fmt.Errorf("联锁驱采Modbus服务创建失败,仿真不存在集中站联锁: %s", ecsId)
|
|
|
|
}
|
|
|
|
qcs := component.CiQcStateType.Get(qce)
|
2023-12-20 14:13:23 +08:00
|
|
|
qcms, err := service.NewModbusQcService(converToModbusDcConfig(modbusConfig, len(qcs.Qbs), len(qcs.Cbs)))
|
2023-12-13 11:22:30 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("联锁驱采Modbus服务创建失败: %s", err)
|
|
|
|
}
|
|
|
|
cms := &cidcModbusService{
|
|
|
|
vs: vs,
|
|
|
|
modbusConfig: modbusConfig,
|
|
|
|
ecsUid: ecsId,
|
2023-12-18 16:26:17 +08:00
|
|
|
qcms: qcms,
|
2023-12-13 11:22:30 +08:00
|
|
|
}
|
2023-12-18 17:59:56 +08:00
|
|
|
// 注册驱采数据仿真更新
|
|
|
|
qcms.RegisterQcDataHandleScheduleTask(cms.update, time.Millisecond*time.Duration(modbusConfig.Interval))
|
2023-12-13 11:22:30 +08:00
|
|
|
return cms, nil
|
|
|
|
}
|
|
|
|
|
2023-12-20 14:13:23 +08:00
|
|
|
func converToModbusDcConfig(config *config.CidcModbusConfig, qdl, cjl int) *dto.ModbusConfig {
|
|
|
|
return &dto.ModbusConfig{
|
2023-12-13 11:22:30 +08:00
|
|
|
Url: config.Url,
|
|
|
|
UnitId: config.UnitId,
|
|
|
|
Endianness: config.Endianness,
|
|
|
|
Interval: config.Interval,
|
|
|
|
Timeout: config.Timeout,
|
2023-12-20 14:13:23 +08:00
|
|
|
Qdl: uint32(qdl),
|
|
|
|
Cjl: uint32(cjl),
|
2023-12-13 11:22:30 +08:00
|
|
|
Mapping: convertToModbusDcMapping(config.Mapping),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-20 14:13:23 +08:00
|
|
|
func convertToModbusDcMapping(modbusDcMapping []config.ModbusDcMapping) []*dto.ModbusDcMapping {
|
|
|
|
res := make([]*dto.ModbusDcMapping, 0)
|
2023-12-13 11:22:30 +08:00
|
|
|
for _, mdm := range modbusDcMapping {
|
2023-12-20 14:13:23 +08:00
|
|
|
res = append(res, &dto.ModbusDcMapping{
|
|
|
|
Function: mdm.Function,
|
|
|
|
Addr: mdm.Addr,
|
|
|
|
Quantity: mdm.Quantity,
|
|
|
|
Type: mdm.Type,
|
|
|
|
Start: mdm.Start,
|
2023-12-13 11:22:30 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
return res
|
|
|
|
}
|