zhangzengfei
2023-09-05 1b34d7bacad94933ad63fc0e199bd32ac49d9fa5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
package controllers
 
import (
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/bhomedbapi.git"
    "basic.com/valib/logger.git"
    "context"
    "encoding/json"
    "github.com/satori/go.uuid"
    "nanomsg.org/go-mangos"
    "nanomsg.org/go-mangos/protocol/rep"
    "nanomsg.org/go-mangos/transport/ipc"
    "nanomsg.org/go-mangos/transport/tcp"
    "strconv"
    "time"
    "vamicro/devicemanage-service/broadcast"
    "vamicro/devicemanage-service/models"
    "vamicro/devicemanage-service/service"
    "vamicro/devicemanage-service/vo"
)
 
type DeviceController struct {
 
}
 
//搜索设备
func (dc *DeviceController) Search(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
    nodes, err := broadcast.BroadCast()
    if err != nil {
        return &bhomeclient.Reply{ Msg: err.Error()}
    }
    if nodes == nil {
        nodes = make([]string, 0)
    }
    return &bhomeclient.Reply{ Success: true, Data: nodes}
}
 
//申请添加设备
func (dc *DeviceController) AddApply(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
    type addApplyArg struct {
        Key     string     `json:"key"`
        DevId     string     `json:"devId"`
        Ip         string     `json:"ip"`
    }
    var reqBody addApplyArg
    err := c.BindJSON(&reqBody)
    if err != nil || reqBody.Key == "" || reqBody.DevId == "" || reqBody.Ip == "" {
        return &bhomeclient.Reply{ Msg: "参数有误"}
    }
    var da models.DeviceApply
    i,e := da.FindByDevId(reqBody.DevId)
    if e != nil || i == 0 { //未申请添加过此设备
        da.Id = uuid.NewV4().String()
        da.DevId = reqBody.DevId
        da.CreateTime = time.Now().Format("2006-01-02 15:04:05")
        da.ApplyKey = reqBody.Key
        da.Ip = reqBody.Ip
        da.Status = models.ApplyStatus_Sending
        if da.Insert() {
            return &bhomeclient.Reply{ Success: true, Msg: "添加成功"}
        } else {
            return &bhomeclient.Reply{ Success: true, Msg: "添加失败"}
        }
    } else if da.Status == models.ApplyStatus_Reject { //已被拒绝的请求,可以重新发起申请
        if da.UpdateStatus(models.ApplyStatus_Sending, da.Id) {
            return &bhomeclient.Reply{ Success: true, Msg: "操作成功"}
        } else {
            return &bhomeclient.Reply{ Msg: "重新发送请求失败"}
        }
    }
 
    return &bhomeclient.Reply{ Msg: "已添加对此设备的申请"}
}
 
func RecvApprove(ctx context.Context) {
    url := "0.0.0.0:"+strconv.Itoa(4012)
    var sock mangos.Socket
    var err error
    var msg []byte
    if sock, err = rep.NewSocket(); err != nil {
        logger.Debug("new applyApprove socket err:", err)
    }
    sock.AddTransport(ipc.NewTransport())
    sock.AddTransport(tcp.NewTransport())
    if err = sock.Listen(url); err != nil {
        logger.Debug("listen on applyApprove socket err:", err)
    }
 
    for {
        select {
        case <-ctx.Done():
            logger.Debug("ctx done")
            return
        default:
            msg, err = sock.Recv()
            if err != nil {
                continue
            }
 
            if len(msg) > 0 {
                apply := dealApprove(msg)
                ret, _ := json.Marshal(*apply)
                retErr := sock.Send(ret)
                if retErr != nil {
                    logger.Debug("retErr:", retErr)
                }
            } else {
                time.Sleep(time.Millisecond*100)
            }
        }
    }
}
 
func dealApprove(msg []byte) *bhomeclient.Reply {
    type approveArg struct {
        DevId     string     `json:"devId"`  //设备id
        Status     int     `json:"status"` //-1表示拒绝,1:表示通过
    }
 
    var reqBody approveArg
    err := json.Unmarshal(msg, &reqBody)
    if err != nil || reqBody.Status < models.ApplyStatus_Reject || reqBody.Status > models.ApplyStatus_Agreed {
        return &bhomeclient.Reply{ Msg: "请求参数有误"}
    }
    var da models.DeviceApply
    i, _ := da.FindByDevId(reqBody.DevId)
    if i == 0 {
        return &bhomeclient.Reply{ Msg: reqBody.DevId+"的申请请求已不存在,请检查" }
    }
    if da.Status != models.ApplyStatus_Waiting {
        return &bhomeclient.Reply{ Msg: "当前此设备id不是申请状态,请检查" }
    }
    if da.UpdateStatus(reqBody.Status, da.Id) {
        return &bhomeclient.Reply{ Success: true, Msg: "操作成功"}
    }
 
    return &bhomeclient.Reply{ Msg: "操作失败"}
}
 
