Compare commits
2 Commits
a72977cd79
...
91db6c959e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91db6c959e | ||
|
|
7b44f97ddb |
@@ -431,3 +431,57 @@ LKLG7C4E3NA774736 | JT808 | 2026-07-01 | daily_total_mileage_km | 12345.600 | sa
|
|||||||
```
|
```
|
||||||
|
|
||||||
说明:生产 TDengine 中已经存在大量 808 非零 `total_mileage_km` 采样,但许多 phone 尚未映射到 VIN,因此 MySQL 按 VIN 的统计只会覆盖已解析 VIN 的车辆。下一步应继续补齐 `vehicle_identity_binding`,让更多 808 车辆进入统计。
|
说明:生产 TDengine 中已经存在大量 808 非零 `total_mileage_km` 采样,但许多 phone 尚未映射到 VIN,因此 MySQL 按 VIN 的统计只会覆盖已解析 VIN 的车辆。下一步应继续补齐 `vehicle_identity_binding`,让更多 808 车辆进入统计。
|
||||||
|
|
||||||
|
## 2026-07-01 23:23 808 注册身份自动维护复验
|
||||||
|
|
||||||
|
部署版本已更新:
|
||||||
|
|
||||||
|
- Git commit:`7b44f97`
|
||||||
|
- 镜像:`crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-gateway-go:go-7b44f97-20260701232200`
|
||||||
|
|
||||||
|
本轮修复内容:
|
||||||
|
|
||||||
|
- 808 `0x0100` 注册帧解析 `province`、`city`、`manufacturer`、`device_type`、`device_id`、`plate_color`、`plate`。
|
||||||
|
- 808 `0x0102` 鉴权帧解析 `auth_token`。
|
||||||
|
- Go gateway 在 identity resolve 后写入 `jt808_registration`,普通上行也会刷新 `latest_seen_at`。
|
||||||
|
- 注册帧通过车牌解析到 VIN 后,会尝试把 phone/device/plate 反写到 `vehicle_identity_binding`。
|
||||||
|
- 注册帧车牌支持 GBK 解码,避免 `Incorrect string value` 写入错误。
|
||||||
|
|
||||||
|
验证命令:
|
||||||
|
|
||||||
|
```text
|
||||||
|
go test ./...
|
||||||
|
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ./cmd/gateway
|
||||||
|
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ./cmd/history-writer
|
||||||
|
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ./cmd/stat-writer
|
||||||
|
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ./cmd/realtime-api
|
||||||
|
```
|
||||||
|
|
||||||
|
ECS 运行状态:
|
||||||
|
|
||||||
|
```text
|
||||||
|
go-vehicle-gateway | go-7b44f97-20260701232200 | 0.0.0.0:808->808, 0.0.0.0:32960->32960
|
||||||
|
go-history-writer | go-7b44f97-20260701232200 | Up
|
||||||
|
go-stat-writer | go-7b44f97-20260701232200 | Up
|
||||||
|
go-realtime-api | go-7b44f97-20260701232200 | 0.0.0.0:20210->20210
|
||||||
|
```
|
||||||
|
|
||||||
|
生产日志确认:
|
||||||
|
|
||||||
|
- 新版本启动后真实 808、32960 连接持续进入。
|
||||||
|
- GBK 车牌注册帧不再出现 `Incorrect string value`。
|
||||||
|
|
||||||
|
MySQL `jt808_registration` 确认:
|
||||||
|
|
||||||
|
```text
|
||||||
|
registration_rows=214
|
||||||
|
distinct_phone=214
|
||||||
|
vin_rows=74
|
||||||
|
plate_rows=74
|
||||||
|
device_rows=72
|
||||||
|
|
||||||
|
013079963379 | device_id=9963379 | plate=沪A06788F | vin=LKLG7C4E3NA774736 | latest_registered_at=2026-07-01 23:23:01
|
||||||
|
013079963321 | device_id=9963321 | plate=沪A59613F | vin=LKLG7C4EXNA774796 | latest_registered_at=2026-07-01 23:23:04
|
||||||
|
```
|
||||||
|
|
||||||
|
说明:`jt808_registration.phone` 保存 808 包头原始 phone;`vehicle_identity_binding.phone` 中已有部分去前导零 phone。Go resolver 会同时查询原始 phone 和去前导零 phone。
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ require (
|
|||||||
github.com/redis/go-redis/v9 v9.17.2
|
github.com/redis/go-redis/v9 v9.17.2
|
||||||
github.com/segmentio/kafka-go v0.4.49
|
github.com/segmentio/kafka-go v0.4.49
|
||||||
github.com/taosdata/driver-go/v3 v3.8.1
|
github.com/taosdata/driver-go/v3 v3.8.1
|
||||||
|
golang.org/x/text v0.29.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
package jt808
|
package jt808
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
"lingniu-vehicle-ingest/go/vehicle-gateway/internal/envelope"
|
"lingniu-vehicle-ingest/go/vehicle-gateway/internal/envelope"
|
||||||
|
"golang.org/x/text/encoding/simplifiedchinese"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -318,7 +321,18 @@ func fixedText(data []byte) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func freeText(data []byte) string {
|
func freeText(data []byte) string {
|
||||||
return strings.TrimRight(strings.TrimSpace(string(data)), "\x00")
|
data = bytes.Trim(data, "\x00 ")
|
||||||
|
if len(data) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if utf8.Valid(data) {
|
||||||
|
return string(data)
|
||||||
|
}
|
||||||
|
decoded, err := simplifiedchinese.GBK.NewDecoder().Bytes(data)
|
||||||
|
if err == nil && utf8.Valid(decoded) {
|
||||||
|
return string(decoded)
|
||||||
|
}
|
||||||
|
return strings.ToValidUTF8(string(data), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseBCDTime(data []byte) time.Time {
|
func parseBCDTime(data []byte) time.Time {
|
||||||
|
|||||||
@@ -153,6 +153,25 @@ func TestParseFrameParsesRegistrationIdentity(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseFrameDecodesGBKRegistrationPlate(t *testing.T) {
|
||||||
|
body := make([]byte, 0, 46)
|
||||||
|
body = binary.BigEndian.AppendUint16(body, 16)
|
||||||
|
body = binary.BigEndian.AppendUint16(body, 32)
|
||||||
|
body = appendFixedASCII(body, "YUTNG", 5)
|
||||||
|
body = appendFixedASCII(body, "ZK6105CHEVNPG4", 20)
|
||||||
|
body = appendFixedASCII(body, "DEV0002", 7)
|
||||||
|
body = append(body, 2)
|
||||||
|
body = append(body, []byte{0xBB, 0xA6, 'A', '5', '3', '3', '0', '1'}...)
|
||||||
|
|
||||||
|
env, err := ParseFrame(buildFrame(0x0100, "013079963380", 9, body), 1782918600000, "115.231.168.135:43625")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ParseFrame() error = %v", err)
|
||||||
|
}
|
||||||
|
if env.Plate != "沪A53301" {
|
||||||
|
t.Fatalf("plate = %q", env.Plate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseFrameParsesAuthenticationToken(t *testing.T) {
|
func TestParseFrameParsesAuthenticationToken(t *testing.T) {
|
||||||
env, err := ParseFrame(buildFrame(0x0102, "064646848757", 8, []byte("g7gps")), 1782918600000, "115.231.168.135:43625")
|
env, err := ParseFrame(buildFrame(0x0102, "064646848757", 8, []byte("g7gps")), 1782918600000, "115.231.168.135:43625")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user