1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package com.dy.rtuMw.web.com;
 
import com.dy.rtuMw.server.ServerProperties;
import com.dy.rtuMw.server.forTcp.TcpSessionCache;
import com.dy.rtuMw.server.local.CommandInnerDeaLer;
import com.dy.rtuMw.server.local.ReturnCommand;
import com.dy.rtuMw.server.tasks.RtuDownTask;
import com.dy.common.mw.core.CoreUnit;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol.CommandType;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
 
 
/**
 * @Author liurunyu
 * @Date 2023/12/21 13:58
 * @LastEditTime 2023/12/21 13:58
 * @Description 命令接收
 */
@Slf4j
@RestController
@RequestMapping(path="com")
@SuppressWarnings("unchecked")//java版本越高,对泛型约束越严,所以配置SuppressWarnings("unchecked")
public class CommandCtrl {
 
    @GetMapping(path = "test")
    public BaseResponse<String> test(){
        return BaseResponseUtils.buildSuccess("ok");
    }
 
    @PostMapping(path = "send", consumes = MediaType.APPLICATION_JSON_VALUE)
    public BaseResponse<Command> send(@RequestBody Command com) {
        log.info("收到web系统发来的命令:\n" + com.toString()) ;
 
        String commandType = com.getType() ;
        if(commandType == null){
            return BaseResponseUtils.buildError(ReturnCommand.errored("出错,收到命令的命令类型为空!", com.getId(), com.getCode()));
        }
        String commandId = com.getId() ;
        if(commandId == null){
            return BaseResponseUtils.buildError(ReturnCommand.errored("出错,收到命令的命令ID为空!",null, com.getCode()));
        }
 
        String code = com.getCode() ;
        if(code == null){
            return BaseResponseUtils.buildError(ReturnCommand.errored("出错,收到命令的命令功能码为空!", com.getId(), null));
        }
 
        if(commandType.equals(CommandType.innerCommand)){
            //通信中间件内部命令,例如查询监控中间件时钟,查询RTU在线情况等
            try{
                Command reCom = new CommandInnerDeaLer().deal(com) ;
                /*
                boolean error = false ;
                if(reCom.param != null && reCom.param != null){
                    CommandBackParam cbp = (CommandBackParam)reCom.param ;
                    if(cbp.getSuccess() != null && !cbp.getSuccess().booleanValue()){
                        error = true ;
                        return BaseResponseUtils.buildError(ReturnCommand.errored(cbp.getMessage(), com.getId(), null));
                    }
                }
                if(!error){
                    return BaseResponseUtils.buildError(ReturnCommand.errored(cbp.getMessage(), com.getId(), null));
                }
                */
                return BaseResponseUtils.buildSuccess(reCom);
            }catch(Exception e){
                return BaseResponseUtils.buildError(ReturnCommand.errored("处理内部命令出错" + (e.getMessage() == null?"":("," + e.getMessage())), com.getId(), com.getCode()) );
            }
 
        }else if(commandType.equals(CommandType.outerCommand)){
            //发向RTU的外部命令,异步处理,web端jroups成员同步得到命令处理结果,但构造命令及下发命令和命令结果接收要异步得到
            try{
                return this.dealOuterCommand(com) ;
            }catch(Exception e){
                return BaseResponseUtils.buildError(ReturnCommand.errored("处理发向RTU的外部命令出错" + (e.getMessage() == null?"":("," + e.getMessage())), com.getId(), com.getCode()) );
            }
        }else if(commandType.equals(CommandType.resultCommand)){
            return BaseResponseUtils.buildError(ReturnCommand.errored("出错,通信中间件不接结果类型的命令!", com.getId(), com.getCode()));
        }else{
            return BaseResponseUtils.buildError(ReturnCommand.errored("出错,收到命令的命令功能码为空!", com.getId(), com.getCode()));
        }
    }
 
    /**
     * 处理发向RTU的外部命令
     * @return 结果
     */
    private BaseResponse<Command> dealOuterCommand(Command command){
        String rtuAddr = command.getRtuAddr() ;
        if(rtuAddr == null || rtuAddr.trim().equals("")){
            return BaseResponseUtils.buildError(ReturnCommand.errored("出错,RTU地址为空!", command.getId(), command.getCode())) ;
        }
        rtuAddr = rtuAddr.trim() ;
        Boolean onLine = TcpSessionCache.isConnect(rtuAddr);
        if(onLine == null){
            return BaseResponseUtils.buildError(ReturnCommand.errored("出错,RTU(地址=" + rtuAddr + ")未上线!", command.getId(), command.getCode())) ;
        }else if(!onLine.booleanValue()){
            if(!ServerProperties.isLowPower){
                return BaseResponseUtils.buildError(ReturnCommand.errored("出错,RTU(地址=" + rtuAddr + ")离线!", command.getId(), command.getCode())) ;
            }
        }
 
        //生成异步任务
        RtuDownTask task = new RtuDownTask() ;
        task.data = command ;
        try{
            log.info("构造下发远程命令" + command.getCode() + "的核心任务,并放入任务队列中");
            CoreUnit.getInstance().pushCoreTask(task);
        }catch(Exception e){
            log.error(e.getMessage(), e);
            return BaseResponseUtils.buildError(ReturnCommand.successed("命令处理失败" + e.getMessage(), command.getId(), command.getCode())) ;
        }
 
        return BaseResponseUtils.buildSuccess(ReturnCommand.successed("命令已接受,即将构造并下发命令。", command.getId(), command.getCode()));
    }
 
}