Просмотр исходного кода

Add 添加查询修改表计配置功能

YueYunyun 2 лет назад
Родитель
Сommit
5ec57461d3
31 измененных файлов с 713 добавлено и 260 удалено
  1. 51 0
      SERVER/IotAdmin/app/iot/apis/device.go
  2. 2 0
      SERVER/IotAdmin/app/iot/router/device.go
  3. 136 0
      SERVER/IotAdmin/app/iot/service/device.go
  4. 17 4
      SERVER/IotAdmin/app/iot/service/dto/device.go
  5. 2 1
      SERVER/IotAdmin/app/iot/service/dto/group.go
  6. 5 0
      SERVER/IotAdmin/config/sql/db.sql
  7. 49 0
      SERVER/IotAdmin/core/tools/utils/map.go
  8. 4 17
      SERVER/IotAdmin/iot/db/meter_calc.go
  9. 69 0
      SERVER/IotAdmin/iot/db/meter_device.go
  10. 0 59
      SERVER/IotAdmin/iot/db/meter_event.go
  11. 15 0
      SERVER/IotAdmin/iot/interface/meter.go
  12. 1 1
      SERVER/IotAdmin/iot/interface/meter_calc.go
  13. 9 0
      SERVER/IotAdmin/iot/interface/report.go
  14. 1 1
      SERVER/IotAdmin/iot/log/data.go
  15. 1 1
      SERVER/IotAdmin/iot/log/device.go
  16. 5 5
      SERVER/IotAdmin/iot/map/meter_calc.go
  17. 90 0
      SERVER/IotAdmin/iot/meter/meter.go
  18. 26 22
      SERVER/IotAdmin/iot/protocol/collect/el-adw300.go
  19. 37 28
      SERVER/IotAdmin/iot/protocol/collect/el-pmc350b.go
  20. 33 0
      SERVER/IotAdmin/iot/protocol/handler/handler.go
  21. 6 6
      SERVER/IotAdmin/iot/protocol/init.go
  22. 2 63
      SERVER/IotAdmin/iot/protocol/report/el-hj212.go
  23. 63 0
      SERVER/IotAdmin/iot/protocol/report/meter_calc.go
  24. 0 20
      SERVER/IotAdmin/iot/protocol/type.go
  25. 5 14
      SERVER/IotAdmin/iot/service/downService/collect.go
  26. 5 7
      SERVER/IotAdmin/iot/service/downService/report.go
  27. 5 1
      SERVER/IotAdmin/iot/struct/electric/adw300.go
  28. 5 1
      SERVER/IotAdmin/iot/struct/electric/pmc350B.go
  29. 11 0
      UI/IOTADMIN.VUE/src/api/iot/_device.ts
  30. 5 1
      UI/IOTADMIN.VUE/src/views/iot/device/_gateway.vue
  31. 53 8
      UI/IOTADMIN.VUE/src/views/iot/device/_meter.vue

+ 51 - 0
SERVER/IotAdmin/app/iot/apis/device.go

@@ -263,3 +263,54 @@ func (e IotDeviceApi) GetReportProtocols(c *gin.Context) {
 	s.GetReportProtocols(&list)
 	s.GetReportProtocols(&list)
 	e.OK(list, "查询成功")
 	e.OK(list, "查询成功")
 }
 }
+
+// GetDeviceConfig 获取表计硬件配置
+// @Summary 获取表计硬件配置
+// @Description 获取表计硬件配置
+// @Tags 设备管理
+// @Success 200 {object} response.Response{data=models.IotDevice} "{"code": 200, "data": [...]}"
+// @Router /api/iot-device/config/{id} [get]
+// @Security Bearer
+func (e IotDeviceApi) GetDeviceConfig(c *gin.Context) {
+	s := &service.IotDeviceService{}
+	req := dto.IotDeviceGetReq{}
+	err := e.MakeContext(c).MakeOrm().Bind(&req).MakeService(&s.Service).Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	data := make(map[string]interface{})
+	p := permission.GetPermissionFromContext(c)
+	err = s.GetDeviceConfig(&req, p, &data)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(data, "查询成功")
+}
+
+// SetDeviceConfig 设置表计硬件配置
+// @Summary 设置表计硬件配置
+// @Description 设置表计硬件配置
+// @Tags 设备管理
+// @Success 200 {object} response.Response{data=models.IotDevice} "{"code": 200, "message": "设置成功"}"
+// @Router /api/iot-device/config [put]
+// @Security Bearer
+func (e IotDeviceApi) SetDeviceConfig(c *gin.Context) {
+	s := &service.IotDeviceService{}
+	req := dto.IotDeviceSetConfigReq{}
+	err := e.MakeContext(c).MakeOrm().Bind(&req).MakeService(&s.Service).Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	p := permission.GetPermissionFromContext(c)
+	err = s.SetDeviceConfig(&req, p)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(nil, "设置成功")
+}

+ 2 - 0
SERVER/IotAdmin/app/iot/router/device.go

@@ -26,6 +26,8 @@ func registerIotDeviceRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMidd
 		r.POST("/refresh", api.Refresh)
 		r.POST("/refresh", api.Refresh)
 		r.GET("/device-protocols", api.GetDeviceProtocols)
 		r.GET("/device-protocols", api.GetDeviceProtocols)
 		r.GET("/report-protocols", api.GetReportProtocols)
 		r.GET("/report-protocols", api.GetReportProtocols)
+		r.GET("/config/:id", api.GetDeviceConfig)
+		r.PUT("/config", api.SetDeviceConfig)
 	}
 	}
 
 
 }
 }

+ 136 - 0
SERVER/IotAdmin/app/iot/service/device.go

@@ -5,9 +5,15 @@ import (
 	"IotAdmin/core/logger"
 	"IotAdmin/core/logger"
 	"IotAdmin/core/sdk"
 	"IotAdmin/core/sdk"
 	"IotAdmin/core/sdk/service"
 	"IotAdmin/core/sdk/service"
+	"IotAdmin/core/tools/utils"
 	"IotAdmin/iot/constant"
 	"IotAdmin/iot/constant"
+	iotInterface "IotAdmin/iot/interface"
+	iotMeter "IotAdmin/iot/meter"
 	iotProtocol "IotAdmin/iot/protocol"
 	iotProtocol "IotAdmin/iot/protocol"
+	iotProtocolHandler "IotAdmin/iot/protocol/handler"
+	"encoding/json"
 	"errors"
 	"errors"
+	"strings"
 
 
 	"gorm.io/gorm"
 	"gorm.io/gorm"
 
 
@@ -174,6 +180,71 @@ func (e *IotDeviceService) Refresh() error {
 	return err
 	return err
 }
 }
 
 
+func (e *IotDeviceService) GetDeviceConfig(d *dto.IotDeviceGetReq, p *permission.DataPermission, data *map[string]interface{}) error {
+	device := &models.IotDevice{}
+	err := e.Orm.Model(device).Scopes(
+		permission.Permission(device.TableName(), p),
+	).First(device, d.GetId()).Error
+	if err != nil {
+		e.Log.Errorf("IotDeviceService GetDeviceConfig error:%s \r\n", err)
+		return err
+	}
+	if device == nil {
+		return errors.New("设备不存在或没有设备权限")
+	}
+	if device.Type != constant.IotDeviceTypeMeter {
+		return errors.New("设备类型不支持此操作")
+	}
+	var cfg interface{}
+	sn := device.Sn
+	if strings.Contains(sn, "_") {
+		arr := strings.Split(sn, "_")
+		sn = arr[0]
+	}
+	ok := iotMeter.IsOnline(sn)
+	if ok {
+		cfg, err = iotMeter.GetMeterConfig(sn, device.Protocol, device.Address)
+		if err != nil {
+			return err
+		}
+	}
+	*data = mergeDeviceConfig(device.OtherConfig, cfg)
+	return nil
+}
+
+func (e *IotDeviceService) SetDeviceConfig(d *dto.IotDeviceSetConfigReq, p *permission.DataPermission) error {
+	device := &models.IotDevice{}
+	err := e.Orm.Model(device).Scopes(
+		permission.Permission(device.TableName(), p),
+	).First(device, d.Id).Error
+	if err != nil {
+		e.Log.Errorf("IotDeviceService GetDeviceConfig error:%s \r\n", err)
+		return err
+	}
+	if device == nil {
+		return errors.New("设备不存在或没有设备权限")
+	}
+	if device.Type != constant.IotDeviceTypeMeter {
+		return errors.New("设备类型不支持此操作")
+	}
+	if err = verifyDeviceConfig(device, d.Config); err != nil {
+		return err
+	}
+	sn := device.Sn
+	if strings.Contains(sn, "_") {
+		arr := strings.Split(sn, "_")
+		sn = arr[0]
+	}
+	ok := iotMeter.IsOnline(sn)
+	if ok {
+		if err = iotMeter.SetMeterConfig(sn, device.Protocol, device.Address, &d.Config); err != nil {
+			return err
+		}
+	}
+	err = e.Orm.Model(device).Update("other_config", d.Config).Error
+	return err
+}
+
 func updateDeviceMap(deviceId int, changeType int) error {
 func updateDeviceMap(deviceId int, changeType int) error {
 	q := sdk.Runtime.GetMemoryQueue("")
 	q := sdk.Runtime.GetMemoryQueue("")
 	mp := make(map[string]interface{})
 	mp := make(map[string]interface{})
@@ -191,3 +262,68 @@ func updateDeviceMap(deviceId int, changeType int) error {
 	}
 	}
 	return nil
 	return nil
 }
 }
