puzhibing
2026-02-12 9aafc10be83aaec35e809a10d99b7b90b09c243f
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package com.xiaopeng.vehicleConvoy.util;
 
 
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.api.dto.vehicleConvoy.BaseImOpenDto;
import com.xiaopeng.api.dto.vehicleConvoy.VehicleTemperatureDto;
import com.xiaopeng.api.feignClient.vehicleConvoy.VehicleControlClient;
import com.xiaopeng.api.vo.vehicleConvoy.VehicleTemperatureVo;
import com.xiaopeng.api.vo.vehicleConvoy.VehiclesCommandVo;
import com.xiaopeng.common.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
 
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
 
/**
 * 车辆控制工具类
 */
@Slf4j
@Component
public class VehicleControlUtil {
 
    @Resource
    private VehicleControlClient vehicleControlClient;
    // 车辆控制接口appid
    @Value("${vehicle.control.appId}")
    private String appid;
    // 车辆控制接口appSecret
    @Value("${vehicle.control.appSecret}")
    private String appSecret;
 
 
    /**
     * 查询车辆内温度
     * @param uid   用户id
     * @param vin   车辆vin
     * 测试车辆:L1NNSGHA5PB000204
     * @return
     */
    public VehicleTemperatureDto queryVehicleTemperature(String uid, String vin) {
        String nonce = System.currentTimeMillis() + "";
        VehicleTemperatureVo vo = new VehicleTemperatureVo();
        vo.setVin(vin);
        vo.setStateList(Arrays.asList("hvacInnerTemp"));
        vo.setAppId(appid);
        vo.setNonce(nonce);
        vo.setOpenId("robot_taxi");
        vo.setSign(sign("", nonce));
        log.info("查询车内温度 请求参数:{}", JSON.toJSONString(vo));
        BaseImOpenDto baseImOpenDto = vehicleControlClient.queryVehicleTemperature(vo, uid);
        if (null == baseImOpenDto || null == baseImOpenDto.getData()) {
            throw new RuntimeException("查询车内温度失败");
        }
        if (200 != baseImOpenDto.getCode()) {
            throw new RuntimeException("查询车内温度失败:" + baseImOpenDto.getMsg());
        }
        return (VehicleTemperatureDto) baseImOpenDto.getData();
    }
 
 
    /**
     * 车辆控制操作
     * @param commandVo
     * @return  msgId 消息id,对比消息回调通知
     * 测试车辆:L1NNSGHA5PB000204
     */
    public String vehiclesCommand(VehiclesCommandVo commandVo){
        String nonce = System.currentTimeMillis() + "";
        commandVo.setAppId(appid);
        commandVo.setNonce(nonce);
        commandVo.setOpenId("robot_taxi");
        Map<String, Object> map = new HashMap<>();
        map.put("uid", commandVo.getUid());
        map.put("vin", commandVo.getVin());
        map.put("commandCode", commandVo.getCommandCode());
        map.put("extParam", commandVo.getExtParam());
        commandVo.setSign(sign(JSON.toJSONString(map), nonce));
        log.info("车辆控制 请求参数:{}", JSON.toJSONString(commandVo));
        BaseImOpenDto baseImOpenDto = vehicleControlClient.vehiclesCommand(commandVo, commandVo.getUid());
        if (null == baseImOpenDto || null == baseImOpenDto.getData()) {
            throw new RuntimeException("车辆控制失败");
        }
        if (200 != baseImOpenDto.getCode()) {
            throw new RuntimeException("车辆控制失败:" + baseImOpenDto.getMsg());
        }
        return baseImOpenDto.getData().toString();
    }
 
 
 
 
 
 
 
    /**
     * 参数签名
     * @param nonce 请求时间戳
     * @return
     */
    private String sign(String body, String nonce){
        Map<String, String> map = new HashMap<>();
        map.put("openId", appid);
        map.put("body", body);
        map.put("nonce", nonce);
        //将map的key进行自然排序再以key+value拼接中间无分隔符
        StringBuilder stringBuilder = new StringBuilder();
        map.keySet().stream().sorted(String::compareTo).forEach(key -> {
            String v = map.get(key);
            if(StringUtils.isNotEmpty(v)){
                stringBuilder.append(key).append(v);
            }
        });
        String stringA = stringBuilder.toString();
        String stringB = appid + stringA + appSecret;
        log.info("车控接口待签名串:{}", stringB);
        try {
            byte[] signByte = HMACSHA1.HmacSHA1Encrypt(stringB, appSecret);
            String localSign = Base64.encodeBase64String(signByte);
            log.info("车控接口已签名串:{}", stringB);
            return localSign;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("车控接口签名失败", e);
            throw new RuntimeException("车控接口签名失败");
        }
    }
}