13 Commits

Author SHA1 Message Date
6a25b6acc7 修改返回值定义 2025-10-17 16:01:11 +08:00
25ba002da2 添加系统相关&节假日相关&用户相关RPC 2025-10-17 15:52:15 +08:00
6429b34a24 添加自动化相关方法 2025-10-16 16:33:06 +08:00
d82138e0e4 添加自动化相关方法 2025-10-16 16:22:12 +08:00
5f5116a4a1 修改文档 2025-10-16 10:53:25 +08:00
89542f9475 修改模块地址 2025-10-16 10:45:49 +08:00
3333514cff 修改保存升级结果方法参数 2025-10-07 20:12:38 +08:00
c283409b9e 添加设备操作日志方法 2025-09-25 14:23:17 +08:00
207b56e419 语音助手参数添加在线状态字段 2025-09-20 17:42:05 +08:00
69e7893d27 添加语音助手相关方法 2025-09-19 18:00:55 +08:00
30e530de6d 修改日志等级 2025-09-15 16:33:50 +08:00
a15b442e64 修改日志驱动类型 2025-09-15 16:11:05 +08:00
ed3bd2bd80 添加服务相关方法&增加日志 2025-09-15 15:53:11 +08:00
11 changed files with 414 additions and 39 deletions

View File

@@ -10,7 +10,7 @@ package main
import ( import (
"log" "log"
"gitee.com/LifetimeNine/singularity-rpc-client/pkg/rpc" "git.lifetime-nine.cn/singularity/rpc-client/pkg/rpc"
) )
func main() { func main() {

8
go.mod
View File

@@ -1,7 +1,11 @@
module gitee.com/LifetimeNine/singularity-rpc-client module git.lifetime-nine.cn/singularity/rpc-client
go 1.24.3 go 1.24.3
require golang.org/x/net v0.43.0 require golang.org/x/net v0.43.0
require golang.org/x/text v0.28.0 // indirect require (
go.uber.org/multierr v1.10.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/text v0.28.0 // indirect
)

4
go.sum
View File

@@ -1,3 +1,7 @@
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=

62
pkg/rpc/automation.go Normal file
View File

@@ -0,0 +1,62 @@
package rpc
import (
"fmt"
"time"
)
// 自动化相关RPC
type Automation struct{}
// 获取自动化列表
func (a *Automation) GetList() (*[]AutomationTask, error) {
result := &Result[[]AutomationTask]{}
if err := GetRequest().Send("automation.list", map[string]any{}, result); err != nil {
return nil, err
}
if result.Code != 0 {
return nil, fmt.Errorf("%s", result.Message)
}
return &result.Data, nil
}
// 获取自动化详情
func (a *Automation) GetDetail(automationId uint32) (*AutomationTask, error) {
body := map[string]any{
"automation_id": automationId,
}
result := &Result[AutomationTask]{}
if err := GetRequest().Send("automation.detail", body, result); err != nil {
return nil, err
}
if result.Code != 0 {
return nil, fmt.Errorf("%s", result.Message)
}
return &result.Data, nil
}
// 更新条件最后执行时间
func (a *Automation) UpdateConditionLastExecuteTime(conditionId uint32, lastExecuteTime time.Time) error {
body := map[string]any{
"condition_id": conditionId,
"time": lastExecuteTime.Format(time.DateTime),
}
result := &Result[any]{}
if err := GetRequest().Send("automation.update_condition_last_execute_time", body, result); err != nil {
return err
}
if result.Code != 0 {
return fmt.Errorf("%s", result.Message)
}
return nil
}
var automation *Automation
// 获取自动化相关RPC
func GetAutomation() *Automation {
if automation == nil {
automation = &Automation{}
}
return automation
}

View File

@@ -5,16 +5,6 @@ import (
"time" "time"
) )
var device *Device
// 获取设备相关RPC类
func GetDevice() *Device {
if device == nil {
device = &Device{}
}
return device
}
// 设备相关RPC // 设备相关RPC
type Device struct{} type Device struct{}
@@ -161,18 +151,78 @@ func (d *Device) UpdateVersion(deviceId uint32, versionNumber uint) error {
} }
// 保存升级结果 // 保存升级结果
func (d *Device) SaveUpgradeResult(upgradeTaskId uint32, status uint8, finishTime time.Time) error { func (d *Device) SaveUpgradeResult(upgradeTaskId uint32, result uint8, finishTime time.Time) error {
body := map[string]any{ body := map[string]any{
"upgrade_task_id": upgradeTaskId, "upgrade_task_id": upgradeTaskId,
"status": status, "result": result,
"finish_time": finishTime.Format(time.DateTime), "finish_time": finishTime.Format(time.DateTime),
} }
result := &Result[any]{} res := &Result[any]{}
if err := GetRequest().Send("device.save_upgrade_result", body, result); err != nil { if err := GetRequest().Send("device.save_upgrade_result", body, res); err != nil {
return err return err
} }
if result.Code != 0 { if res.Code != 0 {
return fmt.Errorf("%s", result.Message) return fmt.Errorf("%s", res.Message)
} }
return nil return nil
} }
// 获取语音助手参数列表
func (d *Device) GetVoiceAssistantList() ([]VoiceAssistant, error) {
body := map[string]any{}
result := &Result[[]VoiceAssistant]{}
if err := GetRequest().Send("device.get_voice_assistant_list", body, result); err != nil {
return nil, err
}
if result.Code != 0 {
return nil, fmt.Errorf("%s", result.Message)
}
return result.Data, nil
}
// 获取设备语音助手参数
func (d *Device) GetVoiceAssistant(deviceId uint32) (*VoiceAssistant, error) {
body := map[string]any{
"device_id": deviceId,
}
result := &Result[*VoiceAssistant]{}
if err := GetRequest().Send("device.get_voice_assistant", body, result); err != nil {
return nil, err
}
if result.Code != 0 {
return nil, fmt.Errorf("%s", result.Message)
}
return result.Data, nil
}
// 记录设备操作日志
func (d *Device) RecordOperationLog(deviceId uint32, platform DeviceOperationLogPlatform, attribute string, value any, valueType uint8, result DeviceOperationLogResult, reason *string, userId *uint32) error {
body := map[string]any{
"device_id": deviceId,
"platform": platform,
"attribute": attribute,
"value": value,
"value_type": valueType,
"result": result,
"reason": reason,
"user_id": userId,
}
res := &Result[any]{}
if err := GetRequest().Send("device.record_operation_log", body, res); err != nil {
return err
}
if res.Code != 0 {
return fmt.Errorf("%s", res.Message)
}
return nil
}
var device *Device
// 获取设备相关RPC类
func GetDevice() *Device {
if device == nil {
device = &Device{}
}
return device
}