//其他节点通过申请或者拒绝申请
func (dc *DeviceController) ApplyApprove(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
    return &bhomeclient.Reply{ Msg: "building..."}
}
 
//func (dc *DeviceController) SyncDevToManager(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
//    var reqBody sysVo.SyncDevInfo
//    err := c.BindJSON(&reqBody)
//    if err != nil {
//        return &bhomeclient.Reply{ Msg: err.Error() }
//    }
//
//    return &bhomeclient.Reply{ Data: reqBody }
//}
 
//设备归类统计,分全部设备、集群xx设备、未加入集群
func (dc *DeviceController) Types(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
    type devStatistic struct {
        Name           string         `json:"name"`
        DevCount     int         `json:"devCount"`
        SdkCount     int         `json:"sdkCount"`
        Percent     string         `json:"percent"`
        ClusterId     string         `json:"clusterId"`
        Type         int         `json:"type"`
    }
    list := make([]devStatistic, 0)
    //1.统计全部设备
    total := devStatistic{
        Name: "全部设备",
        DevCount: 100,
        SdkCount: 45,
        Percent: "80%",
        Type: 0,
    }
    list = append(list, total)
    //2.按集群统计
    var d models.Device
    devCts := d.GroupByCluster()
    if devCts != nil {
        for _,g := range devCts {
            ds := devStatistic{
                Name: g.ClusterName,
                ClusterId: g.ClusterId,
                DevCount: g.Count,
                SdkCount: 0,
                Percent: "70%",
                Type: 1,
            }
            list = append(list, ds)
        }
    }
    //3.未加入集群设备
    ns := devStatistic{
        Name: "未加入集群",
        DevCount: 0,
        SdkCount: 0,
        Percent: "10%",
        Type: 2,
    }
    list = append(list, ns)
 
    return &bhomeclient.Reply{ Success: true, Data: list}
}
 
//通过不同类别获取设备列表,分页
func (dc *DeviceController) PageByType(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
    type PageDevArg struct {
        Type         int     `json:"type"`  //类型
        ClusterId     string     `json:"clusterId"`   //集群id
        Status         int     `json:"status"`   //状态 0:全部,1:在线,-1:离线
        Page         int     `json:"page"`
        Size         int     `json:"size"`
        InputTxt     string     `json:"inputTxt"`
    }
    var reqBody PageDevArg
    err := c.BindJSON(&reqBody)
    if err != nil {
        return &bhomeclient.Reply{ Msg:err.Error()}
    }
    if reqBody.Page <= 0 {
        reqBody.Page = 1
    }
    if reqBody.Size <= 0 {
        reqBody.Size = 8
    }
    var d models.Device
    if reqBody.Type == 0 { //全部设备
        list, err := d.PageAllDev(reqBody.Page, reqBody.Size, reqBody.Status, reqBody.InputTxt)
        if err != nil {
            return &bhomeclient.Reply{ Msg: err.Error()}
        }
        return &bhomeclient.Reply{ Success: true, Data: list}
    } else if reqBody.Type == 1 || reqBody.Type == 2 {  //按集群统计
        list, err := d.PageDevByCluster(reqBody.Page, reqBody.Size, reqBody.ClusterId, reqBody.Status, reqBody.InputTxt)
        if err != nil {
            return &bhomeclient.Reply{ Msg: err.Error()}
        }
        return &bhomeclient.Reply{ Success: true, Data: list}
    }
 
    return nil
}
 
//获取设备详情
func (dc *DeviceController) Detail(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
    devId := c.Query("devId")
    logger.Debug("Detail devId:", devId)
    var d models.Device
    i, e := d.FindByDevId(devId)
    if e == nil && i > 0 {
        detail := vo.DevDetail{}
        pd,_ := vo.CopyDeviceFromModel(d)
        detail.Device = pd
        detail.Sdks = getSdkDetailsByDevId(d.DevId)
        detail.Apps = getAppDetailsByDevId(d.DevId)
 
 
        return &bhomeclient.Reply{ Success:true, Data: detail }
    } else {
        return &bhomeclient.Reply{ Msg:"未找到此设备的相关信息"}
    }
}
 
