增加开关物模型测试

This commit is contained in:
2025-08-11 19:47:30 +08:00
parent 493a09c715
commit a6b12a50ec
8 changed files with 249 additions and 18 deletions

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

74
controllers/switch.go Normal file
View File

@@ -0,0 +1,74 @@
package controllers
import (
"github.com/gin-gonic/gin"
"iot-mqtt-gin/models"
"iot-mqtt-gin/service"
"net/http"
"time"
)
type SwitchController struct {
}
func NewSwitchController() *SwitchController {
controller := &SwitchController{}
return controller
}
func (s *SwitchController) GetDeviceInfo(c *gin.Context) {
devInfo := service.GetDeviceInfo()
ReturnSuccess(c, 200, "设备完整信息获取成功", devInfo, 0)
}
func (s *SwitchController) UpdateDeviceInfo(c *gin.Context) {
var req models.BaseDevice
if err := c.ShouldBindUri(&req); err != nil {
ReturnError(c, 400, "请求参数错误: "+err.Error())
}
/*var req dto.SystemSwitchRequest
if err := c.ShouldBindUri(&req); err != nil {
ReturnError(c, 400, "请求参数错误: "+err.Error())
}*/
// 补充时间信息
if req.CreatedAt.IsZero() {
req.CreatedAt = time.Now()
}
req.UpdatedAt = time.Now()
req.LastActive = time.Now()
info := service.UpdateDeviceInfo(req)
ReturnSuccess(c, 200, "设备完整信息获取成功", info, 0)
}
func (s *SwitchController) GetTSL(c *gin.Context) {
tsl := service.GetTSL()
ReturnSuccess(c, 200, "设备TSL模型获取成功", tsl, 0)
}
func (s *SwitchController) GetSwitchProperty(c *gin.Context) {
status := service.GetSwitchStatus()
ReturnSuccess(c, 200, "设备状态获取成功", status, 0)
}
func (s *SwitchController) SetSwitchProperty(c *gin.Context) {
var req struct {
PowerStatus bool `json:"powerStatus" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效参数: " + err.Error()})
return
}
tsl := service.SetSwitchStatus(req.PowerStatus)
ReturnSuccess(c, 200, "设备状态更新成功", tsl, 0)
}
func (s *SwitchController) TurnOn(c *gin.Context) {
onStatus := service.TurnOn()
ReturnSuccess(c, 200, "设备开关打开成功", onStatus, 0)
}
func (s *SwitchController) TurnOff(c *gin.Context) {
offStatus := service.TurnOff()
ReturnSuccess(c, 200, "设备开关关闭成功", offStatus, 0)
}
func (s *SwitchController) Toggle(c *gin.Context) {
tsl := service.Toggle()
ReturnSuccess(c, 200, "设备状态切换成功", tsl, 0)
}

15
dto/switch_dto.go Normal file
View File

@@ -0,0 +1,15 @@
package dto
import "time"
// SystemDeviceRequest 用户创建请求结构体
type SystemSwitchRequest struct {
DeviceNumber string `uri:"device_number" binding:"required"`
CreatedAt time.Time `json:"created_at"` // 创建时间
UpdatedAt time.Time `json:"updated_at"` // 更新时间
LastActive time.Time `json:"last_active"` // 最后活动时间
}
// SystemDeviceResponse 用户创建返回结构体
type SystemSwitchResponse struct {
}

View File

@@ -66,10 +66,11 @@ func main() {
// 初始化所有控制器
mqttUserCtrl := controllers.NewMqttuserController()
deviceCtrl := controllers.NewDeviceController(mqttClient, nsqProducer)
switchCtrl := controllers.NewSwitchController()
// 设置MQTT消息处理
mqttClient.SetMessageHandler(deviceCtrl.HandleMQTTMessage)
//引入路由
r := router.SetupRouter(mqttUserCtrl, deviceCtrl)
r := router.SetupRouter(mqttUserCtrl, deviceCtrl, switchCtrl)
r.Run(":9999")
}

View File

@@ -1,21 +1,50 @@
package models
import "sync"
// SwitchDevice 开关设备物模型
type SwitchDevice struct {
BaseDevice // 嵌入公共设备模板,继承所有公共属性
Status bool `json:"status"` // 开关状态true-false-
LastChanged string `json:"last_changed"` // 最后状态变更时间
PowerStatus bool `json:"powerStatus"` // 开关状态true=false=
UpdatedAt string `json:"updatedAt"` // 最后更时间
mu sync.Mutex
}
// SwitchStatus 开关状态模型
type SwitchStatus struct {
ID string `json:"id"` // 设备ID
Status bool `json:"status"` // 开关状态: true-开, false-关
// 全局开关设备实例
var GlobalSwitch = &SwitchDevice{
PowerStatus: false, // 初始状态为关闭
}
// SwitchRequest 设置开关状态请求参数
type SwitchRequest struct {
OrgID string `json:"org_id" binding:"required"`
DeviceID string `json:"device_id" binding:"required"`
Status bool `json:"status" binding:"required"`
// 提供方法操作私有锁,避免直接访问
func (s *SwitchDevice) Lock() {
s.mu.Lock()
}
func (s *SwitchDevice) Unlock() {
s.mu.Unlock()
}
// 简化的TSL模型定义
func GetTSL() map[string]interface{} {
return map[string]interface{}{
"schema": "https://iotx-tsl.oss-cn-shanghai.aliyuncs.com/schema.json",
"profile": map[string]string{
"productKey": "switch_basic",
"version": "1.0.0",
},
"properties": []map[string]interface{}{
{
"id": "powerStatus",
"name": "开关状态",
"mode": "rw",
"type": "boolean",
"defaultValue": false,
},
},
"services": []map[string]interface{}{
{"id": "turnOn", "name": "打开开关"},
{"id": "turnOff", "name": "关闭开关"},
{"id": "toggle", "name": "切换状态"},
},
}
}

View File

@@ -11,6 +11,7 @@ import (
func SetupRouter(
mqttuserCtrl *controllers.MqttuserController,
deviceCtrl *controllers.DeviceController,
switchCtrl *controllers.SwitchController,
) *gin.Engine {
r := gin.Default()
r.Use(gin.LoggerWithConfig(logger.LoggerToFile()))
@@ -27,12 +28,20 @@ func SetupRouter(
devices := v1.Group("/devices")
{
devices.GET("/:device_number/onoff", deviceCtrl.DeviceOnOff) // 设备上下线
devices.GET("/tdengine/test", deviceCtrl.TDengineTest) // TDengine测试
/*devices.GET("/:device_number/properties", controllers.DeviceController{}.DeviceOnOff) // 获取设备属性
devices.GET("/:device_number/properties/:property", controllers.DeviceController{}.DeviceOnOff) // 更新设备属性
devices.GET("/:device_number/command", controllers.DeviceController{}.DeviceOnOff) // 发送命令
devices.GET("/:device_number/events", controllers.DeviceController{}.DeviceOnOff) // 获取事件*/
devices.GET("/tdengine/test", deviceCtrl.TDengineTest) // TDengine测试
switchs := devices.Group("/switch")
{
//开关物模型测试开始
switchs.GET("/info", switchCtrl.GetDeviceInfo) // 获取设备完整信息(设备基础接口)
switchs.PUT("/info", switchCtrl.UpdateDeviceInfo) // 更新设备基础信息(设备基础接口)
switchs.GET("/tsl", switchCtrl.GetTSL) // 获取TSL模型定义(设备基础接口)
switchs.GET("/powerStatus", switchCtrl.GetSwitchProperty) // 读取开关状态(开关属性接口)
switchs.PUT("/powerStatus", switchCtrl.SetSwitchProperty) // 设置开关状态(开关属性接口)
switchs.POST("/turnOn", switchCtrl.TurnOn) // 打开开关(开关服务接口)
switchs.POST("/turnOff", switchCtrl.TurnOff) // 关闭开关(开关服务接口)
switchs.POST("/toggle", switchCtrl.Toggle) // 切换状态(开关服务接口)*/
//开关物模型测试结束
}
}
}
return r

View File

@@ -0,0 +1,17 @@
2025-08-11 18:43:21 - 127.0.0.1 "GET /swagger/index.html HTTP/1.1 200 3.9979ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" "
2025-08-11 18:43:21 - 127.0.0.1 "GET /swagger/swagger-ui.css HTTP/1.1 200 1.6015ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" "
2025-08-11 18:43:21 - 127.0.0.1 "GET /swagger/swagger-ui-standalone-preset.js HTTP/1.1 200 1.6221ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" "
2025-08-11 18:43:21 - 127.0.0.1 "GET /swagger/swagger-ui-bundle.js HTTP/1.1 200 9.7877ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" "
2025-08-11 18:43:22 - 127.0.0.1 "GET /swagger/doc.json HTTP/1.1 200 0s "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" "
2025-08-11 18:43:37 - 127.0.0.1 "GET /api/v1/devices/ttt/onoff HTTP/1.1 400 76.3752ms "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" "
2025-08-11 18:44:36 - 127.0.0.1 "GET /api/v1/devices/switch/info HTTP/1.1 200 0s "PostmanRuntime-ApipostRuntime/1.1.0" "
2025-08-11 19:04:00 - 127.0.0.1 "GET /api/v1/devices/switch/info HTTP/1.1 200 0s "PostmanRuntime-ApipostRuntime/1.1.0" "
2025-08-11 19:27:04 - 127.0.0.1 "GET /api/v1/devices/switch/tsl HTTP/1.1 200 517.2µs "PostmanRuntime-ApipostRuntime/1.1.0" "
2025-08-11 19:33:39 - 127.0.0.1 "GET /api/v1/devices/switch/powerStatus HTTP/1.1 200 517.6µs "PostmanRuntime-ApipostRuntime/1.1.0" "
2025-08-11 19:36:16 - 127.0.0.1 "GET /api/v1/devices/switch/powerStatus HTTP/1.1 200 0s "PostmanRuntime-ApipostRuntime/1.1.0" "
2025-08-11 19:38:48 - 127.0.0.1 "GET /api/v1/devices/switch/powerStatus HTTP/1.1 200 0s "PostmanRuntime-ApipostRuntime/1.1.0" "
2025-08-11 19:39:05 - 127.0.0.1 "PUT /api/v1/devices/switch/powerStatus HTTP/1.1 400 0s "PostmanRuntime-ApipostRuntime/1.1.0" "
2025-08-11 19:39:43 - 127.0.0.1 "PUT /api/v1/devices/switch/powerStatus HTTP/1.1 200 0s "PostmanRuntime-ApipostRuntime/1.1.0" "
2025-08-11 19:44:24 - 127.0.0.1 "PUT /api/v1/devices/switch/turnOn HTTP/1.1 404 0s "PostmanRuntime-ApipostRuntime/1.1.0" "
2025-08-11 19:44:40 - 127.0.0.1 "POST /api/v1/devices/switch/turnOn HTTP/1.1 200 0s "PostmanRuntime-ApipostRuntime/1.1.0" "
2025-08-11 19:44:46 - 127.0.0.1 "POST /api/v1/devices/switch/turnOff HTTP/1.1 200 0s "PostmanRuntime-ApipostRuntime/1.1.0" "

80
service/switchService.go Normal file
View File

@@ -0,0 +1,80 @@
package service
import (
"iot-mqtt-gin/models"
"time"
)
// 获取设备信息(包含公共属性和开关状态)
func GetDeviceInfo() models.SwitchDevice {
device := models.GlobalSwitch
device.Lock()
defer device.Unlock()
return *device
}
// 更新设备信息
func UpdateDeviceInfo(info models.BaseDevice) models.SwitchDevice {
device := models.GlobalSwitch
device.Lock()
defer device.Unlock()
// 更新基础信息
device.BaseDevice = info
if device.CreatedAt.IsZero() {
device.CreatedAt = time.Now()
}
device.UpdatedAt = time.Now().String()
device.LastActive = time.Now()
return *device
}
// 获取TSL模型
func GetTSL() map[string]interface{} {
return models.GetTSL()
}
// 获取开关状态
func GetSwitchStatus() bool {
device := models.GlobalSwitch
device.Lock()
defer device.Unlock()
return device.PowerStatus
}
// 设置开关状态
func SetSwitchStatus(status bool) bool {
device := models.GlobalSwitch
device.Lock()
defer device.Unlock()
// 更新最后活动时间
device.LastActive = time.Now()
device.UpdatedAt = time.Now().String()
device.PowerStatus = status
return true
}
// 打开开关
func TurnOn() bool {
return SetSwitchStatus(true)
}
// 关闭开关
func TurnOff() bool {
return SetSwitchStatus(false)
}
// 切换开关状态
func Toggle() bool {
device := models.GlobalSwitch
device.Lock()
current := device.PowerStatus
device.Unlock()
// 切换状态
newStatus := !current
return SetSwitchStatus(newStatus)
}