+
+func verifyDeviceConfig(device *models.IotDevice, cfgStr string) (err error) {
+	var cfg interface{}
+	if cfgStr == "" {
+		return errors.New("配置不能为空")
+	}
+	ok := iotMeter.IsOnline(device.Sn)
+	if ok {
+		var handler iotInterface.MeterHandler
+		handler, err = iotProtocolHandler.GetMeterHandler(device.Protocol)
+		if err != nil {
+			return err
+		}
+		cfg, err = handler.VerifyConfig(&cfgStr)
+		if err != nil {
+			return err
+		}
+	} else {
+		err = json.Unmarshal([]byte(cfgStr), &cfg)
+		if err != nil {
+			return err
+		}
+	}
+	var mp map[string]interface{}
+	mp, err = utils.ToMap(cfg)
+	if err != nil {
+		return err
+	}
+	if strings.HasPrefix(device.Protocol, "El-") {
+		if mp["pvRef"] == "" || mp["pvRef"] == "0" || mp["pvRef"] == 0 || mp["pvRef"] == nil {
+			return errors.New("相基准电压[pvRef]不能为空")
+		}
+		if mp["lvRef"] == "" || mp["lvRef"] == "0" || mp["lvRef"] == 0 || mp["lvRef"] == nil {
+			return errors.New("线基准电压[lvRef]不能为空")
+		}
+	}
+
+	return err
+}
+
+func mergeDeviceConfig(first string, second interface{}) map[string]interface{} {
+	sMp := make(map[string]interface{})
+	if second != nil {
+		sMp, _ = utils.ToMap(second)
+	}
+	if first == "" {
+		return sMp
+	}
+	fMp := make(map[string]interface{})
+	if err := json.Unmarshal([]byte(first), &fMp); err != nil {
+		return sMp
+	}
+	return mergeConfigs(fMp, sMp)
+}
+
+func mergeConfigs(first map[string]interface{}, second map[string]interface{}) map[string]interface{} {
+	mp := make(map[string]interface{})
+	for k, v := range first {
+		mp[k] = v
+	}
+	for k, v := range second {
+		mp[k] = v
+	}
+	return mp
+}

+ 17 - 4
SERVER/IotAdmin/app/iot/service/dto/device.go