func getSdkDetailsByDevId(devId string) []vo.SdkDetail {
    arr := make([]vo.SdkDetail, 0)
 
    var sdkApi bhomedbapi.SdkApi
    sdkMap := sdkApi.FindAllMap()
 
    var ds models.DeviceSdk
    list, _ := ds.FindByMachineCode("", devId)
    if list != nil {
        for _,s :=range list {
            if v,ok := sdkMap[s.SdkId]; ok {
                sd := vo.SdkDetail{}
                sd.Sdk = v
                sd.InstallTime = s.InstallTime
                sd.ExpireTime = s.ExpireTime
                sd.ActivateCode = s.ActivateCode
                arr = append(arr, sd)
            }
        }
    }
    return arr
}
 
func getAppDetailsByDevId(devId string) []vo.AppDetail {
    arr := make([]vo.AppDetail, 0)
 
    var appApi bhomedbapi.AppApi
    appMap := appApi.FindAppMap()
 
    var da models.DeviceApp
    list, _ := da.FindByMachineCode("", devId)
    if list != nil {
        for _,s :=range list {
            if v,ok := appMap[s.AppId]; ok {
                ad := vo.AppDetail{}
                ad.App = v
                ad.InstallTime = s.InstallTime
                ad.ExpireTime = s.ExpireTime
                ad.ActivateCode = s.ActivateCode
                arr = append(arr, ad)
            }
        }
    }
    return arr
}
 
 
//控制远程设备创建集群
func (dc *DeviceController) RemoteCreateCluster(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    var reqBody vo.CreateClusterArg
    err := c.BindJSON(&reqBody)
    if err != nil {
        return &bhomeclient.Reply{ Msg: "参数有误"}
    }
 
    r,err := service.RemoteCreateCluster(reqBody)
    if err == nil {
        return r
    }
    return &bhomeclient.Reply{ Msg: err.Error() }
}
 
//控制远程设备搜索集群
func (dc *DeviceController) RemoteSearchCluster(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    var reqBody vo.SearchClusterArg
    err := c.BindJSON(&reqBody)
    if err != nil {
        return &bhomeclient.Reply{ Msg: "参数有误"}
    }
    r, err := service.RemoteSearchCluster(reqBody)
    if err == nil {
        return r
    }
    return &bhomeclient.Reply{ Msg: err.Error() }
}
 
//获取远程设备搜索到的设备列表
func (dc *DeviceController) RemoteGetSearchNodes(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    var reqBody vo.GetSearchNodesArg
    err := c.BindJSON(&reqBody)
    if err != nil {
        return &bhomeclient.Reply{ Msg: "参数有误"}
    }
    r,err := service.RemoteGetSearchNodes(reqBody)
    if err == nil {
        return r
    }
    return &bhomeclient.Reply{Msg: err.Error()}
}
 
//加入集群
func (dc *DeviceController) RemoteJoinCluster(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
    var reqBody vo.JoinClusterArg
    err := c.BindJSON(&reqBody)
    if err != nil {
        return &bhomeclient.Reply{ Msg: "参数有误"}
    }
    r,err := service.RemoteJoinCluster(reqBody)
    if err == nil {
        return r
    }
    return &bhomeclient.Reply{ Msg: err.Error()}
}
 
//设备重启
func (dc *DeviceController) RemoteReboot(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
    var reqBody vo.RebootArg
    err := c.BindJSON(&reqBody)
    if err != nil {
        return &bhomeclient.Reply{ Msg: "参数有误"}
    }
    r,err := service.RemoteReboot(reqBody)
    if err == nil {
        return r
    }
    return &bhomeclient.Reply{ Msg: err.Error()}
}
 
//移除设备
func (dc *DeviceController) RemoteRemove(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
 
    return nil
}
 
//卸载算法或者应用
func (dc *DeviceController) RemoteUninstall(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
    var reqBody vo.UninstallArg
    err := c.BindJSON(&reqBody)
    if err != nil {
        return &bhomeclient.Reply{ Msg: "参数有误"}
    }
    r,err := service.RemoteUninstall(reqBody)
    if err == nil {
        return r
    }
    return &bhomeclient.Reply{ Msg: err.Error()}
}
 
//升级算法或者应用
func (dc *DeviceController) RemoteUpgrade(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
    var reqBody vo.UpgradeArg
    err := c.BindJSON(&reqBody)
    if err != nil {
        return &bhomeclient.Reply{ Msg: "参数有误"}
    }
    r,err := service.RemoteUpgrade(reqBody)
    if err == nil {
        return r
    }
    return &bhomeclient.Reply{ Msg: err.Error()}
}
 
//系统更新
func (dc *DeviceController) RemoteSysUpdate(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
    var reqBody vo.SysUpdateArg
    err := c.BindJSON(&reqBody)
    if err != nil {
        return &bhomeclient.Reply{ Msg: "参数有误"}
    }
 
    r,err := service.RemoteSysUpdate(reqBody)
    if err == nil {
        return r
    }
    return &bhomeclient.Reply{ Msg: err.Error()}
}