| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- package tools
- import (
- "context"
- "sort"
- "strconv"
- "strings"
- "time"
- "github.com/mark3labs/mcp-go/mcp"
- "fwh-toolbox-server/agentmcp/kit"
- "fwh-toolbox-server/domain"
- "fwh-toolbox-server/repositories"
- )
- // ---- mqtt_log_search ----
- type mqttLogSearchArgs struct {
- SN string `json:"sn" jsonschema:"站点 SN(aGate 序列号)"`
- CmdType string `json:"cmdType" jsonschema:"MQTT 命令类型,如 0(连接中断)、101(登录)、105(心跳)、107(参数更新)、201、211 等"`
- From string `json:"from" jsonschema:"开始时间,yyyy-MM-dd HH:mm:ss"`
- To string `json:"to" jsonschema:"结束时间,同上;与开始时间相差不超过 7 天"`
- Limit int `json:"limit,omitempty" jsonschema:"最多返回条数,1~300,默认 50"`
- }
- // MqttRow mqtt_log_search 的精简行
- type MqttRow struct {
- LogTime string `json:"logTime"` // 设备时间
- Time string `json:"time,omitempty"` // UTC 时间
- Cmd string `json:"cmd,omitempty"`
- Data string `json:"data,omitempty"` // 原始报文,超过 1500 字截断
- }
- var MqttLogSearch = kit.Def[mqttLogSearchArgs]{
- Name: "mqtt_log_search",
- Title: "查询站点 MQTT 日志",
- Description: "查询单个站点在一段时间内某类 MQTT 命令的日志(FWH 平台),按时间倒序。" +
- "返回字段:logTime(设备时间)、time(UTC)、cmd、data(原始报文 JSON,超过 1500 字截断)。报文较大,建议缩小时间范围、减少 limit。",
- ReadOnly: true,
- Handler: func(ctx context.Context, a mqttLogSearchArgs) (*mcp.CallToolResult, error) {
- sn, err := kit.Required("sn", a.SN)
- if err != nil {
- return kit.Fail(err), nil
- }
- cmd, err := kit.Required("cmdType", a.CmdType)
- if err != nil {
- return kit.Fail(err), nil
- }
- from, to, err := kit.ParseRange(a.From, a.To, 7*24*time.Hour)
- if err != nil {
- return kit.Fail(err), nil
- }
- items, err := repositories.QueryMqttLogListOnTimeRange(sn, domain.MqttCmdType(cmd), from, to)
- if err != nil {
- return kit.Upstream("FWH 平台 MQTT 日志接口", err), nil
- }
- rows := make([]MqttRow, 0, len(items))
- for _, it := range items {
- rows = append(rows, MqttRow{
- LogTime: it.LogTime,
- Time: it.Time,
- Cmd: strings.TrimSpace(it.CmdType + " " + it.CmdName),
- Data: clip(it.LogData, 1500),
- })
- }
- sort.SliceStable(rows, func(i, j int) bool { return rows[i].LogTime > rows[j].LogTime })
- return kit.List(rows, -1, kit.Limit(a.Limit, 50, 300), "结果已截断,请缩短时间范围"), nil
- },
- }
- // ---- ems_log_records ----
- type emsLogRecordsArgs struct {
- SN string `json:"sn" jsonschema:"站点 SN(aGate 序列号)"`
- Date string `json:"date,omitempty" jsonschema:"日志日期 yyyy-MM-dd,不填查询全部"`
- LogType int `json:"logType,omitempty" jsonschema:"日志类型,默认 0(全部),取值以 FWH 平台定义为准"`
- }
- var EmsLogRecords = kit.Def[emsLogRecordsArgs]{
- Name: "ems_log_records",
- Title: "查询 EMS 日志召唤记录",
- Description: "查询站点最近的 EMS 日志召唤记录(FWH 平台)。返回字段:id、fileName、callTime(召唤时间)、completeTime、status(1 成功、0 召唤中、-1 失败)、fileUrl、linkId(SN)。" +
- "没有召唤记录时返回提示。",
- ReadOnly: true,
- Handler: func(ctx context.Context, a emsLogRecordsArgs) (*mcp.CallToolResult, error) {
- sn, err := kit.Required("sn", a.SN)
- if err != nil {
- return kit.Fail(err), nil
- }
- date := ""
- if d, err := kit.ParseDate("date", a.Date, true); err != nil {
- return kit.Fail(err), nil
- } else if d != nil {
- date = d.Format(kit.DateLayout)
- }
- rec, err := repositories.QueryEmsLogCallRecord(sn, date, a.LogType)
- if err != nil {
- // 上游在"没有召唤日志"时也返回 error,这里按无数据处理;原始错误只写日志
- return kit.Empty("未找到 EMS 日志召唤记录(" + kit.UpstreamText("FWH 平台 EMS 日志接口", err) + ")。"), nil
- }
- return kit.Object(rec), nil
- },
- }
- // ---- update_log_system ----
- type updateLogSystemArgs struct {
- SN string `json:"sn" jsonschema:"站点 SN(aGate 序列号)"`
- OrderID string `json:"orderId,omitempty" jsonschema:"升级单 ID(列表中的 id),填写时返回该升级单在本站点的明细"`
- Limit int `json:"limit,omitempty" jsonschema:"最多返回条数,1~200,默认 50"`
- }
- var UpdateLogSystem = kit.Def[updateLogSystemArgs]{
- Name: "update_log_system",
- Title: "查询系统升级记录",
- Description: "查询站点的系统(固件)升级记录(FWH 平台)。不填 orderId 时返回升级单列表:id、orderNo(升级单号)、name、upgradeType、upgradeTime(UTC)、upgradeNum 等;" +
- "填 orderId 时返回该升级单在本站点各设备的升级明细(版本、状态、时间等,以实际返回为准)。",
- ReadOnly: true,
- Handler: func(ctx context.Context, a updateLogSystemArgs) (*mcp.CallToolResult, error) {
- sn, err := kit.Required("sn", a.SN)
- if err != nil {
- return kit.Fail(err), nil
- }
- limit := kit.Limit(a.Limit, 50, 200)
- if id := strings.TrimSpace(a.OrderID); id != "" {
- orderID, err := strconv.ParseInt(id, 10, 64)
- if err != nil {
- return kit.Failf("参数 orderId 必须是数字:%s", id), nil
- }
- items, err := repositories.QuerySystemUpdateLogDetail(orderID, sn)
- if err != nil {
- return kit.Upstream("FWH 平台升级记录接口", err), nil
- }
- return kit.List(items, -1, limit, ""), nil
- }
- items, err := repositories.QuerySystemUpdateLog(sn)
- if err != nil {
- return kit.Upstream("FWH 平台升级记录接口", err), nil
- }
- return kit.List(items, -1, limit, ""), nil
- },
- }
- // ---- update_log_ahub ----
- type updateLogAhubArgs struct {
- SN string `json:"sn" jsonschema:"站点 SN(aGate 序列号)"`
- Limit int `json:"limit,omitempty" jsonschema:"最多返回条数,1~200,默认 50"`
- }
- var UpdateLogAhub = kit.Def[updateLogAhubArgs]{
- Name: "update_log_ahub",
- Title: "查询 aHub 升级记录",
- Description: "查询站点下 aHub(PowerLink)的升级记录(FWH 平台),返回升级时间、版本、状态等(以实际返回为准)。",
- ReadOnly: true,
- Handler: func(ctx context.Context, a updateLogAhubArgs) (*mcp.CallToolResult, error) {
- sn, err := kit.Required("sn", a.SN)
- if err != nil {
- return kit.Fail(err), nil
- }
- items, err := repositories.QueryAHubUpdateLog(sn)
- if err != nil {
- return kit.Upstream("FWH 平台 aHub 升级记录接口", err), nil
- }
- return kit.List(items, -1, kit.Limit(a.Limit, 50, 200), ""), nil
- },
- }
|