-
Notifications
You must be signed in to change notification settings - Fork 174
Expand file tree
/
Copy pathtrackController.go
More file actions
174 lines (145 loc) · 4.69 KB
/
Copy pathtrackController.go
File metadata and controls
174 lines (145 loc) · 4.69 KB
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
package controllers
import (
"context"
"encoding/json"
"log"
"strconv"
"time"
"github.com/kubeedge/examples/kubeedge-counter-demo/web-controller-app/utils"
devices "github.com/kubeedge/kubeedge/cloud/pkg/apis/devices/v1alpha2"
"github.com/astaxie/beego"
"k8s.io/client-go/rest"
)
// DeviceStatus is used to patch device status
type DeviceStatus struct {
Status devices.DeviceStatus `json:"status"`
}
// The device id of the counter
var deviceID = "counter"
// The default namespace in which the counter device instance resides
var namespace = "default"
// The CRD client used to patch the device instance.
var crdClient *rest.RESTClient
// The twin value map
var statusMap = map[string]string{
"ON": "1",
"OFF": "0",
}
func init() {
// Create a client to talk to the K8S API server to patch the device CRDs
kubeConfig, err := utils.KubeConfig()
if err != nil {
log.Fatalf("Failed to create KubeConfig, error : %v", err)
}
log.Println("Get kubeConfig successfully")
crdClient, err = utils.NewCRDClient(kubeConfig)
if err != nil {
log.Fatalf("Failed to create device crd client, error : %v", err)
}
log.Println("Get crdClient successfully")
}
// QueryDeviceStatus query device status
func QueryDeviceStatus() map[string]string {
status := map[string]string{
"status": "OFF",
"value": "0",
}
result := DeviceStatus{}
raw, err := crdClient.Get().Namespace(namespace).Resource(utils.ResourceTypeDevices).Name(deviceID).DoRaw(context.TODO())
if err != nil {
log.Printf("Failed to query device status of device %v in namespace %v, error:%+v", deviceID, namespace, err)
return status
}
err = json.Unmarshal(raw, &result)
if err != nil {
log.Printf("Failed to Unmarshal device raw of device %v in namespace %v, error:%+v", deviceID, namespace, err)
return status
}
for _, twin := range result.Status.Twins {
status["status"] = twin.Desired.Value
status["value"] = twin.Reported.Value
}
return status
}
// UpdateDeviceTwinWithDesiredTrack patches the desired state of
// the device twin with the command.
func UpdateDeviceTwinWithDesiredTrack(cmd string) bool {
// get current device status
currentDeviceStatus := QueryDeviceStatus()
if cmd == currentDeviceStatus["status"] {
return true
}
status := buildStatusWithDesiredTrack(cmd)
deviceStatus := &DeviceStatus{Status: status}
body, err := json.Marshal(deviceStatus)
if err != nil {
log.Printf("Failed to marshal device status %v", deviceStatus)
return false
}
result := crdClient.Patch(utils.MergePatchType).Namespace(namespace).Resource(utils.ResourceTypeDevices).Name(deviceID).Body(body).Do(context.TODO())
if result.Error() != nil {
log.Printf("Failed to patch device status %v of device %v in namespace %v \n error:%+v", deviceStatus, deviceID, namespace, result.Error())
return false
} else {
log.Printf("Turn %s %s", cmd, deviceID)
}
return true
}
func buildStatusWithDesiredTrack(cmd string) devices.DeviceStatus {
metadata := map[string]string{
"timestamp": strconv.FormatInt(time.Now().Unix()/1e6, 10),
"type": "string",
}
twins := []devices.Twin{{PropertyName: "status", Desired: devices.TwinProperty{Value: cmd, Metadata: metadata}, Reported: devices.TwinProperty{Value: statusMap[cmd], Metadata: metadata}}}
devicestatus := devices.DeviceStatus{Twins: twins}
return devicestatus
}
type TrackController struct {
beego.Controller
}
// Index is the initial view
func (controller *TrackController) Index() {
log.Println("Index Start")
controller.Layout = "layout.html"
controller.TplName = "content.html"
controller.LayoutSections = map[string]string{}
controller.LayoutSections["PageHead"] = "head.html"
log.Println("Index Finish")
}
// ControlTrack is the main view
func (controller *TrackController) ControlTrack() {
// Get track id
params := struct {
TrackID string `form:":trackId"`
}{controller.GetString(":trackId")}
resultCode := 0
status := map[string]string{}
log.Printf("ControlTrack: %s", params.TrackID)
// update track
if params.TrackID == "ON" {
UpdateDeviceTwinWithDesiredTrack(params.TrackID)
resultCode = 1
} else if params.TrackID == "OFF" {
UpdateDeviceTwinWithDesiredTrack(params.TrackID)
resultCode = 2
} else if params.TrackID == "STATUS" {
status = QueryDeviceStatus()
resultCode = 3
}
// response
controller.AjaxResponse(resultCode, status, nil)
}
// AjaxResponse returns a standard ajax response.
func (Controller *TrackController) AjaxResponse(resultCode int, resultString map[string]string, data interface{}) {
response := struct {
Result int
ResultString map[string]string
ResultObject interface{}
}{
Result: resultCode,
ResultString: resultString,
ResultObject: data,
}
Controller.Data["json"] = response
Controller.ServeJSON()
}