33
pkg/rpc/holiday.go Normal file
View File

@@ -0,0 +1,33 @@
package rpc
import (
"fmt"
"time"
)
// 节假日相关RPC
type Holiday struct{}
// 判断某个日期是否是节假日
func (h *Holiday) IsHoliday(date time.Time) (*bool, error) {
body := map[string]any{
"date": date.Format(time.DateOnly),
}
result := &Result[bool]{}
if err := GetRequest().Send("holiday.is_holiday", body, result); err != nil {
return nil, err
}
if result.Code != 0 {
return nil, fmt.Errorf("%s", result.Message)
}
return &result.Data, nil
}
var holiday *Holiday
func GetHoliday() *Holiday {
if holiday == nil {
holiday = &Holiday{}
}
return holiday
}

View File

@@ -13,6 +13,7 @@ import (
"os" "os"
"time" "time"
"go.uber.org/zap"
"golang.org/x/net/http2" "golang.org/x/net/http2"
) )
@@ -24,6 +25,7 @@ type Request struct {
port uint16 port uint16
rootCertPath string rootCertPath string
client *http.Client client *http.Client
logger *zap.SugaredLogger
} }
// 发送请求 // 发送请求
@@ -58,11 +60,19 @@ func (r *Request) Send(methodName string, body any, responseBody any) error {
return fmt.Errorf("response body json unmarshal fail: %v", err) return fmt.Errorf("response body json unmarshal fail: %v", err)
} }
if r.logger != nil {
r.logger.Debugf("method: %s, request: %s, response: %s",
methodName,
string(bodyByte),
string(responseBodyByte),
)
}
return nil return nil
} }
// 初始化 // 初始化
func Initiate(host string, port uint16, rootCertPath string) error { func Initiate(host string, port uint16, rootCertPath string, logger *zap.SugaredLogger) error {
rootCert, err := os.ReadFile(rootCertPath) rootCert, err := os.ReadFile(rootCertPath)
if err != nil { if err != nil {
return fmt.Errorf("cert file read fail") return fmt.Errorf("cert file read fail")
@@ -70,6 +80,7 @@ func Initiate(host string, port uint16, rootCertPath string) error {
defaultRequest.host = host defaultRequest.host = host
defaultRequest.port = port defaultRequest.port = port
defaultRequest.rootCertPath = rootCertPath defaultRequest.rootCertPath = rootCertPath
defaultRequest.logger = logger
certPool := x509.NewCertPool() certPool := x509.NewCertPool()
certPool.AppendCertsFromPEM(rootCert) certPool.AppendCertsFromPEM(rootCert)

46
pkg/rpc/server.go Normal file
View File

@@ -0,0 +1,46 @@
package rpc
import "fmt"
// 服务相关RPC
type Server struct{}
// 获取Websocket签名信息
func (s *Server) GetWebsocketSignData(sign string) (*WebsocketSignData, error) {
body := map[string]any{
"sign": sign,
}
result := &Result[WebsocketSignData]{}
if err := GetRequest().Send("server.get_websocket_sign", body, result); err != nil {
return nil, err
}
if result.Code != 0 {
return nil, fmt.Errorf("%s", result.Message)
}
return &result.Data, nil
}
// 删除Websocket签名
func (s *Server) DeleteWebsocketSign(sign string) error {
body := map[string]any{
"sign": sign,
}
result := &Result[WebsocketSignData]{}
if err := GetRequest().Send("server.get_websocket_sign", body, result); err != nil {
return err
}
if result.Code != 0 {
return fmt.Errorf("%s", result.Message)
}
return nil
}
var server *Server
// 获取服务相关RPC类
func GetServer() *Server {
if server == nil {
server = &Server{}
}
return server
}

31
pkg/rpc/system.go Normal file
View File

@@ -0,0 +1,31 @@
package rpc
import "fmt"
// 系统相关RPC
type System struct{}
// 获取系统位置
func (s *System) GetSystemLocation() (*SystemLocation, error) {
body := map[string]any{
"key": "system_location",
}
result := &Result[SystemLocation]{}
if err := GetRequest().Send("system.get_config", body, result); err != nil {
return nil, err
}
if result.Code != 0 {
return nil, fmt.Errorf("%s", result.Message)
}
return &result.Data, nil
}
var system *System
// 获取系统相关RPC
func GetSystem() *System {
if system == nil {
system = &System{}
}
return system
}

View File

@@ -37,32 +37,134 @@ const (
// 响应结果 // 响应结果
type Result[D any] struct { type Result[D any] struct {
Code ResultCode `json:"code"` Code ResultCode `json:"code"` // 状态码
Message string `json:"message"` Message string `json:"message"` // 消息
Data D `json:"data"` Data D `json:"data"` // 数据
} }
// 设备详情 // 设备详情
type DeviceDetail struct { type DeviceDetail struct {
Type uint8 `json:"type"` Type uint8 `json:"type"` // 设备类型
ConnectType uint8 `json:"connect_type"` ConnectType uint8 `json:"connect_type"` // 连接类型
Secret string `json:"secret"` Secret string `json:"secret"` // 秘钥
PId uint32 `json:"p_id"` PId uint32 `json:"p_id"` // 上层设备ID
DataId uint32 `json:"data_id"` DataId uint32 `json:"data_id"` // 参数数据ID
} }
// 设备属性参数 // 设备属性参数
type DeviceAttributeOption struct { type DeviceAttributeOption struct {
Type uint8 `json:"type"` Type uint8 `json:"type"` // 设备类型
ContentType uint8 `json:"content_type"` ConnectType uint8 `json:"connect_type"` // 连接类型
Attribute []struct { Attribute []struct {
Type uint8 `json:"type"` Type uint8 `json:"type"` // 属性类型
Name string `json:"name"` Name string `json:"name"` // 属性名称
Flag uint8 `json:"flag"` Flag uint8 `json:"flag"` // 属性标识
Field string `json:"field"` Field string `json:"field"` // 属性字段名
Readonly bool `json:"readonly"` Readonly bool `json:"readonly"` // 是否只读
AllowItem *[]uint8 `json:"allow_item,omitempty"` AllowItem *[]uint8 `json:"allow_item,omitempty"` // 可用选项列表
Min *uint32 `json:"min,omitempty"` Min *uint32 `json:"min,omitempty"` // 最小值
Max *uint32 `json:"max,omitempty"` Max *uint32 `json:"max,omitempty"` // 最大值
} `json:"attribute"` } `json:"attribute"` // 设备属性列表
}
// Websocket签名数据
type WebsocketSignData struct {
UserId uint32 `json:"user_id"` // 用户ID
Platform string `json:"platform"` // 平台
}
// 语音助手数据
type VoiceAssistant struct {
Id uint32 `json:"id"` // ID
Type uint8 `json:"type"` // 类型
OnlineStatus uint8 `json:"online_status"` // 在线状态
BemFaEnable uint8 `json:"bem_fa_enable"` // 是否启用巴法平台
BemFaName string `json:"bem_fa_name"` // 巴法平台名称
}
// 设备操作日志平台
type DeviceOperationLogPlatform uint8
const (
// 设备操作日志平台 - 管理后台
DeviceOperationLogPlatformBackstage DeviceOperationLogPlatform = iota + 1
// 设备操作日志平台 - 语音助手
DeviceOperationLogPlatformAssistant
// 设备操作日志平台 - 设备
DeviceOperationLogPlatformDevice
// 设备操作日志平台 - APP
DeviceOperationLogPlatformApp
// 设备操作日志平台 - 自动化
DeviceOperationLogPlatformAutomation
// 设备操作日志平台 - 桌面端
DeviceOperationLogPlatformDesktop
// 设备操作日志平台 - API
DeviceOperationLogPlatformAPI
)
// 设备操作日志结果
type DeviceOperationLogResult uint8
const (
// 设备操作日志结果 - 成功
DeviceOperationLogResultSuccess DeviceOperationLogResult = iota + 1
// 设备操作日志结果 - 失败
DeviceOperationLogResultFail
)
// 自动化条件
type AutomationCondition struct {
Id uint32 `json:"id"` // ID
ConditionType uint8 `json:"condition_type"` // 条件类型
TriggerType uint8 `json:"trigger_type"` // 触发类型
DeviceId *uint32 `json:"device_id,omitempty"` // 设备ID
DeviceAttribute *string `json:"device_attribute,omitempty"` // 设备属性
TargetValue *string `json:"target_value,omitempty"` // 目标值
TimeValue *string `json:"time_value,omitempty"` // 时间值
RepeatType *uint8 `json:"repeat_type,omitempty"` // 时间重复类型
CustomRepeatRange []uint8 `json:"custom_repeat_range"` // 自定义重复范围
LastExecuteTime *string `json:"last_execute_time,omitempty"` // 最后执行时间
}
// 自动化动作
type AutomationAction struct {
Id uint32 `json:"id"` // ID
Type uint8 `json:"type"` // 类型
DeviceId *uint32 `json:"device_id,omitempty"` // 设备ID
DeviceAttribute *string `json:"device_attribute,omitempty"` // 设备属性
TargetValue *string `json:"target_value,omitempty"` // 目标值
ValueType *uint8 `json:"value_type,omitempty"` // 值类型
DelayDuration *uint32 `json:"delay_duration,omitempty"` // 延时时长
NoticeContent *string `json:"notice_content,omitempty"` // 通知内容
}
// 自动化任务
type AutomationTask struct {
Id uint32 `json:"id"` // ID
Title string `json:"title"` // 标题
CreateUserId uint32 `json:"create_user_id"` // 创建用户ID
EffectivePeriod uint8 `json:"effective_period"` // 生效时段
PeriodBeginTime *string `json:"period_begin_time,omitempty"` // 时段开始时间
PeriodEndTime *string `json:"period_end_time,omitempty"` // 时段结束时间
RepeatType uint8 `json:"repeat_type"` // 重复类型
CustomRepeatRange []uint8 `json:"custom_repeat_range"` // 自定义重复范围
IsSatisfyAll uint8 `json:"is_satisfy_all"` // 是否要满足所有条件
ConditionList []AutomationCondition `json:"condition_list"` // 条件列表
ActionList []AutomationAction `json:"action_list"` // 动作列表
}
// 系统位置
type SystemLocation struct {
Longitude float64 `json:"longitude,string"` // 经度
Latitude float64 `json:"latitude,string"` // 维度
}
// 用户详情
type UserDetail struct {
Mobile *string `json:"mobile,omitempty"` // 手机号
Email *string `json:"email,omitempty"` // 邮箱
Nickname *string `json:"nickname,omitempty"` // 昵称
QQ *string `json:"qq,omitempty"` // QQ
Status uint8 `json:"status"` // 状态
} }

32
pkg/rpc/user.go Normal file
View File

@@ -0,0 +1,32 @@
package rpc
import "fmt"
// 用户相关RPC
type User struct{}
// 获取用户详情
func (u *User) GetDetail(userId uint32) (*UserDetail, error) {
body := map[string]any{
"user_id": userId,
"field_list": []string{"mobile", "email", "nickname", "qq", "status"},
}
result := &Result[UserDetail]{}
if err := GetRequest().Send("user.get_detail", body, result); err != nil {
return nil, err
}
if result.Code != 0 {
return nil, fmt.Errorf("%s", result.Message)
}
return &result.Data, nil
}
var user *User
// 获取用户相关RPC
func GetUser() *User {
if user == nil {
user = &User{}
}
return user
}