@@ -28,10 +28,18 @@ type IotDeviceGetPageReq struct {
 }
 }
 
 
 type IotDeviceOrder struct {
 type IotDeviceOrder struct {
-	GroupId string `form:"groupIdOrder"  search:"type:order;column:group_id;table:iot_device"`
-	Sn      string `form:"snOrder"  search:"type:order;column:sn;table:iot_device"`
-	Name    string `form:"nameOrder"  search:"type:order;column:name;table:iot_device"`
-	Type    int    `form:"typeOrder"  search:"type:order;column:type;table:iot_device"`
+	GroupId        string `form:"groupIdOrder"  search:"type:order;column:group_id;table:iot_device"`
+	Sn             string `form:"snOrder"  search:"type:order;column:sn;table:iot_device"`
+	Name           string `form:"nameOrder"  search:"type:order;column:name;table:iot_device"`
+	Protocol       string `form:"protocolOrder"  search:"type:order;column:protocol;table:iot_device"`
+	Type           int    `form:"typeOrder"  search:"type:order;column:type;table:iot_device"`
+	Mode           int    `form:"modeOrder"  search:"type:order;column:mode;table:iot_device"`
+	Address        int    `form:"addressOrder"  search:"type:order;column:address;table:iot_device"`
+	Status         int    `form:"statusOrder"  search:"type:order;column:status;table:iot_device"`
+	OnlineStatus   int    `form:"onlineStatusOrder"  search:"type:order;column:online_status;table:iot_device"`
+	TimeOnline     string `form:"timeOnlineOrder" search:"type:order;column:time_online;table:iot_device"`
+	TimeOffline    string `form:"timeOfflineOrder" search:"type:order;column:time_offline;table:iot_device"`
+	CreatedAtOrder string `form:"createdAtOrder" search:"type:order;column:created_at;table:iot_device"`
 }
 }
 
 
 func (m *IotDeviceGetPageReq) GetNeedSearch() interface{} {
 func (m *IotDeviceGetPageReq) GetNeedSearch() interface{} {
@@ -236,3 +244,8 @@ func (s *IotDeviceResp) Generate(model *models.IotDevice) {
 	s.CreateBy = model.CreateBy
 	s.CreateBy = model.CreateBy
 	s.CreatedAt = model.CreatedAt
 	s.CreatedAt = model.CreatedAt
 }
 }
+
+type IotDeviceSetConfigReq struct {
+	Id     int    `json:"id"`
+	Config string `json:"config"`
+}

+ 2 - 1
SERVER/IotAdmin/app/iot/service/dto/group.go

@@ -16,7 +16,8 @@ type IotGroupGetPageReq struct {
 }
 }
 
 
 type IotGroupOrder struct {
 type IotGroupOrder struct {
-	Name string `form:"nameOrder"  search:"type:order;column:name;table:iot_group"`
+	Name           string `form:"nameOrder"  search:"type:order;column:name;table:iot_group"`
+	CreatedAtOrder string `search:"type:order;column:created_at;table:iot_group" form:"createdAtOrder"`
 }
 }
 
 
 func (m *IotGroupGetPageReq) GetNeedSearch() interface{} {
 func (m *IotGroupGetPageReq) GetNeedSearch() interface{} {

+ 5 - 0
SERVER/IotAdmin/config/sql/db.sql

@@ -311,6 +311,7 @@ INSERT INTO sys_menu VALUES (215, 213, '新增网关', '#', 'plus-square', '/0/2
 INSERT INTO sys_menu VALUES (216, 213, '修改网关', '#', 'pencil-square', '/0/207/213/216', 'F', '', 'iot:device:edit', '', 'btn btn-light-success', 'handleUpdate@1', 3, 0, 0, 0, 1, 1, '2024-03-28 16:46:18.713', '2024-04-01 09:09:56.511', NULL);
 INSERT INTO sys_menu VALUES (216, 213, '修改网关', '#', 'pencil-square', '/0/207/213/216', 'F', '', 'iot:device:edit', '', 'btn btn-light-success', 'handleUpdate@1', 3, 0, 0, 0, 1, 1, '2024-03-28 16:46:18.713', '2024-04-01 09:09:56.511', NULL);
 INSERT INTO sys_menu VALUES (217, 213, '删除网关', '#', 'dash-square', '/0/207/213/217', 'F', '', 'iot:device:remove', '', 'btn btn-light-danger', 'handleDelete@0', 4, 0, 0, 0, 1, 1, '2024-03-28 16:46:19.055', '2024-04-01 09:09:56.511', NULL);
 INSERT INTO sys_menu VALUES (217, 213, '删除网关', '#', 'dash-square', '/0/207/213/217', 'F', '', 'iot:device:remove', '', 'btn btn-light-danger', 'handleDelete@0', 4, 0, 0, 0, 1, 1, '2024-03-28 16:46:19.055', '2024-04-01 09:09:56.511', NULL);
 INSERT INTO sys_menu VALUES (218, 213, '重新加载', '#', 'arrow-repeat', '/0/207/213/218', 'F', '', 'iot:device:refresh', '', 'btn btn-light-info', 'handleRefresh', 5, 0, 0, 0, 1, 1, '2024-03-28 16:46:19.055', '2024-04-01 09:09:56.511', NULL);
 INSERT INTO sys_menu VALUES (218, 213, '重新加载', '#', 'arrow-repeat', '/0/207/213/218', 'F', '', 'iot:device:refresh', '', 'btn btn-light-info', 'handleRefresh', 5, 0, 0, 0, 1, 1, '2024-03-28 16:46:19.055', '2024-04-01 09:09:56.511', NULL);
+INSERT INTO sys_menu VALUES (219, 213, '更新配置', '#', 'gear', '/0/207/213/219', 'F', '', 'iot:device:config', '', '', '', 6, 0, 0, 0, 0, 1, '2024-03-28 16:46:19.055', '2024-04-01 09:09:56.511', NULL);
 
 
 INSERT INTO sys_api VALUES (222, 'IotAdmin/app/iot/apis.(*IotGroupApi).GetPage-fm', '获取分组列表', '/api/iot-group', 'GET', 'BUS', 0, 0, '2024-03-28 16:46:11.552', '2024-04-01 09:09:56.520', NULL);
 INSERT INTO sys_api VALUES (222, 'IotAdmin/app/iot/apis.(*IotGroupApi).GetPage-fm', '获取分组列表', '/api/iot-group', 'GET', 'BUS', 0, 0, '2024-03-28 16:46:11.552', '2024-04-01 09:09:56.520', NULL);
 INSERT INTO sys_api VALUES (223, 'IotAdmin/app/iot/apis.(*IotGroupApi).Get-fm', '获取分组详情', '/api/iot-group/:id', 'GET', 'BUS', 0, 0, '2024-03-28 16:46:11.671', '2024-04-01 09:09:56.520', NULL);
 INSERT INTO sys_api VALUES (223, 'IotAdmin/app/iot/apis.(*IotGroupApi).Get-fm', '获取分组详情', '/api/iot-group/:id', 'GET', 'BUS', 0, 0, '2024-03-28 16:46:11.671', '2024-04-01 09:09:56.520', NULL);
@@ -325,6 +326,8 @@ INSERT INTO sys_api VALUES (231, 'IotAdmin/app/iot/apis.(*IotDeviceApi).Delete-f
 INSERT INTO sys_api VALUES (232, 'IotAdmin/app/iot/apis.(*IotDeviceApi).Refresh-fm', '重新加载设备', '/api/iot-device/refresh', 'POST', 'BUS', 0, 0, '2024-03-28 16:46:18.950', '2024-04-01 09:09:56.520', NULL);
 INSERT INTO sys_api VALUES (232, 'IotAdmin/app/iot/apis.(*IotDeviceApi).Refresh-fm', '重新加载设备', '/api/iot-device/refresh', 'POST', 'BUS', 0, 0, '2024-03-28 16:46:18.950', '2024-04-01 09:09:56.520', NULL);
 INSERT INTO sys_api VALUES (233, 'IotAdmin/app/iot/apis.(*IotDeviceApi).GetDeviceProtocols-fm', '获取表计协议列表', '/api/iot-device/device-protocol', 'GET', 'BUS', 0, 0, '2024-03-28 16:46:18.950', '2024-04-01 09:09:56.520', NULL);
 INSERT INTO sys_api VALUES (233, 'IotAdmin/app/iot/apis.(*IotDeviceApi).GetDeviceProtocols-fm', '获取表计协议列表', '/api/iot-device/device-protocol', 'GET', 'BUS', 0, 0, '2024-03-28 16:46:18.950', '2024-04-01 09:09:56.520', NULL);
 INSERT INTO sys_api VALUES (234, 'IotAdmin/app/iot/apis.(*IotDeviceApi).GetReportProtocols-fm', '获取上报协议列表', '/api/iot-device/report-protocol', 'GET', 'BUS', 0, 0, '2024-03-28 16:46:18.950', '2024-04-01 09:09:56.520', NULL);
 INSERT INTO sys_api VALUES (234, 'IotAdmin/app/iot/apis.(*IotDeviceApi).GetReportProtocols-fm', '获取上报协议列表', '/api/iot-device/report-protocol', 'GET', 'BUS', 0, 0, '2024-03-28 16:46:18.950', '2024-04-01 09:09:56.520', NULL);
+INSERT INTO sys_api VALUES (235, 'IotAdmin/app/iot/apis.(*IotDeviceApi).GetDeviceConfig-fm', '获取设备表计配置', '/api/iot-device/config/:id', 'GET', 'BUS', 0, 0, '2024-04-01 13:34:18.320', '2024-04-01 13:34:18.320', NULL);
+INSERT INTO sys_api VALUES (236, 'IotAdmin/app/iot/apis.(*IotDeviceApi).SetDeviceConfig-fm', '更新设备表计配置', '/api/iot-device/config', 'PUT', 'BUS', 0, 0, '2024-04-01 13:34:18.540', '2024-04-01 13:34:18.540', NULL);
 
 
 INSERT INTO sys_menu_api VALUES (208, 222);
 INSERT INTO sys_menu_api VALUES (208, 222);
 INSERT INTO sys_menu_api VALUES (209, 222);
 INSERT INTO sys_menu_api VALUES (209, 222);
@@ -345,6 +348,8 @@ INSERT INTO sys_menu_api VALUES (213, 233);
 INSERT INTO sys_menu_api VALUES (214, 233);
 INSERT INTO sys_menu_api VALUES (214, 233);
 INSERT INTO sys_menu_api VALUES (213, 234);
 INSERT INTO sys_menu_api VALUES (213, 234);
 INSERT INTO sys_menu_api VALUES (214, 234);
 INSERT INTO sys_menu_api VALUES (214, 234);
+INSERT INTO sys_menu_api VALUES (219, 235);
+INSERT INTO sys_menu_api VALUES (219, 236);
 
 
 
 
 
 

+ 49 - 0
SERVER/IotAdmin/core/tools/utils/map.go

@@ -0,0 +1,49 @@
+package utils
+
+import (
+	"fmt"
+	"reflect"
+)
+
+// ToMap 将数据转换为map。假设data是一个结构体。
+func ToMap(data interface{}) (map[string]interface{}, error) {
+	// 验证输入类型
+	kind := reflect.ValueOf(data).Kind()
+	if kind == reflect.Ptr {
+		if reflect.ValueOf(data).IsNil() {
+			return nil, fmt.Errorf("输入数据指针不能为空")
+		}
+		data = reflect.ValueOf(data).Elem().Interface()
+		kind = reflect.ValueOf(data).Kind()
+	}
+	if kind == reflect.Map {
+		mp := data.(map[string]interface{})
+		return mp, nil
+	}
+	if kind != reflect.Struct {
+		return nil, fmt.Errorf("输入数据类型必须是结构体或map")
+	}
+
+	mp := make(map[string]interface{})
+
+	// 使用反射遍历结构体字段并填充map
+	t := reflect.TypeOf(data)
+	v := reflect.ValueOf(data)
+
+	for i := 0; i < t.NumField(); i++ {
+		field := t.Field(i)
+		value := v.Field(i)
+
+		// 将字段名和字段值添加到map中
+		key := field.Tag.Get("json")
+		if key == "-" {
+			continue
+		}
+		if key == "" {
+			key = field.Name
+		}
+		mp[key] = value.Interface()
+	}
+
+	return mp, nil
+}

+ 4 - 17
SERVER/IotAdmin/iot/db/meter_calc.go

@@ -5,10 +5,8 @@ import (
 	"IotAdmin/core/logger"
 	"IotAdmin/core/logger"
 	"IotAdmin/core/sdk"
 	"IotAdmin/core/sdk"
 	"IotAdmin/core/storage"
 	"IotAdmin/core/storage"
-	iotInterface "IotAdmin/iot/interface"
 	iotMap "IotAdmin/iot/map"
 	iotMap "IotAdmin/iot/map"
-	iotProtocol "IotAdmin/iot/protocol"
-	"IotAdmin/iot/struct/electric"
+	iotReportProtocol "IotAdmin/iot/protocol/report"
 	"encoding/json"
 	"encoding/json"
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
@@ -63,22 +61,11 @@ func addMeterCalc(mc models.IotMeterCalc) (err error) {
 	if mc.Device == nil || mc.Device.Protocol == "" {
 	if mc.Device == nil || mc.Device.Protocol == "" {
 		return errors.New("device is nil")
 		return errors.New("device is nil")
 	}
 	}
-	var meterCalc iotInterface.MeterCalc
-	switch mc.Device.Protocol {
-	case iotProtocol.MeterAdw300:
-		meterCalc, err = electric.NewMeterADW300(mc.Id, mc.Time, mc.Data, mc.Device.OtherConfig)
-		if err != nil {
-			return
-		}
-	case iotProtocol.MeterPmc350b:
-		meterCalc, err = electric.NewMeterPMC350B(mc.Id, mc.Time, mc.Data, mc.Device.OtherConfig)
-		if err != nil {
-			return
-		}
-	default:
+	meterCalcHandler, err := iotReportProtocol.GetMeterCalcHandler(mc.Device.Protocol, mc.Id, mc.Time, mc.Data, mc.Device.OtherConfig)
+	if err != nil {
 		return
 		return
 	}
 	}
-	iotMap.MapMeterCalc.Add(mc.Id, &meterCalc)
+	iotMap.MapMeterCalc.Add(mc.Id, &meterCalcHandler)
 	return
 	return
 
 
 }
 }

+ 69 - 0
SERVER/IotAdmin/iot/db/meter_device.go

@@ -0,0 +1,69 @@
+package iotDb
+
+import (
+	"IotAdmin/app/iot/models"
+	"IotAdmin/core/logger"
+	"IotAdmin/iot/constant"
+	iotLog "IotAdmin/iot/log"
+	iotMap "IotAdmin/iot/map"
+	iotStruct "IotAdmin/iot/struct"
+	"errors"
+
+	"gorm.io/gorm"
+)
+
+// LoadDtuDeviceMap 加载DTU设备
+func LoadDtuDeviceMap() error {
+	iotMap.MapDtuDevice.Clean()
+	deviceArr := make([]models.IotDevice, 0)
+	for _, db := range dbMap {
+		gatewayArr := make([]models.IotDevice, 0)
+		d := &models.IotDevice{}
+		err := db.Model(d).Select("id,sn,name,type,mode,status,cycle").Where("type = ? AND status = ?", constant.IotDeviceTypeGateway, constant.IotDeviceOnline).Find(&gatewayArr).Error
+		if err != nil {
+			continue
+		}
+		deviceArr = append(deviceArr, gatewayArr...)
+		err = loadDtuDeviceMap(db, &deviceArr)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func loadDtuDeviceMap(db *gorm.DB, arr *[]models.IotDevice) error {
+	if len(*arr) == 0 {
+		return nil
+	}
+	for _, v := range *arr {
+		err := addDtuDevice(db, v)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func addDtuDevice(db *gorm.DB, device models.IotDevice) error {
+
+	if device.Type != constant.IotDeviceTypeGateway {
+		return errors.New("type is not gateway")
+	}
+	children := make([]models.IotDevice, 0)
+	db.Model(&models.IotDevice{}).Select("id,sn,status,dsn,protocol,address,bm_yz,other_config").Where("parent_id = ? AND status = ?", device.Id, constant.IotDeviceOnline).Find(&children)
+	if len(children) == 0 {
+		return nil
+	}
+	cfg := device.ToDtuConfig(&children)
+	var dtu = &iotStruct.DtuDevice{
+		SN:     device.Sn,
+		Name:   device.Name,
+		Config: cfg,
+		Logger: logger.NewHelper(iotLog.SetupDeviceLogger(device.Sn)),
+	}
+	logger.Infof("加载DTU设备: %s %v", dtu.SN, dtu.Config)
+	dtu.Logger.Infof("加载DTU设备 %v", *dtu.Config)
+	iotMap.MapDtuDevice.Add(device.Sn, dtu)
+	return nil
+}

+ 0 - 59
SERVER/IotAdmin/iot/db/device.go → SERVER/IotAdmin/iot/db/meter_event.go

@@ -6,72 +6,13 @@ import (
 	"IotAdmin/core/sdk"
 	"IotAdmin/core/sdk"
 	"IotAdmin/core/storage"
 	"IotAdmin/core/storage"
 	"IotAdmin/iot/constant"
 	"IotAdmin/iot/constant"
-	iotLog "IotAdmin/iot/log"
 	iotMap "IotAdmin/iot/map"
 	iotMap "IotAdmin/iot/map"
 	iotStruct "IotAdmin/iot/struct"
 	iotStruct "IotAdmin/iot/struct"
 	"encoding/json"
 	"encoding/json"
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
-
-	"gorm.io/gorm"
 )
 )
 
 
-// LoadDtuDeviceMap 加载DTU设备
-func LoadDtuDeviceMap() error {
-	iotMap.MapDtuDevice.Clean()
-	deviceArr := make([]models.IotDevice, 0)
-	for _, db := range dbMap {
-		gatewayArr := make([]models.IotDevice, 0)
-		d := &models.IotDevice{}
-		err := db.Model(d).Select("id,sn,name,type,mode,status,cycle").Where("type = ? AND status = ?", constant.IotDeviceTypeGateway, constant.IotDeviceOnline).Find(&gatewayArr).Error
-		if err != nil {
-			continue
-		}
-		deviceArr = append(deviceArr, gatewayArr...)
-		err = loadDtuDeviceMap(db, &deviceArr)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func loadDtuDeviceMap(db *gorm.DB, arr *[]models.IotDevice) error {
-	if len(*arr) == 0 {
-		return nil
-	}
-	for _, v := range *arr {
-		err := addDtuDevice(db, v)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func addDtuDevice(db *gorm.DB, device models.IotDevice) error {
-
-	if device.Type != constant.IotDeviceTypeGateway {
-		return errors.New("type is not gateway")
-	}
-	children := make([]models.IotDevice, 0)
-	db.Model(&models.IotDevice{}).Select("id,sn,status,dsn,protocol,address,bm_yz,other_config").Where("parent_id = ? AND status = ?", device.Id, constant.IotDeviceOnline).Find(&children)
-	if len(children) == 0 {
-		return nil
-	}
-	cfg := device.ToDtuConfig(&children)
-	var dtu = &iotStruct.DtuDevice{
-		SN:     device.Sn,
-		Name:   device.Name,
-		Config: cfg,
-		Logger: logger.NewHelper(iotLog.SetupDeviceLogger(device.Sn)),
-	}
-	logger.Infof("加载DTU设备: %s %v", dtu.SN, dtu.Config)
-	dtu.Logger.Infof("加载DTU设备 %v", *dtu.Config)
-	iotMap.MapDtuDevice.Add(device.Sn, dtu)
-	return nil
-}
-
 func DtuChangeStatus(message storage.Message) (err error) {
 func DtuChangeStatus(message storage.Message) (err error) {
 	db := sdk.Runtime.GetDbByKey(message.GetPrefix())
 	db := sdk.Runtime.GetDbByKey(message.GetPrefix())
 	if db == nil {
 	if db == nil {

+ 15 - 0
SERVER/IotAdmin/iot/interface/meter.go

@@ -0,0 +1,15 @@
+package iotInterface
+
+import (
+	iotRtuService "IotAdmin/iot/service/rtuService"
+	iotStruct "IotAdmin/iot/struct"
+)
+
+// MeterHandler 电表处理接口
+type MeterHandler interface {
+	Collect(w iotRtuService.RtuNetPgr, data *iotStruct.CollectData) error
+	SetAddress(w iotRtuService.RtuNetPgr, addr int) error
+	GetConfig(w iotRtuService.RtuNetPgr) (*map[string]interface{}, error)
+	VerifyConfig(data *string) (interface{}, error)
+	SetConfig(w iotRtuService.RtuNetPgr, cfg *string) error
+}

+ 1 - 1
SERVER/IotAdmin/iot/interface/meter_calc.go

@@ -1,6 +1,6 @@
 package iotInterface
 package iotInterface
 
 
-type MeterCalc interface {
+type MeterCalcHandler interface {
 	GetMeterNo() string
 	GetMeterNo() string
 	GetUpdateTime() int
 	GetUpdateTime() int
 	GetMeterData() interface{}
 	GetMeterData() interface{}

+ 9 - 0
SERVER/IotAdmin/iot/interface/report.go

@@ -0,0 +1,9 @@
+package iotInterface
+
+import iotStruct "IotAdmin/iot/struct"
+
+// ReportHandler 上报处理接口
+type ReportHandler interface {
+	Adapter(data *iotStruct.CollectData)
+	Report(data *iotStruct.CollectData, config *iotStruct.ReportConfig) *string
+}

+ 1 - 1
SERVER/IotAdmin/iot/log/data.go

@@ -54,7 +54,7 @@ func getWrite(data *iotStruct.CollectData) *writer.FileWriter {
 			writer.WithPath(path),
 			writer.WithPath(path),
 			// 不切割文件
 			// 不切割文件
 			writer.WithCap(0),
 			writer.WithCap(0),
-			writer.WithSuffix(".data"),
+			writer.WithSuffix("data"),
 		)
 		)
 		if err != nil {
 		if err != nil {
 			log.Printf("Report Log setup error: %s \r\n", err.Error())
 			log.Printf("Report Log setup error: %s \r\n", err.Error())

+ 1 - 1
SERVER/IotAdmin/iot/log/device.go

@@ -18,7 +18,7 @@ func SetupDeviceLogger(sn string) logger.Logger {
 	output, err := writer.NewFileWriter(
 	output, err := writer.NewFileWriter(
 		writer.WithPath(path),
 		writer.WithPath(path),
 		writer.WithCap(logCap<<10),
 		writer.WithCap(logCap<<10),
-		writer.WithSuffix(".log"),
+		writer.WithSuffix("log"),
 	)
 	)
 	if err != nil {
 	if err != nil {
 		log.Printf("device logger setup error: %s \r\n", err.Error())
 		log.Printf("device logger setup error: %s \r\n", err.Error())

+ 5 - 5
SERVER/IotAdmin/iot/map/meter_calc.go

@@ -17,7 +17,7 @@ func NewMeterCalcMap() *MeterCalcMap {
 	return cm
 	return cm
 }
 }
 
 
-func (cm *MeterCalcMap) Add(key string, val *iotInterface.MeterCalc) {
+func (cm *MeterCalcMap) Add(key string, val *iotInterface.MeterCalcHandler) {
 	cm.Map.Store(key, val)
 	cm.Map.Store(key, val)
 }
 }
 
 
@@ -25,11 +25,11 @@ func (cm *MeterCalcMap) Remove(key string) {
 	cm.Map.Delete(key)
 	cm.Map.Delete(key)
 }
 }
 
 
-func (cm *MeterCalcMap) Get(key string) (*iotInterface.MeterCalc, bool) {
-	var res *iotInterface.MeterCalc
+func (cm *MeterCalcMap) Get(key string) (*iotInterface.MeterCalcHandler, bool) {
+	var res *iotInterface.MeterCalcHandler
 	x, ok := cm.Map.Load(key)
 	x, ok := cm.Map.Load(key)
 	if ok {
 	if ok {
-		res = x.(*iotInterface.MeterCalc)
+		res = x.(*iotInterface.MeterCalcHandler)
 		return res, true
 		return res, true
 	}
 	}
 	return res, false
 	return res, false
@@ -46,7 +46,7 @@ func (cm *MeterCalcMap) AlterKey(before, after string) bool {
 		if _, ok = cm.Map.Load(after); ok {
 		if _, ok = cm.Map.Load(after); ok {
 			return false
 			return false
 		}
 		}
-		val := v.(*iotInterface.MeterCalc)
+		val := v.(*iotInterface.MeterCalcHandler)
 		cm.Map.Store(after, val)
 		cm.Map.Store(after, val)
 		cm.Map.Delete(before)
 		cm.Map.Delete(before)
 		return true
 		return true

+ 90 - 0
SERVER/IotAdmin/iot/meter/meter.go

@@ -0,0 +1,90 @@
+package iotMeter
+
+import (
+	"IotAdmin/core/tools/utils"
+	iotInterface "IotAdmin/iot/interface"
+	iotMap "IotAdmin/iot/map"
+	iotProtocol "IotAdmin/iot/protocol"
+	iotProtocolHandler "IotAdmin/iot/protocol/handler"
+	iotRtuService "IotAdmin/iot/service/rtuService"
+	iotStruct "IotAdmin/iot/struct"
+	"errors"
+	"fmt"
+)
+
+func SetMeterAddress(sn, protocol string, addr, newAddr int) error {
+	client, handler, rtu, err := getClientHandle(sn, protocol, addr)
+	if err != nil {
+		return err
+	}
+	client.MLock.Lock()
+	defer client.MLock.Unlock()
+	if newAddr == addr {
+		return errors.New("新地址不能与旧地址相同")
+	}
+	if newAddr < 1 || newAddr > 255 {
+		return errors.New("新地址范围1-255")
+	}
+	if err = handler.SetAddress(rtu, newAddr); err != nil {
+		return fmt.Errorf("表计地址设置失败: %s", err.Error())
+	}
+	return nil
+}
+
+func SetMeterConfig(sn, protocol string, addr int, data *string) error {
+	client, handler, rtu, err := getClientHandle(sn, protocol, addr)
+	if err != nil {
+		return err
+	}
+	client.MLock.Lock()
+	defer client.MLock.Unlock()
+	if err = handler.SetConfig(rtu, data); err != nil {
+		return fmt.Errorf("表计配置设置失败: %s", err.Error())
+	}
+	return nil
+}
+
+func GetMeterConfig(sn, protocol string, addr int) (data interface{}, err error) {
+	client, handler, rtu, err := getClientHandle(sn, protocol, addr)
+	if err != nil {
+		return
+	}
+	client.MLock.Lock()
+	defer client.MLock.Unlock()
+	if data, err = handler.GetConfig(rtu); err != nil {
+		err = fmt.Errorf("表计配置获取失败: %s", err.Error())
+	}
+	return
+}
+
+func getClientHandle(sn, protocol string, addr int) (client *iotStruct.DtuClient, handle iotInterface.MeterHandler, rtu iotRtuService.RtuNetPgr, err error) {
+	if !iotProtocol.VerifyMeterProtocol(protocol) {
+		err = errors.New("表计协议不支持")
+		return
+	}
+	if addr < 1 || addr > 255 {
+		err = errors.New("地址范围1-255")
+		return
+	}
+	_, ok := iotMap.MapDtuDevice.Get(sn)
+	if !ok {
+		err = errors.New("表计不存在")
+		return
+	}
+	client, ok = iotMap.MapDtuClient.Get(sn)
+	if !ok {
+		err = errors.New("表计正在通信或已离线,请稍后再试!")
+		return
+	}
+	rtu = iotRtuService.NewRtuNetPgr(utils.IntoByte(addr))
+	rtu.SetClientState(client)
+	rtu.SetSerialNumber(sn)
+
+	handle, err = iotProtocolHandler.GetMeterHandler(protocol)
+	return
+}
+
+func IsOnline(sn string) bool {
+	_, ok := iotMap.MapDtuClient.Get(sn)
+	return ok
+}

+ 26 - 22
SERVER/IotAdmin/iot/protocol/electric/meter_adw300.go → SERVER/IotAdmin/iot/protocol/collect/el-adw300.go

@@ -1,8 +1,8 @@
-package iotElProtocol
+package iotCollectProtocol
 
 
 import (
 import (
 	"IotAdmin/core/tools/utils"
 	"IotAdmin/core/tools/utils"
-	iotProtocol "IotAdmin/iot/protocol"
+	iotInterface "IotAdmin/iot/interface"
 	iotService "IotAdmin/iot/service/rtuService"
 	iotService "IotAdmin/iot/service/rtuService"
 	iotStruct "IotAdmin/iot/struct"
 	iotStruct "IotAdmin/iot/struct"
 	"IotAdmin/iot/struct/electric"
 	"IotAdmin/iot/struct/electric"
@@ -15,7 +15,7 @@ import (
 type adw300Meter struct {
 type adw300Meter struct {
 }
 }
 
 
-func NewAdw300MeterHandler() iotProtocol.MeterHandler {
+func NewAdw300MeterHandler() iotInterface.MeterHandler {
 	return &adw300Meter{}
 	return &adw300Meter{}
 }
 }
 
 
@@ -55,42 +55,46 @@ func (m *adw300Meter) SetAddress(w iotService.RtuNetPgr, addr int) (err error) {
 	return
 	return
 }
 }
 
 
-// GetRatio 查询电表变比
-func (m *adw300Meter) GetRatio(w iotService.RtuNetPgr) (string, error) {
+// GetConfig 查询电表变比
+func (m *adw300Meter) GetConfig(w iotService.RtuNetPgr) (*map[string]interface{}, error) {
 	if adu, err := w.GetHoldingRegs(0x0E, 2); err != nil {
 	if adu, err := w.GetHoldingRegs(0x0E, 2); err != nil {
 		err = fmt.Errorf("ADW300 查询电表变比失败  ERROR:%v", err)
 		err = fmt.Errorf("ADW300 查询电表变比失败  ERROR:%v", err)
-		return "", err
+		return nil, err
 	} else {
 	} else {
-		ratio := &electric.MeterADW300Other{}
+		cfg := &electric.MeterADW300Other{}
 		index := 0
 		index := 0
 		m := int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
 		m := int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-		ratio.PT = int(m)
+		cfg.PT = int(m)
 		index += 2
 		index += 2
 		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
 		m = int16(uint16(adu[index])<<8 | uint16(adu[index+1]))
-		ratio.CT = int(m)
-		str, err := json.Marshal(ratio)
-		if err != nil {
-			err = fmt.Errorf("ADW300 查询电表变比失败  ERROR:%v", err)
-			return "", err
-		}
-		return string(str), nil
+		cfg.CT = int(m)
+		mp, err := utils.ToMap(cfg)
+		return &mp, err
+	}
+}
+func (m *adw300Meter) VerifyConfig(data *string) (interface{}, error) {
+	cfg := &electric.MeterADW300Other{}
+	if err := json.Unmarshal([]byte(*data), cfg); err != nil {
+		err = fmt.Errorf("PMC-350B 设置电表变比失败,变比数据解析失败  ERROR:%v", err)
+		return nil, err
 	}
 	}
+	return cfg, nil
 }
 }
 
 
-// SetRatio 设置电表变比
-func (m *adw300Meter) SetRatio(w iotService.RtuNetPgr, data string) error {
-	ratio := &electric.MeterADW300Other{}
-	if err := json.Unmarshal([]byte(data), ratio); err != nil {
-		err = fmt.Errorf("ADW300 设置电表变比失败,变比数据解析失败  ERROR:%v", err)
+// SetConfig 设置电表变比
+func (m *adw300Meter) SetConfig(w iotService.RtuNetPgr, data *string) error {
+	c, err := m.VerifyConfig(data)
+	if err != nil {
 		return err
 		return err
 	}
 	}
+	cfg := c.(*electric.MeterADW300Other)
 	var buf []byte
 	var buf []byte
 	{
 	{
-		k := utils.HfWord2byte(ratio.PT)
+		k := utils.HfWord2byte(cfg.PT)
 		buf = append(buf, k...)
 		buf = append(buf, k...)
 	}
 	}
 	{
 	{
-		k := utils.HfWord2byte(ratio.CT)
+		k := utils.HfWord2byte(cfg.CT)
 		buf = append(buf, k...)
 		buf = append(buf, k...)
 	}
 	}
 	if _, err := w.SetHoldingRegs(0x0E, 2, buf); err != nil {
 	if _, err := w.SetHoldingRegs(0x0E, 2, buf); err != nil {

+ 37 - 28
SERVER/IotAdmin/iot/protocol/electric/meter_pmc350b.go → SERVER/IotAdmin/iot/protocol/collect/el-pmc350b.go

@@ -1,8 +1,8 @@
-package iotElProtocol
+package iotCollectProtocol
 
 
 import (
 import (
 	"IotAdmin/core/tools/utils"
 	"IotAdmin/core/tools/utils"
-	iotProtocol "IotAdmin/iot/protocol"
+	iotInterface "IotAdmin/iot/interface"
 	iotService "IotAdmin/iot/service/rtuService"
 	iotService "IotAdmin/iot/service/rtuService"
 	iotStruct "IotAdmin/iot/struct"
 	iotStruct "IotAdmin/iot/struct"
 	"IotAdmin/iot/struct/electric"
 	"IotAdmin/iot/struct/electric"
@@ -33,12 +33,11 @@ var (
 	}
 	}
 )
 )
 
 
-func NewPmc350bMeterHandler() iotProtocol.MeterHandler {
+func NewPmc350bMeterHandler() iotInterface.MeterHandler {
 	return &pmc350bMeter{}
 	return &pmc350bMeter{}
 }
 }
 
 
 func (m *pmc350bMeter) Collect(w iotService.RtuNetPgr, colData *iotStruct.CollectData) error {
 func (m *pmc350bMeter) Collect(w iotService.RtuNetPgr, colData *iotStruct.CollectData) error {
-
 	for _, v := range pmc350bCollects {
 	for _, v := range pmc350bCollects {
 		if adu, err := w.GetHoldingRegs(v.Origin, v.Amount); err != nil {
 		if adu, err := w.GetHoldingRegs(v.Origin, v.Amount); err != nil {
 			colData.Logger.Errorf("PMC-350B 采集失败[%s]  ERROR:%v", runtime.FuncForPC(reflect.ValueOf(v.Method).Pointer()).Name(), err)
 			colData.Logger.Errorf("PMC-350B 采集失败[%s]  ERROR:%v", runtime.FuncForPC(reflect.ValueOf(v.Method).Pointer()).Name(), err)
@@ -62,67 +61,77 @@ func (m *pmc350bMeter) SetAddress(w iotService.RtuNetPgr, addr int) (err error)
 	return
 	return
 }
 }
 
 
-// GetRatio 查询电表变比
-func (m *pmc350bMeter) GetRatio(w iotService.RtuNetPgr) (string, error) {
+// GetConfig 查询电表变比
+func (m *pmc350bMeter) GetConfig(w iotService.RtuNetPgr) (*map[string]interface{}, error) {
 	if adu, err := w.GetHoldingRegs(6000, 10); err != nil {
 	if adu, err := w.GetHoldingRegs(6000, 10); err != nil {
 		err = fmt.Errorf("PMC-350B 查询电表变比失败  ERROR:%v", err)
 		err = fmt.Errorf("PMC-350B 查询电表变比失败  ERROR:%v", err)
-		return "", err
+		return nil, err
 	} else {
 	} else {
 		var (
 		var (
 			index = 0
 			index = 0
 			n     int32
 			n     int32
 		)
 		)
-		s := &electric.MeterPMC350BOther{}
+		cfg := &electric.MeterPMC350BOther{}
 		n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
 		n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-		s.PrimaryVolt = int(n)
+		cfg.PrimaryVolt = int(n)
 		index += 4
 		index += 4
 		n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
 		n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-		s.SecondVolt = int(n)
+		cfg.SecondVolt = int(n)
 		index += 4
 		index += 4
 		n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
 		n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-		s.PrimaryCurrent = int(n)
+		cfg.PrimaryCurrent = int(n)
 		index += 4
 		index += 4
 		n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
 		n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-		s.SecondCurrent = int(n)
+		cfg.SecondCurrent = int(n)
 		index += 4
 		index += 4
 		n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
 		n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
-		s.CurrentType = int(n)
+		cfg.CurrentType = int(n)
 		index += 4
 		index += 4
-		str, err := json.Marshal(s)
-		if err != nil {
-			err = fmt.Errorf("PMC-350B 变比序列化失败  ERROR:%v", err)
-			return "", err
-		}
-		return string(str), nil
+		//str, err := json.Marshal(cfg)
+		//if err != nil {
+		//	err = fmt.Errorf("PMC-350B 变比序列化失败  ERROR:%v", err)
+		//	return "", err
+		//}
+		mp, err := utils.ToMap(cfg)
+		return &mp, err
 	}
 	}
 }
 }
 
 
-// SetRatio 设置电表变比
-func (m *pmc350bMeter) SetRatio(w iotService.RtuNetPgr, data string) error {
-	ratio := &electric.MeterPMC350BOther{}
-	if err := json.Unmarshal([]byte(data), ratio); err != nil {
+func (m *pmc350bMeter) VerifyConfig(data *string) (interface{}, error) {
+	cfg := &electric.MeterPMC350BOther{}
+	if err := json.Unmarshal([]byte(*data), cfg); err != nil {
 		err = fmt.Errorf("PMC-350B 设置电表变比失败,变比数据解析失败  ERROR:%v", err)
 		err = fmt.Errorf("PMC-350B 设置电表变比失败,变比数据解析失败  ERROR:%v", err)
+		return nil, err
+	}
+	return cfg, nil
+}
+
+// SetConfig 设置电表变比
+func (m *pmc350bMeter) SetConfig(w iotService.RtuNetPgr, data *string) error {
+	c, err := m.VerifyConfig(data)
+	if err != nil {
 		return err
 		return err
 	}
 	}
+	cfg := c.(*electric.MeterPMC350BOther)
 	var buf []byte
 	var buf []byte
 	{
 	{
-		k := utils.Word2byte(ratio.PrimaryVolt)
+		k := utils.Word2byte(cfg.PrimaryVolt)
 		buf = append(buf, k...)
 		buf = append(buf, k...)
 	}
 	}
 	{
 	{
-		k := utils.Word2byte(ratio.SecondVolt)
+		k := utils.Word2byte(cfg.SecondVolt)
 		buf = append(buf, k...)
 		buf = append(buf, k...)
 	}
 	}
 	{
 	{
-		k := utils.Word2byte(ratio.PrimaryCurrent)
+		k := utils.Word2byte(cfg.PrimaryCurrent)
 		buf = append(buf, k...)
 		buf = append(buf, k...)
 	}
 	}
 	{
 	{
-		k := utils.Word2byte(ratio.SecondCurrent)
+		k := utils.Word2byte(cfg.SecondCurrent)
 		buf = append(buf, k...)
 		buf = append(buf, k...)
 	}
 	}
 	{
 	{
-		k := utils.Word2byte(ratio.CurrentType)
+		k := utils.Word2byte(cfg.CurrentType)
 		buf = append(buf, k...)
 		buf = append(buf, k...)
 	}
 	}
 	if _, err := w.SetHoldingRegs(6000, 10, buf); err != nil {
 	if _, err := w.SetHoldingRegs(6000, 10, buf); err != nil {

+ 33 - 0
SERVER/IotAdmin/iot/protocol/handler/handler.go

@@ -0,0 +1,33 @@
+package iotProtocolHandler
+
+import (
+	iotInterface "IotAdmin/iot/interface"
+	iotProtocol "IotAdmin/iot/protocol"
+	iotElProtocol "IotAdmin/iot/protocol/collect"
+	iotReportProtocol "IotAdmin/iot/protocol/report"
+	"errors"
+)
+
+// GetMeterHandler 获取表计协议处理器
+func GetMeterHandler(protocol string) (handler iotInterface.MeterHandler, err error) {
+	switch protocol {
+	case iotProtocol.MeterElAdw300:
+		handler = iotElProtocol.NewAdw300MeterHandler()
+	case iotProtocol.MeterElPmc350b:
+		handler = iotElProtocol.NewPmc350bMeterHandler()
+	default:
+		err = errors.New("not support protocol")
+	}
+	return
+}
+
+// GetReportHandler 获取上报协议处理器
+func GetReportHandler(protocol string) (handler iotInterface.ReportHandler, err error) {
+	switch protocol {
+	case iotProtocol.PlatElHj212:
+		handler = iotReportProtocol.NewElHj212ReportHandler()
+	default:
+		err = errors.New("not support protocol")
+	}
+	return
+}

+ 6 - 6
SERVER/IotAdmin/iot/protocol/init.go

@@ -3,10 +3,10 @@ package iotProtocol
 import "IotAdmin/core/logger"
 import "IotAdmin/core/logger"
 
 
 const (
 const (
-	// MeterAdw300  电表ADW300协议
-	MeterAdw300 = "ADW300"
-	// MeterPmc350b 电表PMC350B协议
-	MeterPmc350b = "PMC350B"
+	// MeterElAdw300  电表ADW300协议
+	MeterElAdw300 = "EL-ADW300"
+	// MeterElPmc350b 电表PMC350B协议
+	MeterElPmc350b = "EL-PMC350B"
 )
 )
 const (
 const (
 	// PlatElHj212 平台电表HJ212协议
 	// PlatElHj212 平台电表HJ212协议
@@ -19,8 +19,8 @@ var (
 )
 )
 
 
 func init() {
 func init() {
-	meterProtocol = append(meterProtocol, MeterAdw300)
-	meterProtocol = append(meterProtocol, MeterPmc350b)
+	meterProtocol = append(meterProtocol, MeterElAdw300)
+	meterProtocol = append(meterProtocol, MeterElPmc350b)
 	platformProtocol = append(platformProtocol, PlatElHj212)
 	platformProtocol = append(platformProtocol, PlatElHj212)
 }
 }
 
 

+ 2 - 63
SERVER/IotAdmin/iot/protocol/electric/report_el-hj212.go → SERVER/IotAdmin/iot/protocol/report/el-hj212.go

@@ -1,17 +1,11 @@
-package iotElProtocol
+package iotReportProtocol
 
 
 import (
 import (
-	"IotAdmin/common/global"
-	"IotAdmin/core/logger"
-	"IotAdmin/core/sdk"
 	"IotAdmin/core/tools/utils"
 	"IotAdmin/core/tools/utils"
 	iotInterface "IotAdmin/iot/interface"
 	iotInterface "IotAdmin/iot/interface"
-	iotMap "IotAdmin/iot/map"
-	iotProtocol "IotAdmin/iot/protocol"
 	iotReportService "IotAdmin/iot/service/reportService"
 	iotReportService "IotAdmin/iot/service/reportService"
 	iotStruct "IotAdmin/iot/struct"
 	iotStruct "IotAdmin/iot/struct"
 	"IotAdmin/iot/struct/electric"
 	"IotAdmin/iot/struct/electric"
-	"encoding/json"
 	"fmt"
 	"fmt"
 	"strconv"
 	"strconv"
 	"time"
 	"time"
@@ -20,7 +14,7 @@ import (
 type elHj212 struct {
 type elHj212 struct {
 }
 }
 
 
-func NewElHj212ReportHandler() iotProtocol.ReportHandler {
+func NewElHj212ReportHandler() iotInterface.ReportHandler {
 	return &elHj212{}
 	return &elHj212{}
 }
 }
 
 
@@ -60,61 +54,6 @@ func (*elHj212) Report(data *iotStruct.CollectData, config *iotStruct.ReportConf
 	return
 	return
 }
 }
 
 
-func getMeterElectricCalc(cfg *iotStruct.SlaveConfig) (calc iotInterface.MeterCalc, tms int, err error) {
-	now := time.Now()
-	today, _ := strconv.Atoi(now.Format("20060102"))
-	tms = today
-	if x, ok := iotMap.MapMeterCalc.Get(cfg.No); ok {
-		calc = *x
-	} else {
-		calc = nil
-	}
-
-	if calc == nil {
-		switch cfg.Protocol {
-		case iotProtocol.MeterAdw300:
-			calc, err = electric.NewMeterADW300(cfg.No, today, "", cfg.OtherConfig)
-			if err != nil {
-				err = fmt.Errorf("创建电表[%s]-[%s] 计算参数失败: %s", cfg.No, cfg.Protocol, err.Error())
-				return
-			}
-		case iotProtocol.MeterPmc350b:
-			calc, err = electric.NewMeterPMC350B(cfg.No, today, "", cfg.OtherConfig)
-			if err != nil {
-				err = fmt.Errorf("创建电表[%s]-[%s] 计算参数失败: %s", cfg.No, cfg.Protocol, err.Error())
-				return
-			}
-		default:
-			err = fmt.Errorf("不支持的协议: %s %s", cfg.No, cfg.Protocol)
-			return
-		}
-	}
-	return
-}
-
-func updateMeterCalc(elMeter electric.MeterElectric, calc *iotInterface.MeterCalc) {
-	q := sdk.Runtime.GetMemoryQueue("")
-	data, err := json.Marshal(elMeter)
-	if err != nil {
-		logger.Errorf("更新电表计算参数失败: %s", err.Error())
-		return
-	}
-	mp := make(map[string]interface{})
-	mp["data"] = string(data)
-	mp["id"] = elMeter.Id
-	mp["time"] = elMeter.Time
-	message, err := sdk.Runtime.GetStreamMessage("", global.UpdateMeterCalc, mp)
-	if err != nil {
-		logger.Errorf("构建更新表计计算参数 message [%s]失败: %v", global.UpdateMeterCalc, err)
-		return
-	}
-	err = q.Append(message)
-	if err != nil {
-		return
-	}
-	iotMap.MapMeterCalc.Add(elMeter.Id, calc)
-}
-
 func packHj212(d *iotStruct.CollectData, cfg *iotStruct.ReportConfig) (string, bool) {
 func packHj212(d *iotStruct.CollectData, cfg *iotStruct.ReportConfig) (string, bool) {
 	now := time.Now()
 	now := time.Now()
 	nt := fmt.Sprintf("%04d%02d%02d%02d%02d00", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute())
 	nt := fmt.Sprintf("%04d%02d%02d%02d%02d00", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute())

+ 63 - 0
SERVER/IotAdmin/iot/protocol/report/meter_calc.go

@@ -0,0 +1,63 @@
+package iotReportProtocol
+
+import (
+	"IotAdmin/common/global"
+	"IotAdmin/core/logger"
+	"IotAdmin/core/sdk"
+	iotInterface "IotAdmin/iot/interface"
+	iotMap "IotAdmin/iot/map"
+	iotProtocol "IotAdmin/iot/protocol"
+	iotStruct "IotAdmin/iot/struct"
+	"IotAdmin/iot/struct/electric"
+	"encoding/json"
+	"errors"
+	"strconv"
+	"time"
+)
+
+func getMeterElectricCalc(cfg *iotStruct.SlaveConfig) (calc iotInterface.MeterCalcHandler, tms int, err error) {
+	now := time.Now()
+	today, _ := strconv.Atoi(now.Format("20060102"))
+	tms = today
+	if x, ok := iotMap.MapMeterCalc.Get(cfg.No); ok {
+		calc = *x
+	} else {
+		calc, err = GetMeterCalcHandler(cfg.Protocol, cfg.No, today, "", cfg.OtherConfig)
+	}
+	return
+}
+
+// GetMeterCalcHandler 获取表计协议计算处理器
+func GetMeterCalcHandler(protocol string, id string, time int, calc, cfg string) (handler iotInterface.MeterCalcHandler, err error) {
+	switch protocol {
+	case iotProtocol.MeterElAdw300:
+		handler, err = electric.NewMeterADW300(id, time, calc, cfg)
+	case iotProtocol.MeterElPmc350b:
+		handler, err = electric.NewMeterPMC350B(id, time, calc, cfg)
+	default:
+		err = errors.New("not support protocol")
+	}
+	return
+}
+func updateMeterCalc(elMeter electric.MeterElectric, calc *iotInterface.MeterCalcHandler) {
+	q := sdk.Runtime.GetMemoryQueue("")
+	data, err := json.Marshal(elMeter)
+	if err != nil {
+		logger.Errorf("更新电表计算参数失败: %s", err.Error())
+		return
+	}
+	mp := make(map[string]interface{})
+	mp["data"] = string(data)
+	mp["id"] = elMeter.Id
+	mp["time"] = elMeter.Time
+	message, err := sdk.Runtime.GetStreamMessage("", global.UpdateMeterCalc, mp)
+	if err != nil {
+		logger.Errorf("构建更新表计计算参数 message [%s]失败: %v", global.UpdateMeterCalc, err)
+		return
+	}
+	err = q.Append(message)
+	if err != nil {
+		return
+	}
+	iotMap.MapMeterCalc.Add(elMeter.Id, calc)
+}

+ 0 - 20
SERVER/IotAdmin/iot/protocol/type.go

@@ -1,20 +0,0 @@
-package iotProtocol
-
-import (
-	iotRtuService "IotAdmin/iot/service/rtuService"
-	iotStruct "IotAdmin/iot/struct"
-)
-
-// MeterHandler 电表处理接口
-type MeterHandler interface {
-	Collect(w iotRtuService.RtuNetPgr, data *iotStruct.CollectData) error
-	SetAddress(w iotRtuService.RtuNetPgr, addr int) error
-	GetRatio(w iotRtuService.RtuNetPgr) (string, error)
-	SetRatio(w iotRtuService.RtuNetPgr, ratio string) error
-}
-
-// ReportHandler 上报处理接口
-type ReportHandler interface {
-	Adapter(data *iotStruct.CollectData)
-	Report(data *iotStruct.CollectData, config *iotStruct.ReportConfig) *string
-}

+ 5 - 14
SERVER/IotAdmin/iot/service/downService/collect.go

@@ -4,8 +4,7 @@ import (
 	"IotAdmin/core/logger"
 	"IotAdmin/core/logger"
 	"IotAdmin/core/tools/utils"
 	"IotAdmin/core/tools/utils"
 	iotMap "IotAdmin/iot/map"
 	iotMap "IotAdmin/iot/map"
-	iotProtocol "IotAdmin/iot/protocol"
-	iotElProtocol "IotAdmin/iot/protocol/electric"
+	iotProtocolHandler "IotAdmin/iot/protocol/handler"
 	iotRtuService "IotAdmin/iot/service/rtuService"
 	iotRtuService "IotAdmin/iot/service/rtuService"
 	iotStruct "IotAdmin/iot/struct"
 	iotStruct "IotAdmin/iot/struct"
 )
 )
@@ -48,17 +47,10 @@ func collectData(sn string, config *iotStruct.DtuConfig) *[]*iotStruct.CollectDa
 		w.SetClientState(client)
 		w.SetClientState(client)
 		w.SetSerialNumber(sn)
 		w.SetSerialNumber(sn)
 
 
-		var (
-			err            error
-			collectHandler iotProtocol.MeterHandler
-		)
-		switch cfg.Protocol {
-		case iotProtocol.MeterAdw300:
-			collectHandler = iotElProtocol.NewAdw300MeterHandler()
-		case iotProtocol.MeterPmc350b:
-			collectHandler = iotElProtocol.NewPmc350bMeterHandler()
-		default:
-			client.Logger.Errorf("[%s]未识别采集器类型: %s", cfg.No, cfg.Protocol)
+		collectHandler, err := iotProtocolHandler.GetMeterHandler(cfg.Protocol)
+		if err != nil {
+			client.Logger.Errorf("[%s]未识别采集器协议: %s", cfg.No, cfg.Protocol)
+			continue
 		}
 		}
 		newCfg := cfg
 		newCfg := cfg
 		colData := &iotStruct.CollectData{
 		colData := &iotStruct.CollectData{
@@ -74,7 +66,6 @@ func collectData(sn string, config *iotStruct.DtuConfig) *[]*iotStruct.CollectDa
 		client.Logger.Debugf("[- %s -]采集完成 Addr:%d  Protocol: %s", cfg.No, cfg.Addr, cfg.Protocol)
 		client.Logger.Debugf("[- %s -]采集完成 Addr:%d  Protocol: %s", cfg.No, cfg.Addr, cfg.Protocol)
 	}
 	}
 	client.Logger.Info(" \r\n【采集数据完成】")
 	client.Logger.Info(" \r\n【采集数据完成】")
-
 	logger.Debugf("采集数据完成【%s】 %v", sn, array)
 	logger.Debugf("采集数据完成【%s】 %v", sn, array)
 	return &array
 	return &array
 }
 }

+ 5 - 7
SERVER/IotAdmin/iot/service/downService/report.go

@@ -2,8 +2,7 @@ package iotDownService
 
 
 import (
 import (
 	iotLog "IotAdmin/iot/log"
 	iotLog "IotAdmin/iot/log"
-	iotProtocol "IotAdmin/iot/protocol"
-	iotElProtocol "IotAdmin/iot/protocol/electric"
+	iotProtocolHandler "IotAdmin/iot/protocol/handler"
 	iotStruct "IotAdmin/iot/struct"
 	iotStruct "IotAdmin/iot/struct"
 )
 )
 
 
@@ -11,17 +10,16 @@ func reportData(dataArray *[]*iotStruct.CollectData) {
 	if dataArray == nil || len(*dataArray) == 0 {
 	if dataArray == nil || len(*dataArray) == 0 {
 		return
 		return
 	}
 	}
-	var reportHandler iotProtocol.ReportHandler
 	for _, data := range *dataArray {
 	for _, data := range *dataArray {
 		cfg := data.SlaveConfig
 		cfg := data.SlaveConfig
 		if cfg == nil {
 		if cfg == nil {
 			continue
 			continue
 		}
 		}
 		for _, rc := range *cfg.ReportConfig {
 		for _, rc := range *cfg.ReportConfig {
-			switch rc.Protocol {
-			case iotProtocol.PlatElHj212:
-				reportHandler = iotElProtocol.NewElHj212ReportHandler()
-			default:
+			reportHandler, err := iotProtocolHandler.GetReportHandler(rc.Protocol)
+			if err != nil {
+				data.Logger.Errorf("GetReportHandler error:%s", err)
+				continue
 			}
 			}
 			go func(d *iotStruct.CollectData, cfg *iotStruct.ReportConfig) {
 			go func(d *iotStruct.CollectData, cfg *iotStruct.ReportConfig) {
 				reportHandler.Adapter(d)
 				reportHandler.Adapter(d)

+ 5 - 1
SERVER/IotAdmin/iot/struct/electric/adw300.go

@@ -15,7 +15,7 @@ type MeterADW300Other struct {
 	CT int `json:"ct"`
 	CT int `json:"ct"`
 }
 }
 
 
-func NewMeterADW300(id string, time int, calc, cfg string) (iotInterface.MeterCalc, error) {
+func NewMeterADW300(id string, time int, calc, cfg string) (iotInterface.MeterCalcHandler, error) {
 	meter := &MeterADW300{
 	meter := &MeterADW300{
 		MeterElectric: MeterElectric{
 		MeterElectric: MeterElectric{
 			MeterElectricBase: MeterElectricBase{
 			MeterElectricBase: MeterElectricBase{
@@ -79,3 +79,7 @@ func (m *MeterADW300) SetMeterData(data interface{}) {
 		m.MeterElectricBase = meter.MeterElectricBase
 		m.MeterElectricBase = meter.MeterElectricBase
 	}
 	}
 }
 }
+
+func (mo *MeterADW300Other) GetStructData() interface{} {
+	return mo
+}

+ 5 - 1
SERVER/IotAdmin/iot/struct/electric/pmc350B.go

@@ -20,7 +20,7 @@ type MeterPMC350BOther struct {
 	CurrentType    int `json:"currentType"`
 	CurrentType    int `json:"currentType"`
 }
 }
 
 
-func NewMeterPMC350B(id string, time int, calc, cfg string) (iotInterface.MeterCalc, error) {
+func NewMeterPMC350B(id string, time int, calc, cfg string) (iotInterface.MeterCalcHandler, error) {
 	meter := &MeterPMC350B{
 	meter := &MeterPMC350B{
 		MeterElectric: MeterElectric{
 		MeterElectric: MeterElectric{
 			MeterElectricBase: MeterElectricBase{
 			MeterElectricBase: MeterElectricBase{
@@ -87,3 +87,7 @@ func (m *MeterPMC350B) SetMeterData(data interface{}) {
 		m.MeterElectricBase = meter.MeterElectricBase
 		m.MeterElectricBase = meter.MeterElectricBase
 	}
 	}
 }
 }
+
+func (mo *MeterPMC350BOther) GetStructData() interface{} {
+	return mo
+}

+ 11 - 0
UI/IOTADMIN.VUE/src/api/iot/_device.ts

@@ -54,6 +54,17 @@ class deviceApi {
 			url: "/iot-device/report-protocols"
 			url: "/iot-device/report-protocols"
 		})
 		})
 	}
 	}
+	getDeviceConfig = (id: any) => {
+		return Rs.get({
+			url: "/iot-device/config/" + id
+		})
+	}
+	updateDeviceConfig = (data: any) => {
+		return Rs.put({
+			url: "/iot-device/config",
+			data: data
+		})
+	}
 }
 }
 
 
 export default deviceApi
 export default deviceApi

+ 5 - 1
UI/IOTADMIN.VUE/src/views/iot/device/_gateway.vue

@@ -362,7 +362,11 @@ defineExpose({ query })
 					</el-button>
 					</el-button>
 				</vb-tooltip>
 				</vb-tooltip>
 				<vb-tooltip content="新增表计" placement="top">
 				<vb-tooltip content="新增表计" placement="top">
-					<el-button link type="danger" @click="handleCreateMeter(row)">
+					<el-button
+						link
+						type="danger"
+						@click="handleCreateMeter(row)"
+						v-hasPermission="'iot:device:add'">
 						<template #icon>
 						<template #icon>
 							<VbIcon icon-name="plus-square" icon-type="duotone" class="fs-3"></VbIcon>
 							<VbIcon icon-name="plus-square" icon-type="duotone" class="fs-3"></VbIcon>
 						</template>
 						</template>

+ 53 - 8
UI/IOTADMIN.VUE/src/views/iot/device/_meter.vue

@@ -10,6 +10,7 @@ const reportProtocolOptions = ref<any[]>([])
 const isAdd = ref(false)
 const isAdd = ref(false)
 const tableRef = ref()
 const tableRef = ref()
 const modalRef = ref()
 const modalRef = ref()
+const modalConfigRef = ref()
 const opts = reactive<any>({
 const opts = reactive<any>({
 	columns: [
 	columns: [
 		{ field: "id", name: "ID", width: 100, visible: false, isSort: false, tooltip: true },
 		{ field: "id", name: "ID", width: 100, visible: false, isSort: false, tooltip: true },
@@ -184,21 +185,24 @@ const opts = reactive<any>({
 			type: "textarea",
 			type: "textarea",
 			required: false
 			required: false
 		},
 		},
+
 		{
 		{
-			field: "otherConfig",
-			label: "其他配置",
+			field: "description",
+			label: "设备描述",
 			class: "w-100",
 			class: "w-100",
 			component: "I",
 			component: "I",
 			type: "textarea",
 			type: "textarea",
 			required: false
 			required: false
-		},
+		}
+	] as any,
+	formItems2: [
 		{
 		{
-			field: "description",
-			label: "设备描述",
+			field: "config",
+			label: "表计配置",
 			class: "w-100",
 			class: "w-100",
 			component: "I",
 			component: "I",
 			type: "textarea",
 			type: "textarea",
-			required: false
+			required: true
 		}
 		}
 	] as any,
 	] as any,
 	modalTitle: "表计",
 	modalTitle: "表计",
@@ -227,12 +231,15 @@ const opts = reactive<any>({
 		protocol: undefined,
 		protocol: undefined,
 		address: undefined,
 		address: undefined,
 		bmYz: undefined,
 		bmYz: undefined,
-		description: undefined,
-		otherConfig: undefined
+		description: undefined
 	}
 	}
 })
 })
 const { queryParams, emptyFormData } = toRefs(opts)
 const { queryParams, emptyFormData } = toRefs(opts)
 const form = ref<any>(Object.assign({}, emptyFormData.value))
 const form = ref<any>(Object.assign({}, emptyFormData.value))
+const form2 = ref<any>({
+	id: undefined,
+	config: ""
+})
 
 
 function handleCreate(parentId: number) {
 function handleCreate(parentId: number) {
 	isAdd.value = true
 	isAdd.value = true
@@ -302,6 +309,26 @@ function handelRemoveReportConfig(index: number) {
 	})
 	})
 }
 }
 
 
+function handelUpdateConfig(row: any) {
+	apis.iot.deviceApi.getDeviceConfig(row.id).then((res: any) => {
+		form2.value = {
+			id: row.id,
+			config: JSON.stringify(res.data)
+		}
+		modalConfigRef.value.show()
+	})
+}
+
+function submitConfig() {
+	if (form2.value.config == "") {
+		message.msgError("请输入配置")
+		return
+	}
+	apis.iot.deviceApi.updateDeviceConfig(form2.value).then(() => {
+		message.msgSuccess("修改成功")
+	})
+}
+
 function init() {
 function init() {
 	apis.iot.deviceApi.getDeviceProtocols().then((res: any) => {
 	apis.iot.deviceApi.getDeviceProtocols().then((res: any) => {
 		protocolOptions.value = res.data.map((v: any) => {
 		protocolOptions.value = res.data.map((v: any) => {
@@ -393,6 +420,17 @@ defineExpose({
 						</template>
 						</template>
 					</el-button>
 					</el-button>
 				</vb-tooltip>
 				</vb-tooltip>
+				<vb-tooltip content="修改配置" placement="top">
+					<el-button
+						link
+						type="danger"
+						@click="handelUpdateConfig(row)"
+						v-hasPermission="'iot:device:config'">
+						<template #icon>
+							<VbIcon icon-name="gear" icon-type="solid" class="fs-3"></VbIcon>
+						</template>
+					</el-button>
+				</vb-tooltip>
 				<vb-tooltip content="删除" placement="top">
 				<vb-tooltip content="删除" placement="top">
 					<el-button
 					<el-button
 						link
 						link
@@ -504,5 +542,12 @@ defineExpose({
 				</div>
 				</div>
 			</template>
 			</template>
 		</VbModal>
 		</VbModal>
+		<VbModal
+			v-model:modal="modalConfigRef"
+			title="修改配置"
+			:form-items="opts.formItems2 as any"
+			:form-data="form2"
+			@confirm="submitConfig"
+			append-to-body></VbModal>
 	</div>
 	</div>
 </template>
 </template>