diff --git a/mappers/kubeedge-v1.15.0/modbus/Dockerfile b/mappers/kubeedge-v1.15.0/modbus/Dockerfile new file mode 100644 index 00000000..1afa4316 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/Dockerfile @@ -0,0 +1,20 @@ +FROM golang:1.17-alpine AS builder + +WORKDIR /build + +ENV GO111MODULE=on \ + GOPROXY=https://goproxy.cn,direct + +COPY . . + +RUN CGO_ENABLED=0 GOOS=linux go build -o main cmd/main.go + + +FROM ubuntu:16.04 + +RUN mkdir -p kubeedge + +COPY --from=builder /build/main kubeedge/ +COPY ./config.yaml kubeedge/ + +WORKDIR kubeedge diff --git a/mappers/kubeedge-v1.15.0/modbus/Makefile b/mappers/kubeedge-v1.15.0/modbus/Makefile new file mode 100644 index 00000000..4dbacfe2 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/Makefile @@ -0,0 +1,34 @@ +SHELL := /bin/bash + +curr_dir := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))) +rest_args := $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS)) +$(eval $(rest_args):;@:) + +help: + # + # Usage: + # make generate : generate a mapper based on a template. + # make mapper {mapper-name} : execute mapper building process. + # + # Actions: + # - mod, m : download code dependencies. + # - lint, l : verify code via go fmt and `golangci-lint`. + # - build, b : compile code. + # - package, p : package docker image. + # - clean, c : clean output binary. + # + # Parameters: + # ARM : true or undefined + # ARM64 : true or undefined + # + # Example: + # - make mapper modbus ARM64=true : execute `build` "modbus" mapper for ARM64. + # - make mapper modbus test : execute `test` "modbus" mapper. + @echo + +make_rules := $(shell ls $(curr_dir)/hack/make-rules | sed 's/.sh//g') +$(make_rules): + @$(curr_dir)/hack/make-rules/$@.sh $(rest_args) + +.DEFAULT_GOAL := help +.PHONY: $(make_rules) build test package \ No newline at end of file diff --git a/mappers/kubeedge-v1.15.0/modbus/cmd/main.go b/mappers/kubeedge-v1.15.0/modbus/cmd/main.go new file mode 100644 index 00000000..78d5d2e6 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/cmd/main.go @@ -0,0 +1,67 @@ +package main + +import ( + "errors" + "os" + + "k8s.io/klog/v2" + + "github.com/kubeedge/modbus/device" + "github.com/kubeedge/modbus/pkg/common" + "github.com/kubeedge/modbus/pkg/config" + "github.com/kubeedge/modbus/pkg/grpcclient" + "github.com/kubeedge/modbus/pkg/grpcserver" + "github.com/kubeedge/modbus/pkg/httpserver" + "github.com/kubeedge/modbus/pkg/util/parse" +) + +func main() { + var err error + var c config.Config + + klog.InitFlags(nil) + defer klog.Flush() + + if err = c.Parse(); err != nil { + klog.Fatal(err) + os.Exit(1) + } + klog.Infof("config: %+v", c) + + grpcclient.Init(&c) + + // start grpc server + grpcServer := grpcserver.NewServer( + grpcserver.Config{ + SockPath: c.GrpcServer.SocketPath, + Protocol: common.ProtocolCustomized, + }, + device.NewDevPanel(), + ) + + panel := device.NewDevPanel() + err = panel.DevInit(&c) + if err != nil && !errors.Is(err, parse.ErrEmptyData) { + klog.Fatal(err) + } + klog.Infoln("devInit finished") + + // register to edgecore + // if dev init mode is register, mapper's dev will init when registry to edgecore + if c.DevInit.Mode != common.DevInitModeRegister { + klog.Infoln("======dev init mode is not register, will register to edgecore") + if _, _, err = grpcclient.RegisterMapper(false); err != nil { + klog.Fatal(err) + } + klog.Infoln("registerMapper finished") + } + go panel.DevStart() + + httpServer := httpserver.NewRestServer(panel) + go httpServer.StartServer() + + defer grpcServer.Stop() + if err = grpcServer.Start(); err != nil { + klog.Fatal(err) + } +} diff --git a/mappers/kubeedge-v1.15.0/modbus/config.yaml b/mappers/kubeedge-v1.15.0/modbus/config.yaml new file mode 100644 index 00000000..17945135 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/config.yaml @@ -0,0 +1,12 @@ +grpc_server: + socket_path: /etc/kubeedge/modbus.sock +common: + name: Modbus-mapper + version: v1.13.0 + api_version: v1.0.0 + protocol: modbus # TODO add your protocol name + address: 127.0.0.1 + edgecore_sock: /etc/kubeedge/dmi.sock +dev_init: + mode: register + diff --git a/mappers/kubeedge-v1.15.0/modbus/data/dbmethod/influxdb2/client.go b/mappers/kubeedge-v1.15.0/modbus/data/dbmethod/influxdb2/client.go new file mode 100644 index 00000000..626886aa --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/data/dbmethod/influxdb2/client.go @@ -0,0 +1,76 @@ +package influxdb2 + +import ( + "context" + "encoding/json" + "os" + "time" + + "k8s.io/klog/v2" + + influxdb2 "github.com/influxdata/influxdb-client-go/v2" + "github.com/kubeedge/modbus/pkg/common" +) + +type DataBaseConfig struct { + Influxdb2ClientConfig *Influxdb2ClientConfig `json:"influxdb2ClientConfig,omitempty"` + Influxdb2DataConfig *Influxdb2DataConfig `json:"influxdb2DataConfig,omitempty"` +} + +type Influxdb2ClientConfig struct { + Url string `json:"url,omitempty"` + Org string `json:"org,omitempty"` + Bucket string `json:"bucket,omitempty"` +} + +type Influxdb2DataConfig struct { + Measurement string `json:"measurement,omitempty"` + Tag map[string]string `json:"tag,omitempty"` + FieldKey string `json:"fieldKey,omitempty"` +} + +func NewDataBaseClient(clientConfig json.RawMessage, dataConfig json.RawMessage) (*DataBaseConfig, error) { + // parse influx database config data + influxdb2ClientConfig := new(Influxdb2ClientConfig) + influxdb2DataConfig := new(Influxdb2DataConfig) + err := json.Unmarshal(clientConfig, influxdb2ClientConfig) + if err != nil { + return nil, err + } + err = json.Unmarshal(dataConfig, influxdb2DataConfig) + if err != nil { + return nil, err + } + return &DataBaseConfig{ + Influxdb2ClientConfig: influxdb2ClientConfig, + Influxdb2DataConfig: influxdb2DataConfig, + }, nil +} + +func (d *DataBaseConfig) InitDbClient() influxdb2.Client { + var usrtoken string + usrtoken = os.Getenv("TOKEN") + client := influxdb2.NewClient(d.Influxdb2ClientConfig.Url, usrtoken) + + return client +} + +func (d *DataBaseConfig) CloseSession(client influxdb2.Client) { + client.Close() +} + +func (d *DataBaseConfig) AddData(data *common.DataModel, client influxdb2.Client) error { + // write device data to influx database + writeAPI := client.WriteAPIBlocking(d.Influxdb2ClientConfig.Org, d.Influxdb2ClientConfig.Bucket) + p := influxdb2.NewPoint(d.Influxdb2DataConfig.Measurement, + d.Influxdb2DataConfig.Tag, + map[string]interface{}{d.Influxdb2DataConfig.FieldKey: data.Value}, + time.Now()) + // write point immediately + err := writeAPI.WritePoint(context.Background(), p) + if err != nil { + klog.V(4).Info("Exit AddData") + return err + } + return nil +} diff --git a/mappers/kubeedge-v1.15.0/modbus/data/publish/http/client.go b/mappers/kubeedge-v1.15.0/modbus/data/publish/http/client.go new file mode 100644 index 00000000..803efe4d --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/data/publish/http/client.go @@ -0,0 +1,73 @@ +package http + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strconv" + "strings" + "time" + + "k8s.io/klog/v2" + + "github.com/kubeedge/modbus/pkg/common" + "github.com/kubeedge/modbus/pkg/global" +) + +type PushMethod struct { + HTTP *HTTPConfig `json:"http"` +} + +type HTTPConfig struct { + HostName string `json:"hostName,omitempty"` + Port int `json:"port,omitempty"` + RequestPath string `json:"requestPath,omitempty"` + Timeout int `json:"timeout,omitempty"` +} + +func NewDataPanel(config json.RawMessage) (global.DataPanel, error) { + httpConfig := new(HTTPConfig) + err := json.Unmarshal(config, httpConfig) + if err != nil { + return nil, err + } + return &PushMethod{ + HTTP: httpConfig, + }, nil +} + +func (pm *PushMethod) InitPushMethod() error { + klog.V(1).Info("Init HTTP") + return nil +} + +func (pm *PushMethod) Push(data *common.DataModel) { + klog.V(2).Info("Publish device data by HTTP") + + targetUrl := pm.HTTP.HostName + ":" + strconv.Itoa(pm.HTTP.Port) + pm.HTTP.RequestPath + payload := data.PropertyName + "=" + data.Value + formatTimeStr := time.Unix(data.TimeStamp/1e3, 0).Format("2006-01-02 15:04:05") + currentTime := "&time" + "=" + formatTimeStr + payload += currentTime + + klog.V(3).Infof("Publish %v to %s", payload, targetUrl) + + resp, err := http.Post(targetUrl, + "application/x-www-form-urlencoded", + strings.NewReader(payload)) + + if err != nil { + fmt.Println(err) + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + // handle error + klog.Errorf("Publish device data by HTTP failed, err = %v", err) + return + } + klog.V(1).Info("############### Message published. ###############") + klog.V(3).Infof("HTTP reviced %s", string(body)) + +} diff --git a/mappers/kubeedge-v1.15.0/modbus/data/publish/mqtt/client.go b/mappers/kubeedge-v1.15.0/modbus/data/publish/mqtt/client.go new file mode 100644 index 00000000..8726a4dc --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/data/publish/mqtt/client.go @@ -0,0 +1,63 @@ +package mqtt + +import ( + "encoding/json" + "fmt" + "os" + "time" + + mqtt "github.com/eclipse/paho.mqtt.golang" + "k8s.io/klog/v2" + + "github.com/kubeedge/modbus/pkg/common" + "github.com/kubeedge/modbus/pkg/global" +) + +type PushMethod struct { + MQTT *MQTTConfig `json:"http"` +} + +type MQTTConfig struct { + Address string `json:"address,omitempty"` + Topic string `json:"topic,omitempty"` + QoS int `json:"qos,omitempty"` + Retained bool `json:"retained,omitempty"` +} + +func NewDataPanel(config json.RawMessage) (global.DataPanel, error) { + mqttConfig := new(MQTTConfig) + err := json.Unmarshal(config, mqttConfig) + if err != nil { + return nil, err + } + return &PushMethod{ + MQTT: mqttConfig, + }, nil +} + +func (pm *PushMethod) InitPushMethod() error { + klog.V(1).Info("Init MQTT") + return nil +} + +func (pm *PushMethod) Push(data *common.DataModel) { + klog.V(1).Infof("Publish %v to %s on topic: %s, Qos: %d, Retained: %v", + data.Value, pm.MQTT.Address, pm.MQTT.Topic, pm.MQTT.QoS, pm.MQTT.Retained) + + opts := mqtt.NewClientOptions().AddBroker(pm.MQTT.Address) + client := mqtt.NewClient(opts) + + if token := client.Connect(); token.Wait() && token.Error() != nil { + fmt.Println(token.Error()) + os.Exit(1) + } + formatTimeStr := time.Unix(data.TimeStamp/1e3, 0).Format("2006-01-02 15:04:05") + str_time := "time is " + formatTimeStr + " " + str_publish := str_time + pm.MQTT.Topic + ": " + data.Value + + token := client.Publish(pm.MQTT.Topic, byte(pm.MQTT.QoS), pm.MQTT.Retained, str_publish) + token.Wait() + + client.Disconnect(250) + klog.V(2).Info("############### Message published. ###############") +} diff --git a/mappers/kubeedge-v1.15.0/modbus/device/device.go b/mappers/kubeedge-v1.15.0/modbus/device/device.go new file mode 100644 index 00000000..109174f9 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/device/device.go @@ -0,0 +1,483 @@ +package device + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "os" + "os/signal" + "strings" + "sync" + "time" + + "k8s.io/klog/v2" + + dbInflux "github.com/kubeedge/modbus/data/dbmethod/influxdb2" + httpMethod "github.com/kubeedge/modbus/data/publish/http" + mqttMethod "github.com/kubeedge/modbus/data/publish/mqtt" + "github.com/kubeedge/modbus/driver" + "github.com/kubeedge/modbus/pkg/common" + "github.com/kubeedge/modbus/pkg/config" + "github.com/kubeedge/modbus/pkg/global" + "github.com/kubeedge/modbus/pkg/util/parse" +) + +type DevPanel struct { + deviceMuxs map[string]context.CancelFunc + devices map[string]*driver.CustomizedDev + models map[string]common.DeviceModel + protocols map[string]common.ProtocolConfig + wg sync.WaitGroup + serviceMutex sync.Mutex + quitChan chan os.Signal +} + +var ( + devPanel *DevPanel + once sync.Once +) + +// NewDevPanel init and return devPanel +func NewDevPanel() *DevPanel { + once.Do(func() { + devPanel = &DevPanel{ + deviceMuxs: make(map[string]context.CancelFunc), + devices: make(map[string]*driver.CustomizedDev), + models: make(map[string]common.DeviceModel), + protocols: make(map[string]common.ProtocolConfig), + wg: sync.WaitGroup{}, + serviceMutex: sync.Mutex{}, + quitChan: make(chan os.Signal), + } + }) + return devPanel +} + +// DevStart start all devices. +func (d *DevPanel) DevStart() { + for id, dev := range d.devices { + klog.V(4).Info("Dev: ", id, dev) + ctx, cancel := context.WithCancel(context.Background()) + d.deviceMuxs[id] = cancel + d.wg.Add(1) + go d.start(ctx, dev) + } + signal.Notify(d.quitChan, os.Interrupt) + go func() { + <-d.quitChan + for id, device := range d.devices { + err := device.CustomizedClient.StopDevice() + if err != nil { + klog.Errorf("Service has stopped but failed to stop %s:%v", id, err) + } + } + klog.V(1).Info("Exit mapper") + os.Exit(1) + }() + d.wg.Wait() +} + +// start the device +func (d *DevPanel) start(ctx context.Context, dev *driver.CustomizedDev) { + defer d.wg.Done() + + var protocolConfig driver.ProtocolConfig + if err := json.Unmarshal(dev.Instance.PProtocol.ConfigData, &protocolConfig); err != nil { + klog.Errorf("Unmarshal ProtocolConfigs error: %v", err) + return + } + client, err := driver.NewClient(protocolConfig) + if err != nil { + klog.Errorf("Init dev %s error: %v", dev.Instance.Name, err) + return + } + dev.CustomizedClient = client + err = dev.CustomizedClient.InitDevice() + if err != nil { + klog.Errorf("Init device %s error: %v", dev.Instance.ID, err) + return + } + go dataHandler(ctx, dev) + <-ctx.Done() +} + +// dataHandler initialize the timer to handle data plane and devicetwin. +func dataHandler(ctx context.Context, dev *driver.CustomizedDev) { + for _, twin := range dev.Instance.Twins { + twin.Property.PProperty.DataType = strings.ToLower(twin.Property.PProperty.DataType) + var visitorConfig driver.VisitorConfig + + err := json.Unmarshal(twin.Property.Visitors, &visitorConfig) + visitorConfig.VisitorConfigData.DataType = strings.ToLower(visitorConfig.VisitorConfigData.DataType) + if err != nil { + klog.Errorf("Unmarshal VisitorConfig error: %v", err) + continue + } + err = setVisitor(&visitorConfig, &twin, dev) + if err != nil { + klog.Error(err) + continue + } + // handle twin + twinData := &TwinData{ + DeviceName: dev.Instance.Name, + Client: dev.CustomizedClient, + Name: twin.PropertyName, + Type: twin.ObservedDesired.Metadata.Type, + ObservedDesired: twin.ObservedDesired, + VisitorConfig: &visitorConfig, + Topic: fmt.Sprintf(common.TopicTwinUpdate, dev.Instance.ID), + CollectCycle: time.Duration(twin.Property.CollectCycle), + ReportToCloud: twin.Property.ReportToCloud, + } + go twinData.Run(ctx) + // handle push method + if twin.Property.PushMethod.MethodConfig != nil && twin.Property.PushMethod.MethodName != "" { + dataModel := common.NewDataModel(dev.Instance.Name, twin.Property.PropertyName, common.WithType(twin.ObservedDesired.Metadata.Type)) + pushHandler(ctx, &twin, dev.CustomizedClient, &visitorConfig, dataModel) + } + // handle database + if twin.Property.PushMethod.DBMethod.DBMethodName != "" { + dataModel := common.NewDataModel(dev.Instance.Name, twin.Property.PropertyName, common.WithType(twin.ObservedDesired.Metadata.Type)) + dbHandler(ctx, &twin, dev.CustomizedClient, &visitorConfig, dataModel) + } + } +} + +// pushHandler start data panel work +func pushHandler(ctx context.Context, twin *common.Twin, client *driver.CustomizedClient, visitorConfig *driver.VisitorConfig, dataModel *common.DataModel) { + var dataPanel global.DataPanel + var err error + // initialization dataPanel + switch twin.Property.PushMethod.MethodName { + case "http": + dataPanel, err = httpMethod.NewDataPanel(twin.Property.PushMethod.MethodConfig) + case "mqtt": + dataPanel, err = mqttMethod.NewDataPanel(twin.Property.PushMethod.MethodConfig) + default: + err = errors.New("custom protocols are not currently supported when push data") + } + if err != nil { + klog.Errorf("new data panel error: %v", err) + return + } + // initialization PushMethod + err = dataPanel.InitPushMethod() + if err != nil { + klog.Errorf("init publish method err: %v", err) + return + } + reportCycle := time.Duration(twin.Property.ReportCycle) + if reportCycle == 0 { + reportCycle = 1 * time.Second + } + ticker := time.NewTicker(reportCycle) + go func() { + for { + select { + case <-ticker.C: + deviceData, err := client.GetDeviceData(visitorConfig) + if err != nil { + klog.Errorf("publish error: %v", err) + continue + } + sData, err := common.ConvertToString(deviceData) + if err != nil { + klog.Errorf("Failed to convert publish method data : %v", err) + continue + } + dataModel.SetValue(sData) + dataModel.SetTimeStamp() + dataPanel.Push(dataModel) + case <-ctx.Done(): + return + } + } + }() +} + +// dbHandler start db client to save data +func dbHandler(ctx context.Context, twin *common.Twin, client *driver.CustomizedClient, visitorConfig *driver.VisitorConfig, dataModel *common.DataModel) { + switch twin.Property.PushMethod.DBMethod.DBMethodName { + // TODO add more database + case "influx": + dbConfig, err := dbInflux.NewDataBaseClient(twin.Property.PushMethod.DBMethod.DBConfig.Influxdb2ClientConfig, twin.Property.PushMethod.DBMethod.DBConfig.Influxdb2DataConfig) + if err != nil { + klog.Errorf("new database client error: %v", err) + return + } + dbClient := dbConfig.InitDbClient() + if err != nil { + klog.Errorf("init database client err: %v", err) + return + } + reportCycle := time.Duration(twin.Property.ReportCycle) + if reportCycle == 0 { + reportCycle = 1 * time.Second + } + ticker := time.NewTicker(reportCycle) + go func() { + for { + select { + case <-ticker.C: + deviceData, err := client.GetDeviceData(visitorConfig) + if err != nil { + klog.Errorf("publish error: %v", err) + continue + } + sData, err := common.ConvertToString(deviceData) + if err != nil { + klog.Errorf("Failed to convert publish method data : %v", err) + continue + } + dataModel.SetValue(sData) + dataModel.SetTimeStamp() + + err = dbConfig.AddData(dataModel, dbClient) + if err != nil { + klog.Errorf("influx database add data error: %v", err) + return + } + case <-ctx.Done(): + dbConfig.CloseSession(dbClient) + return + } + } + }() + } +} + +// setVisitor check if visitor property is readonly, if not then set it. +func setVisitor(visitorConfig *driver.VisitorConfig, twin *common.Twin, dev *driver.CustomizedDev) error { + if twin.Property.PProperty.AccessMode == "ReadOnly" { + klog.V(3).Infof("%s twin readonly property: %s", dev.Instance.Name, twin.PropertyName) + return nil + } + klog.V(2).Infof("Convert type: %s, value: %s ", twin.Property.PProperty.DataType, twin.ObservedDesired.Value) + value, err := common.Convert(twin.Property.PProperty.DataType, twin.ObservedDesired.Value) + if err != nil { + klog.Errorf("Failed to convert value as %s : %v", twin.Property.PProperty.DataType, err) + return err + } + err = dev.CustomizedClient.SetDeviceData(value, visitorConfig) + if err != nil { + return fmt.Errorf("%s set device data error: %v", twin.PropertyName, err) + } + return nil +} + +// DevInit initialize the device +func (d *DevPanel) DevInit(cfg *config.Config) error { + devs := make(map[string]*common.DeviceInstance) + + switch cfg.DevInit.Mode { + //case common.DevInitModeConfigmap: + // if err := parse.Parse(cfg.DevInit.Configmap, devs, d.models, d.protocols); err != nil { + // return err + // } + case common.DevInitModeRegister: + if err := parse.ParseByUsingRegister(devs, d.models, d.protocols); err != nil { + return err + } + } + + for key, deviceInstance := range devs { + cur := new(driver.CustomizedDev) + cur.Instance = *deviceInstance + d.devices[key] = cur + } + return nil +} + +// UpdateDev stop old device, then update and start new device +func (d *DevPanel) UpdateDev(model *common.DeviceModel, device *common.DeviceInstance, protocol *common.ProtocolConfig) { + d.serviceMutex.Lock() + defer d.serviceMutex.Unlock() + + if oldDevice, ok := d.devices[device.ID]; ok { + err := d.stopDev(oldDevice, device.ID) + if err != nil { + klog.Error(err) + } + } + // start new device + d.devices[device.ID] = new(driver.CustomizedDev) + d.devices[device.ID].Instance = *device + d.models[device.ID] = *model + d.protocols[device.ID] = *protocol + + ctx, cancelFunc := context.WithCancel(context.Background()) + d.deviceMuxs[device.ID] = cancelFunc + d.wg.Add(1) + go d.start(ctx, d.devices[device.ID]) +} + +// UpdateDevTwins update device's twins +func (d *DevPanel) UpdateDevTwins(deviceID string, twins []common.Twin) error { + d.serviceMutex.Lock() + defer d.serviceMutex.Unlock() + dev, ok := d.devices[deviceID] + if !ok { + return fmt.Errorf("device %s not found", deviceID) + } + dev.Instance.Twins = twins + model := d.models[dev.Instance.Model] + protocol := d.protocols[dev.Instance.ProtocolName] + d.UpdateDev(&model, &dev.Instance, &protocol) + return nil +} + +// DealDeviceTwinGet get device's twin data +func (d *DevPanel) DealDeviceTwinGet(deviceID string, twinName string) (interface{}, error) { + d.serviceMutex.Lock() + defer d.serviceMutex.Unlock() + dev, ok := d.devices[deviceID] + if !ok { + return nil, fmt.Errorf("not found device %s", deviceID) + } + var res []parse.TwinResultResponse + for _, twin := range dev.Instance.Twins { + if twinName != "" && twin.PropertyName != twinName { + continue + } + payload, err := getTwinData(deviceID, twin, d.devices[deviceID]) + if err != nil { + return nil, err + } + item := parse.TwinResultResponse{ + PropertyName: twinName, + Payload: payload, + } + res = append(res, item) + } + return json.Marshal(res) +} + +// getTwinData get twin +func getTwinData(deviceID string, twin common.Twin, dev *driver.CustomizedDev) ([]byte, error) { + var visitorConfig driver.VisitorConfig + err := json.Unmarshal(twin.Property.Visitors, &visitorConfig) + if err != nil { + return nil, err + } + err = setVisitor(&visitorConfig, &twin, dev) + if err != nil { + return nil, err + } + twinData := &TwinData{ + DeviceName: deviceID, + Client: dev.CustomizedClient, + Name: twin.PropertyName, + Type: twin.ObservedDesired.Metadata.Type, + VisitorConfig: &visitorConfig, + Topic: fmt.Sprintf(common.TopicTwinUpdate, deviceID), + } + return twinData.GetPayLoad() +} + +// GetDevice get device instance +func (d *DevPanel) GetDevice(deviceID string) (interface{}, error) { + d.serviceMutex.Lock() + defer d.serviceMutex.Unlock() + found, ok := d.devices[deviceID] + if !ok || found == nil { + return nil, fmt.Errorf("device %s not found", deviceID) + } + + // get the latest reported twin value + for i, twin := range found.Instance.Twins { + payload, err := getTwinData(deviceID, twin, found) + if err != nil { + return nil, err + } + found.Instance.Twins[i].Reported.Value = string(payload) + } + return found, nil +} + +// RemoveDevice remove device instance +func (d *DevPanel) RemoveDevice(deviceID string) error { + d.serviceMutex.Lock() + defer d.serviceMutex.Unlock() + dev := d.devices[deviceID] + delete(d.devices, deviceID) + err := d.stopDev(dev, deviceID) + if err != nil { + return err + } + return nil +} + +// stopDev stop device and goroutine +func (d *DevPanel) stopDev(dev *driver.CustomizedDev, id string) error { + cancelFunc, ok := d.deviceMuxs[id] + if !ok { + return fmt.Errorf("can not find device %s from device muxs", id) + } + + err := dev.CustomizedClient.StopDevice() + if err != nil { + klog.Errorf("stop device %s error: %v", id, err) + } + cancelFunc() + return nil +} + +// GetModel if the model exists, return device model +func (d *DevPanel) GetModel(modelName string) (common.DeviceModel, error) { + d.serviceMutex.Lock() + defer d.serviceMutex.Unlock() + if model, ok := d.models[modelName]; ok { + return model, nil + } + return common.DeviceModel{}, fmt.Errorf("deviceModel %s not found", modelName) +} + +// UpdateModel update device model +func (d *DevPanel) UpdateModel(model *common.DeviceModel) { + d.serviceMutex.Lock() + d.models[model.Name] = *model + d.serviceMutex.Unlock() +} + +// RemoveModel remove device model +func (d *DevPanel) RemoveModel(modelName string) { + d.serviceMutex.Lock() + delete(d.models, modelName) + d.serviceMutex.Unlock() +} + +// GetTwinResult Get twin's value and data type +func (d *DevPanel) GetTwinResult(deviceID string, twinName string) (string, string, error) { + d.serviceMutex.Lock() + defer d.serviceMutex.Unlock() + dev, ok := d.devices[deviceID] + if !ok { + return "", "", fmt.Errorf("not found device %s", deviceID) + } + var res string + var dataType string + for _, twin := range dev.Instance.Twins { + if twinName != "" && twin.PropertyName != twinName { + continue + } + var visitorConfig driver.VisitorConfig + err := json.Unmarshal(twin.Property.Visitors, &visitorConfig) + if err != nil { + return "", "", err + } + err = setVisitor(&visitorConfig, &twin, dev) + + data, err := dev.CustomizedClient.GetDeviceData(&visitorConfig) + if err != nil { + return "", "", fmt.Errorf("get device data failed: %v", err) + } + res, err = common.ConvertToString(data) + if err != nil { + return "", "", err + } + dataType = twin.Property.PProperty.DataType + } + return res, dataType, nil +} diff --git a/mappers/kubeedge-v1.15.0/modbus/device/devicetwin.go b/mappers/kubeedge-v1.15.0/modbus/device/devicetwin.go new file mode 100644 index 00000000..bd5a2d9a --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/device/devicetwin.go @@ -0,0 +1,106 @@ +package device + +import ( + "context" + "encoding/json" + "fmt" + "strings" + "time" + + "k8s.io/klog/v2" + + "github.com/kubeedge/modbus/driver" + "github.com/kubeedge/modbus/pkg/common" + dmiapi "github.com/kubeedge/modbus/pkg/dmi-api" + "github.com/kubeedge/modbus/pkg/grpcclient" + "github.com/kubeedge/modbus/pkg/util/parse" +) + +type TwinData struct { + DeviceName string + Client *driver.CustomizedClient + Name string + Type string + ObservedDesired common.TwinProperty + VisitorConfig *driver.VisitorConfig + Topic string + Results interface{} + CollectCycle time.Duration + ReportToCloud bool +} + +func (td *TwinData) GetPayLoad() ([]byte, error) { + var err error + td.VisitorConfig.VisitorConfigData.DataType = strings.ToLower(td.VisitorConfig.VisitorConfigData.DataType) + td.Results, err = td.Client.GetDeviceData(td.VisitorConfig) + if err != nil { + return nil, fmt.Errorf("get device data failed: %v", err) + } + sData, err := common.ConvertToString(td.Results) + if err != nil { + klog.Errorf("Failed to convert %s %s value as string : %v", td.DeviceName, td.Name, err) + return nil, err + } + if len(sData) > 30 { + klog.V(4).Infof("Get %s : %s ,value is %s......", td.DeviceName, td.Name, sData[:30]) + } else { + klog.V(4).Infof("Get %s : %s ,value is %s", td.DeviceName, td.Name, sData) + } + var payload []byte + if strings.Contains(td.Topic, "$hw") { + if payload, err = common.CreateMessageTwinUpdate(td.Name, td.Type, sData, td.ObservedDesired.Value); err != nil { + return nil, fmt.Errorf("create message twin update failed: %v", err) + } + } else { + if payload, err = common.CreateMessageData(td.Name, td.Type, sData); err != nil { + return nil, fmt.Errorf("create message data failed: %v", err) + } + } + return payload, nil +} + +func (td *TwinData) PushToEdgeCore() { + payload, err := td.GetPayLoad() + if err != nil { + klog.Errorf("twindata %s unmarshal failed, err: %s", td.Name, err) + return + } + + var msg common.DeviceTwinUpdate + if err = json.Unmarshal(payload, &msg); err != nil { + klog.Errorf("twindata %s unmarshal failed, err: %s", td.Name, err) + return + } + + twins := parse.ConvMsgTwinToGrpc(msg.Twin) + + var rdsr = &dmiapi.ReportDeviceStatusRequest{ + DeviceName: td.DeviceName, + ReportedDevice: &dmiapi.DeviceStatus{ + Twins: twins, + //State: "OK", + }, + } + + if err := grpcclient.ReportDeviceStatus(rdsr); err != nil { + klog.Errorf("fail to report device status of %s with err: %+v", rdsr.DeviceName, err) + } +} + +func (td *TwinData) Run(ctx context.Context) { + if !td.ReportToCloud { + return + } + if td.CollectCycle == 0 { + td.CollectCycle = 1 * time.Second + } + ticker := time.NewTicker(td.CollectCycle) + for { + select { + case <-ticker.C: + td.PushToEdgeCore() + case <-ctx.Done(): + return + } + } +} diff --git a/mappers/kubeedge-v1.15.0/modbus/driver/devicetype.go b/mappers/kubeedge-v1.15.0/modbus/driver/devicetype.go new file mode 100644 index 00000000..5fc4aa84 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/driver/devicetype.go @@ -0,0 +1,66 @@ +package driver + +import ( + "sync" + "time" + + "github.com/sailorvii/modbus" + + "github.com/kubeedge/modbus/pkg/common" +) + +// CustomizedDev is the customized device configuration and client information. +type CustomizedDev struct { + Instance common.DeviceInstance + CustomizedClient *CustomizedClient +} + +type CustomizedClient struct { + // TODO add some variables to help you better implement device drivers + deviceMutex sync.Mutex + ProtocolConfig + ModbusProtocolConfig + ModbusClient modbus.Client +} + +type ProtocolConfig struct { + ProtocolName string `json:"protocolName"` + ConfigData `json:"configData"` +} + +type ConfigData struct { + // TODO: add your protocol config data + SlaveID byte + SerialPort string + BaudRate int + DataBits int + StopBits int + Parity string + Timeout int +} + +type ModbusProtocolConfig struct { + SlaveID byte + SerialPort string + BaudRate int + DataBits int + StopBits int + Parity string + Timeout time.Duration +} + +type VisitorConfig struct { + ProtocolName string `json:"protocolName"` + VisitorConfigData `json:"configData"` +} + +type VisitorConfigData struct { + // TODO: add your visitor config data + DataType string `json:"dataType"` + Register string `json:"register"` + Offset uint16 `json:"offset"` + Limit int `json:"limit"` + Scale float64 `json:"scale,omitempty"` + IsSwap bool `json:"isSwap,omitempty"` + IsRegisterSwap bool `json:"isRegisterSwap,omitempty"` +} diff --git a/mappers/kubeedge-v1.15.0/modbus/driver/driver.go b/mappers/kubeedge-v1.15.0/modbus/driver/driver.go new file mode 100644 index 00000000..23940756 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/driver/driver.go @@ -0,0 +1,146 @@ +package driver + +import ( + "errors" + "sync" + "time" + + "github.com/sailorvii/modbus" + "k8s.io/klog/v2" +) + +var clients *sync.Map + +var clientInit sync.Once + +func initMap() { + clientInit.Do(func() { + if clients == nil { + clients = new(sync.Map) + } + }) +} + +func NewClient(protocol ProtocolConfig) (*CustomizedClient, error) { + modbusProtocolConfig := ModbusProtocolConfig{ + SlaveID: protocol.SlaveID, + SerialPort: protocol.SerialPort, + BaudRate: protocol.BaudRate, + DataBits: protocol.DataBits, + StopBits: protocol.StopBits, + Parity: protocol.Parity, + Timeout: time.Duration(protocol.Timeout), + } + client := &CustomizedClient{ + ProtocolConfig: protocol, + deviceMutex: sync.Mutex{}, + ModbusProtocolConfig: modbusProtocolConfig, + } + return client, nil +} + +func (c *CustomizedClient) InitDevice() error { + // TODO: add init operation + // you can use c.ProtocolConfig + initMap() + klog.Infoln("SerialPort : ", c.ModbusProtocolConfig.SerialPort) + v, ok := clients.Load(c.ModbusProtocolConfig.SerialPort) + if ok { + c.ModbusClient = v.(modbus.Client) + return nil + } + + handler := modbus.NewRTUClientHandler(c.ModbusProtocolConfig.SerialPort) + handler.BaudRate = c.ModbusProtocolConfig.BaudRate + handler.DataBits = c.ModbusProtocolConfig.DataBits + handler.Parity = parity(c.ModbusProtocolConfig.Parity) + handler.StopBits = c.ModbusProtocolConfig.StopBits + handler.SlaveId = c.ModbusProtocolConfig.SlaveID + handler.Timeout = c.ModbusProtocolConfig.Timeout + handler.IdleTimeout = c.ModbusProtocolConfig.Timeout + client := modbus.NewClient(handler) + clients.Store(c.ModbusProtocolConfig.SerialPort, &client) + c.ModbusClient = client + + return nil +} + +func (c *CustomizedClient) GetDeviceData(visitor *VisitorConfig) (interface{}, error) { + // TODO: add the code to get device's data + // you can use c.ProtocolConfig and visitor + c.deviceMutex.Lock() + defer c.deviceMutex.Unlock() + + var results []byte + var err error + switch visitor.Register { + case "CoilRegister": + results, err = c.ModbusClient.ReadCoils(visitor.Offset, uint16(visitor.Limit)) + case "DiscreteInputRegister": + results, err = c.ModbusClient.ReadDiscreteInputs(visitor.Offset, uint16(visitor.Limit)) + case "HoldingRegister": + results, err = c.ModbusClient.ReadHoldingRegisters(visitor.Offset, uint16(visitor.Limit)) + case "InputRegister": + results, err = c.ModbusClient.ReadInputRegisters(visitor.Offset, uint16(visitor.Limit)) + default: + return nil, errors.New("Bad register type") + } + klog.V(2).Info("Get result: ", results) + return results, err +} + +func (c *CustomizedClient) SetDeviceData(data interface{}, visitor *VisitorConfig) error { + // TODO: set device's data + // you can use c.ProtocolConfig and visitor + var results []byte + var err error + + c.deviceMutex.Lock() + defer c.deviceMutex.Unlock() + + klog.V(1).Info("Set:", visitor.Register, visitor.Offset, uint16(visitor.Limit)) + + switch visitor.Register { + case "CoilRegister": + var valueSet uint16 + switch uint16(visitor.Limit) { + case 0: + valueSet = 0x0000 + case 1: + valueSet = 0xFF00 + default: + return errors.New("Wrong value") + } + results, err = c.ModbusClient.WriteSingleCoil(visitor.Offset, valueSet) + case "HoldingRegister": + results, err = c.ModbusClient.WriteSingleRegister(visitor.Offset, uint16(visitor.Limit)) + default: + return errors.New("Bad register type") + } + klog.V(1).Info("Set result:", err, results) + return nil +} + +func (c *CustomizedClient) StopDevice() error { + // TODO: stop device + // you can use c.ProtocolConfig + err := c.ModbusClient.Close() + if err != nil { + return err + } + return nil +} + +// parity convert into the format that modbus driver requires. +func parity(ori string) string { + var p string + switch ori { + case "even": + p = "E" + case "odd": + p = "O" + default: + p = "N" + } + return p +} diff --git a/mappers/kubeedge-v1.15.0/modbus/go.mod b/mappers/kubeedge-v1.15.0/modbus/go.mod new file mode 100644 index 00000000..03bfee2e --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/go.mod @@ -0,0 +1,33 @@ +module github.com/kubeedge/modbus + +go 1.17 + +require ( + github.com/golang/protobuf v1.5.2 + github.com/gorilla/mux v1.8.0 + github.com/sailorvii/modbus v0.1.2 + github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace + golang.org/x/net v0.8.0 // indirect + google.golang.org/grpc v1.47.0 + google.golang.org/protobuf v1.27.1 + gopkg.in/yaml.v2 v2.4.0 + k8s.io/klog/v2 v2.80.1 +) + +require ( + github.com/eclipse/paho.mqtt.golang v1.4.3 + github.com/influxdata/influxdb-client-go/v2 v2.12.3 +) + +require ( + github.com/deepmap/oapi-codegen v1.8.2 // indirect + github.com/go-logr/logr v1.2.0 // indirect + github.com/goburrow/serial v0.1.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect + github.com/pkg/errors v0.9.1 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect + google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect +) diff --git a/mappers/kubeedge-v1.15.0/modbus/go.sum b/mappers/kubeedge-v1.15.0/modbus/go.sum new file mode 100644 index 00000000..5a0fd6c4 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/go.sum @@ -0,0 +1,254 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= +github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik= +github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= +github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/goburrow/serial v0.1.0 h1:v2T1SQa/dlUqQiYIT8+Cu7YolfqAi3K96UmhwYyuSrA= +github.com/goburrow/serial v0.1.0/go.mod h1:sAiqG0nRVswsm1C97xsttiYCzSLBmUZ/VSlVLZJ8haA= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/influxdata/influxdb-client-go/v2 v2.12.3 h1:28nRlNMRIV4QbtIUvxhWqaxn0IpXeMSkY/uJa/O/vC4= +github.com/influxdata/influxdb-client-go/v2 v2.12.3/go.mod h1:IrrLUbCjjfkmRuaCiGQg4m2GbkaeJDcuWoxiWdQEbA0= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/sailorvii/modbus v0.1.2 h1:Btjqzck5qJAkVhvzRNYjeRirN1OZwNhbVWCe2alyuOw= +github.com/sailorvii/modbus v0.1.2/go.mod h1:7KS/EFWv2J88WuVRiI/WnttT2xO+R7DlvshfdBa2cSw= +github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace h1:9PNP1jnUjRhfmGMlkXHjYPishpcw4jpSt/V/xYY3FMA= +github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= diff --git a/mappers/kubeedge-v1.15.0/modbus/hack/make-rules/mapper.sh b/mappers/kubeedge-v1.15.0/modbus/hack/make-rules/mapper.sh new file mode 100644 index 00000000..4cba4250 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/hack/make-rules/mapper.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +CURR_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)" +ROOT_DIR="$(cd "${CURR_DIR}/../.." && pwd -P)" +source "${ROOT_DIR}/hack/lib/init.sh" + +mkdir -p "${CURR_DIR}/bin" +mkdir -p "${CURR_DIR}/dist" + +function mod() { + [[ "${2:-}" != "only" ]] + local mapper="${1}" + + # the mapper is sharing the vendor with root + pushd "${ROOT_DIR}" >/dev/null || exist 1 + echo "downloading dependencies for mapper ${mapper}..." + + if [[ "$(go env GO111MODULE)" == "off" ]]; then + echo "go mod has been disabled by GO111MODULE=off" + else + echo "tidying" + go mod tidy + echo "vending" + go mod vendor + fi + + echo "...done" + popd >/dev/null || return +} + +function lint() { + [[ "${2:-}" != "only" ]] && mod "$@" + local mapper="${1}" + + echo "fmt and linting mapper ${mapper}..." + + gofmt -s -w "${CURR_DIR}/" + golangci-lint run "${CURR_DIR}/..." + + echo "...done" +} + +function build() { + [[ "${2:-}" != "only" ]] && lint "$@" + local mapper="${1}" + + local flags=" -w -s " + local ext_flags=" -extldflags '-static' " + local os="${OS:-$(go env GOOS)}" + local arch="${ARCH:-$(go env GOARCH)}" + + local platform + if [[ "${ARM:-false}" == "true" ]]; then + echo "crossed packaging for linux/arm" + platform=("linux/arm") + elif [[ "${ARM64:-false}" == "true" ]]; then + echo "crossed packaging for linux/arm64" + platform=("linux/arm64") + else + local os="${OS:-$(go env GOOS)}" + local arch="${ARCH:-$(go env GOARCH)}" + platform=("${os}/${arch}") + fi + + echo "building ${platform}" + + local os_arch + IFS="/" read -r -a os_arch <<<"${platform}" + local os=${os_arch[0]} + local arch=${os_arch[1]} + GOOS=${os} GOARCH=${arch} CGO_ENABLED=0 go build \ + -ldflags "${flags} ${ext_flags}" \ + -o "${CURR_DIR}/bin/${mapper}_${os}_${arch}" \ + "${CURR_DIR}/cmd/main.go" + + cp ${CURR_DIR}/bin/${mapper}_${os}_${arch} ${CURR_DIR}/bin/${mapper} + echo "...done" +} + +function package() { + [[ "${2:-}" != "only" ]] && build "$@" + local mapper="${1}" + + echo "packaging mapper ${mapper}..." + + local image_name="${mapper}-mapper" + local tag=v1.0 + + local platform + if [[ "${ARM:-false}" == "true" ]]; then + echo "crossed packaging for linux/arm" + platform=("linux/arm") + elif [[ "${ARM64:-false}" == "true" ]]; then + echo "crossed packaging for linux/arm64" + platform=("linux/arm64") + else + local os="${OS:-$(go env GOOS)}" + local arch="${ARCH:-$(go env GOARCH)}" + platform=("${os}/${arch}") + fi + + pushd "${CURR_DIR}" >/dev/null 2>&1 + if [[ "${platform}" =~ darwin/* ]]; then + echo "package into Darwin OS image is unavailable, please use CROSS=true env to containerize multiple arch images or use OS=linux ARCH=amd64 env to containerize linux/amd64 image" + fi + + local image_tag="${image_name}:${tag}-${platform////-}" + echo "packaging ${image_tag}" + sudo docker build \ + --platform "${platform}" \ + -t "${image_tag}" . + popd >/dev/null 2>&1 + + echo "...done" +} + +function clean() { + local mapper="${1}" + + echo "cleanup mapper ${mapper}..." + + rm -rf "${CURR_DIR}/bin/*" + + echo "...done" +} + +function entry() { + local mapper="${1:-}" + shift 1 + + local stages="${1:-build}" + shift $(($# > 0 ? 1 : 0)) + + IFS="," read -r -a stages <<<"${stages}" + local commands=$* + if [[ ${#stages[@]} -ne 1 ]]; then + commands="only" + fi + + for stage in "${stages[@]}"; do + echo "# make mapper ${mapper} ${stage} ${commands}" + case ${stage} in + m | mod) mod "${mapper}" "${commands}" ;; + l | lint) lint "${mapper}" "${commands}" ;; + b | build) build "${mapper}" "${commands}" ;; + p | pkg | package) package "${mapper}" "${commands}" ;; + t | test) test "${mapper}" "${commands}" ;; + c | clean) clean "${mapper}" "${commands}" ;; + *) echo "unknown action '${stage}', select from mod,lint,build,test,clean" ;; + esac + done +} + +echo $@ +entry "$@" \ No newline at end of file diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/common/configmaptype.go b/mappers/kubeedge-v1.15.0/modbus/pkg/common/configmaptype.go new file mode 100644 index 00000000..0e8e756e --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/common/configmaptype.go @@ -0,0 +1,122 @@ +/* +Copyright 2023 The KubeEdge Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import "encoding/json" + +// DeviceProfile is structure to store in configMap. It will be removed later +type DeviceProfile struct { + DeviceInstances []DeviceInstance `json:"deviceInstances,omitempty"` + DeviceModels []DeviceModel `json:"deviceModels,omitempty"` + Protocols []ProtocolConfig `json:"protocols,omitempty"` +} + +// DeviceInstance is structure to store device in deviceProfile.json in configmap. +type DeviceInstance struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + ProtocolName string `json:"protocol,omitempty"` + PProtocol ProtocolConfig + Model string `json:"model,omitempty"` + Twins []Twin `json:"twins,omitempty"` + Properties []DeviceProperty `json:"properties,omitempty"` +} + +// DeviceModel is structure to store deviceModel in deviceProfile.json in configmap. +type DeviceModel struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Properties []ModelProperty `json:"properties,omitempty"` +} + +// ModelProperty is structure to store deviceModel property. +type ModelProperty struct { + Name string `json:"name,omitempty"` + DataType string `json:"dataType,omitempty"` + Description string `json:"description,omitempty"` + AccessMode string `json:"accessMode,omitempty"` + Minimum string `json:"minimum,omitempty"` + Maximum string `json:"maximum,omitempty"` + Unit string `json:"unit,omitempty"` +} + +// Protocol is structure to store protocol in deviceProfile.json in configmap. + +type ProtocolConfig struct { + // Unique protocol name + // Required. + ProtocolName string `json:"protocolName,omitempty"` + // Any config data + // +optional + // +kubebuilder:validation:XPreserveUnknownFields + ConfigData json.RawMessage `json:"configData,omitempty"` +} + +// DeviceProperty is structure to store propertyVisitor in deviceProfile.json in configmap. +type DeviceProperty struct { + Name string `json:"name,omitempty"` + PropertyName string `json:"propertyName,omitempty"` + ModelName string `json:"modelName,omitempty"` + Protocol string `json:"protocol,omitempty"` + Visitors json.RawMessage `json:"visitorConfig"` + // whether be reported to the cloud + ReportToCloud bool `json:"reportToCloud,omitempty"` + CollectCycle int64 `json:"collectCycle"` + ReportCycle int64 `json:"reportCycle,omitempty"` + PushMethod PushMethodConfig `json:"pushMethod,omitempty"` + PProperty ModelProperty +} + +// PushMethodConfig is structure to store push config +type PushMethodConfig struct { + MethodName string `json:"MethodName"` + MethodConfig json.RawMessage `json:"MethodConfig"` + DBMethod DBMethodConfig `json:"dbMethod,omitempty"` +} + +type DBMethodConfig struct { + DBMethodName string `json:"dbMethodName"` + DBConfig DBConfig `json:"dbConfig"` +} + +type DBConfig struct { + Influxdb2ClientConfig json.RawMessage `json:"influxdb2ClientConfig"` + Influxdb2DataConfig json.RawMessage `json:"influxdb2DataConfig"` + RedisConfigData json.RawMessage `json:"redisConfigData"` +} + +// Metadata is the metadata for data. +type Metadata struct { + Timestamp string `json:"timestamp,omitempty"` + Type string `json:"type,omitempty"` +} + +// Twin is the set/get pair to one register. +type Twin struct { + PropertyName string `json:"propertyName,omitempty"` + Property *DeviceProperty + ObservedDesired TwinProperty `json:"observedDesired,omitempty"` + Reported TwinProperty `json:"reported,omitempty"` +} + +type TwinProperty struct { + // Required: The value for this property. + Value string `json:"value,"` + // Additional metadata like timestamp when the value was reported etc. + // +optional + Metadata Metadata `json:"metadata,omitempty"` +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/common/const.go b/mappers/kubeedge-v1.15.0/modbus/pkg/common/const.go new file mode 100644 index 00000000..8daf3811 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/common/const.go @@ -0,0 +1,43 @@ +/* +Copyright 2023 The KubeEdge Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import "time" + +// Device status definition. +const ( + DEVSTOK = "OK" + DEVSTERR = "ERROR" /* Expected value is not equal as setting */ + DEVSTDISCONN = "DISCONNECTED" /* Disconnected */ + DEVSTUNHEALTHY = "UNHEALTHY" /* Unhealthy status from device */ + DEVSTUNKNOWN = "UNKNOWN" +) +const ( + ProtocolBlueTooth = "bluetooth" + ProtocolModbus = "modbus" + ProtocolOnvif = "onvif" + ProtocolOpcua = "opcua" + ProtocolCustomized = "customized-protocol" +) + +const DefaultCollectCycle = time.Second +const DefaultReportCycle = time.Second + +const ( + DevInitModeRegister = "register" + DevInitModeConfigmap = "configmap" +) diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/common/dataconverter.go b/mappers/kubeedge-v1.15.0/modbus/pkg/common/dataconverter.go new file mode 100644 index 00000000..f1c8c854 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/common/dataconverter.go @@ -0,0 +1,169 @@ +/* +Copyright 2023 The KubeEdge Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "encoding/json" + "errors" + "fmt" + "reflect" + "strconv" + "strings" + + "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" + "google.golang.org/protobuf/types/known/wrapperspb" +) + +// Convert string to other types +func Convert(valueType string, value string) (result interface{}, err error) { + switch valueType { + case "int": + return strconv.ParseInt(value, 10, 64) + case "float": + return strconv.ParseFloat(value, 32) + case "double": + return strconv.ParseFloat(value, 64) + case "boolean": + return strconv.ParseBool(value) + case "string": + return value, nil + default: + return nil, errors.New("Convert failed") + } +} + +// ConvertToString other types to string +func ConvertToString(value interface{}) (string, error) { + var result string + if value == nil { + return result, nil + } + switch v := value.(type) { + case float64: + ft := v + result = strconv.FormatFloat(ft, 'f', -1, 64) + case float32: + ft := v + result = strconv.FormatFloat(float64(ft), 'f', -1, 64) + case int: + it := v + result = strconv.Itoa(it) + case uint: + it := v + result = strconv.Itoa(int(it)) + case int8: + it := v + result = strconv.Itoa(int(it)) + case uint8: + it := v + result = strconv.Itoa(int(it)) + case int16: + it := v + result = strconv.Itoa(int(it)) + case uint16: + it := v + result = strconv.Itoa(int(it)) + case int32: + it := v + result = strconv.Itoa(int(it)) + case uint32: + it := v + result = strconv.Itoa(int(it)) + case int64: + it := v + result = strconv.FormatInt(it, 10) + case uint64: + it := v + result = strconv.FormatUint(it, 10) + case string: + result = v + case []byte: + result = string(v) + default: + newValue, err := json.Marshal(value) + if err != nil { + return "", err + } + result = string(newValue) + } + return result, nil +} + +// DecodeAnyValue Any to interface +func DecodeAnyValue(value *anypb.Any) (interface{}, error) { + typeURL := value.GetTypeUrl() + + messageTypeName := getMessageTypeName(typeURL) + if messageTypeName == "" { + return nil, fmt.Errorf("cant get message type:%s", typeURL) + } + if strings.Contains(messageTypeName, "google.protobuf.") { + switch messageTypeName { + case "google.protobuf.Int32Value": + return decodeWrapperValue(value, &wrapperspb.Int32Value{}) + case "google.protobuf.StringValue": + return decodeWrapperValue(value, &wrapperspb.StringValue{}) + case "google.protobuf.FloatValue": + return decodeWrapperValue(value, &wrapperspb.FloatValue{}) + case "google.protobuf.BoolValue": + return decodeWrapperValue(value, &wrapperspb.BoolValue{}) + case "google.protobuf.Int64Value": + return decodeWrapperValue(value, &wrapperspb.Int64Value{}) + default: + return nil, fmt.Errorf("unknown type : %s", messageTypeName) + } + } + messageType := proto.MessageType(messageTypeName) + if messageType == nil { + return nil, fmt.Errorf("cant get message type:%s", messageTypeName) + } + + if !reflect.TypeOf((*proto.Message)(nil)).Elem().AssignableTo(messageType) { + return nil, fmt.Errorf("assiganbleto proto.Message error:%s", messageTypeName) + } + message := reflect.New(messageType.Elem()).Interface().(proto.Message) + if err := proto.Unmarshal(value.Value, message); err != nil { + return nil, fmt.Errorf("unmarshal value error:%v", err) + } + return message, nil +} + +// decodeWrapperValue get proto.Message, then convert to interface +func decodeWrapperValue(value *anypb.Any, wrapper proto.Message) (interface{}, error) { + if err := proto.Unmarshal(value.Value, wrapper); err != nil { + return nil, fmt.Errorf("decode wrapperValue,proto unmarshal error:%v", err) + } + wrapperValue := reflect.ValueOf(wrapper).Elem() + valueField := wrapperValue.FieldByName("Value") + if !valueField.IsValid() { + return nil, fmt.Errorf("cant get wrapperValue") + } + return valueField.Interface(), nil +} + +// getMessageTypeName get type by parse type url +func getMessageTypeName(typeURL string) string { + index := len(typeURL) - 1 + for index >= 0 && typeURL[index] != '/' { + index-- + } + if index >= 0 && index < len(typeURL)-1 { + return typeURL[index+1:] + } + return "" +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/common/datamodel.go b/mappers/kubeedge-v1.15.0/modbus/pkg/common/datamodel.go new file mode 100644 index 00000000..effd2739 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/common/datamodel.go @@ -0,0 +1,57 @@ +package common + +// DataModel defined standard data model for transferring data between interfaces +type DataModel struct { + // TODO DataModel is standardized data, need add field + DeviceName string + PropertyName string + + Value string + Type string + + TimeStamp int64 +} + +type Option func(*DataModel) + +func (dm *DataModel) SetType(dataType string) { + dm.Type = dataType +} + +func (dm *DataModel) SetValue(data string) { + dm.Value = data +} + +func (dm *DataModel) SetTimeStamp() { + dm.TimeStamp = getTimestamp() +} + +func WithType(dataType string) Option { + return func(model *DataModel) { + model.Type = dataType + } +} + +func WithValue(data string) Option { + return func(model *DataModel) { + model.Value = data + } +} + +func WithTimeStamp(timeStamp int64) Option { + return func(model *DataModel) { + model.TimeStamp = timeStamp + } +} + +func NewDataModel(deviceName string, propertyName string, options ...Option) *DataModel { + dataModel := &DataModel{ + DeviceName: deviceName, + PropertyName: propertyName, + TimeStamp: getTimestamp(), + } + for _, option := range options { + option(dataModel) + } + return dataModel +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/common/event.go b/mappers/kubeedge-v1.15.0/modbus/pkg/common/event.go new file mode 100644 index 00000000..9820ecd9 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/common/event.go @@ -0,0 +1,65 @@ +/* +Copyright 2023 The KubeEdge Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "encoding/json" + "time" +) + +// Joint the topic like topic := fmt.Sprintf(TopicTwinUpdateDelta, deviceID) +const ( + TopicTwinUpdateDelta = "$hw/events/device/%s/twin/update/delta" + TopicTwinUpdate = "$hw/events/device/%s/twin/update" + TopicStateUpdate = "$hw/events/device/%s/state/update" + TopicDataUpdate = "$ke/events/device/%s/data/update" +) + +// getTimestamp get current timestamp. +func getTimestamp() int64 { + return time.Now().UnixNano() / 1e6 +} + +// CreateMessageTwinUpdate create twin update message. +func CreateMessageTwinUpdate(name string, valueType string, value string, expectValue string) (msg []byte, err error) { + var updateMsg DeviceTwinUpdate + + updateMsg.BaseMessage.Timestamp = getTimestamp() + updateMsg.Twin = map[string]*MsgTwin{} + updateMsg.Twin[name] = &MsgTwin{} + updateMsg.Twin[name].Actual = &TwinValue{Value: &value} + updateMsg.Twin[name].Expected = &TwinValue{Value: &expectValue} + updateMsg.Twin[name].Metadata = &TypeMetadata{Type: valueType} + + msg, err = json.Marshal(updateMsg) + return +} + +// CreateMessageData create data message. +func CreateMessageData(name string, valueType string, value string) (msg []byte, err error) { + var dataMsg DeviceData + + dataMsg.BaseMessage.Timestamp = getTimestamp() + dataMsg.Data = map[string]*DataValue{} + dataMsg.Data[name] = &DataValue{} + dataMsg.Data[name].Value = value + dataMsg.Data[name].Metadata.Type = valueType + dataMsg.Data[name].Metadata.Timestamp = getTimestamp() + + msg, err = json.Marshal(dataMsg) + return +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/common/eventtype.go b/mappers/kubeedge-v1.15.0/modbus/pkg/common/eventtype.go new file mode 100644 index 00000000..cf9fe8b3 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/common/eventtype.go @@ -0,0 +1,106 @@ +/* +Copyright 2023 The KubeEdge Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +// BaseMessage the base structure of event message. +type BaseMessage struct { + EventID string `json:"event_id"` + Timestamp int64 `json:"timestamp"` +} + +// TwinValue the structure of twin value. +type TwinValue struct { + Value *string `json:"value,omitempty"` + Metadata ValueMetadata `json:"metadata,omitempty"` +} + +// ValueMetadata the meta of value. +type ValueMetadata struct { + Timestamp string `json:"timestamp,omitempty"` +} + +// TypeMetadata the meta of value type. +type TypeMetadata struct { + Type string `json:"type,omitempty"` +} + +// TwinVersion twin version. +type TwinVersion struct { + CloudVersion int64 `json:"cloud"` + EdgeVersion int64 `json:"edge"` +} + +// MsgTwin the structure of device twin. +type MsgTwin struct { + Expected *TwinValue `json:"expected,omitempty"` + Actual *TwinValue `json:"actual,omitempty"` + Optional *bool `json:"optional,omitempty"` + Metadata *TypeMetadata `json:"metadata,omitempty"` + ExpectedVersion *TwinVersion `json:"expected_version,omitempty"` + ActualVersion *TwinVersion `json:"actual_version,omitempty"` +} + +// DeviceTwinUpdate the structure of device twin update. +type DeviceTwinUpdate struct { + BaseMessage + Twin map[string]*MsgTwin `json:"twin"` +} + +// DeviceTwinResult device get result. +type DeviceTwinResult struct { + BaseMessage + Twin map[string]*MsgTwin `json:"twin"` +} + +// DeviceTwinDelta twin delta. +type DeviceTwinDelta struct { + BaseMessage + Twin map[string]*MsgTwin `json:"twin"` + Delta map[string]string `json:"delta"` +} + +// DataMetadata data metadata. +type DataMetadata struct { + Timestamp int64 `json:"timestamp"` + Type string `json:"type"` +} + +// DataValue data value. +type DataValue struct { + Value string `json:"value"` + Metadata DataMetadata `json:"metadata"` +} + +// DeviceData device data structure. +type DeviceData struct { + BaseMessage + Data map[string]*DataValue `json:"data"` +} + +// MsgAttr the struct of device attr +type MsgAttr struct { + Value string `json:"value"` + Optional *bool `json:"optional,omitempty"` + Metadata *TypeMetadata `json:"metadata,omitempty"` +} + +// DeviceUpdate device update. +type DeviceUpdate struct { + BaseMessage + State string `json:"state,omitempty"` + Attributes map[string]*MsgAttr `json:"attributes"` +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/config/config.go b/mappers/kubeedge-v1.15.0/modbus/pkg/config/config.go new file mode 100644 index 00000000..76900d3c --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/config/config.go @@ -0,0 +1,99 @@ +/* +Copyright 2023 The KubeEdge Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +import ( + "errors" + "io/ioutil" + "os" + "strings" + + "github.com/spf13/pflag" + "gopkg.in/yaml.v2" + "k8s.io/klog/v2" + + "github.com/kubeedge/modbus/pkg/common" +) + +var defaultConfigFile = "./config.yaml" + +// Config is the common mapper configuration. +type Config struct { + GrpcServer GRPCServer `yaml:"grpc_server"` + Common Common `yaml:"common"` + DevInit DevInit `yaml:"dev_init"` +} + +type GRPCServer struct { + SocketPath string `yaml:"socket_path"` +} + +type Common struct { + Name string `yaml:"name"` + Version string `yaml:"version"` + APIVersion string `yaml:"api_version"` + Protocol string `yaml:"protocol"` + Address string `yaml:"address"` + EdgeCoreSock string `yaml:"edgecore_sock"` +} + +type DevInit struct { + Mode string `yaml:"mode"` + Configmap string `yaml:"configmap"` +} + +// Parse the configuration file. If failed, return error. +func (c *Config) Parse() error { + var level klog.Level + var loglevel string + var configFile string + + pflag.StringVar(&loglevel, "v", "1", "log level") + pflag.StringVar(&configFile, "config-file", defaultConfigFile, "Config file name") + pflag.Parse() + cf, err := ioutil.ReadFile(configFile) + if err != nil { + return err + } + if err = yaml.Unmarshal(cf, c); err != nil { + return err + } + if err = level.Set(loglevel); err != nil { + return err + } + + switch c.DevInit.Mode { + case common.DevInitModeConfigmap: + if _, err := ioutil.ReadFile(c.DevInit.Configmap); err != nil { + if !os.IsNotExist(err) { + return err + } + c.DevInit.Configmap = strings.TrimSpace(os.Getenv("DEVICE_PROFILE")) + } + if strings.TrimSpace(c.DevInit.Configmap) == "" { + return errors.New("can not parse configmap") + } + case common.DevInitModeRegister: + case "": // if mode is nil, use meta server mode + c.DevInit.Mode = common.DevInitModeRegister + fallthrough + default: + return errors.New("unsupported dev init mode " + c.DevInit.Mode) + } + + return nil +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/dmi-api/api.pb.go b/mappers/kubeedge-v1.15.0/modbus/pkg/dmi-api/api.pb.go new file mode 100644 index 00000000..19e252db --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/dmi-api/api.pb.go @@ -0,0 +1,3242 @@ +/* +Copyright 2022 The KubeEdge Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// +// To regenerate api.pb.go run hack/generate-dmi.sh + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.19.4 +// source: api.proto + +package v1beta1 + +import ( + "google.golang.org/grpc" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type MapperRegisterRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The flag to show how device manager returns. + // True means device manager should return the device list in the response. + // False means device manager should just return nothing. + WithData bool `protobuf:"varint,1,opt,name=withData,proto3" json:"withData,omitempty"` + // Mapper information to be registered to the device manager. + Mapper *MapperInfo `protobuf:"bytes,2,opt,name=mapper,proto3" json:"mapper,omitempty"` +} + +func (x *MapperRegisterRequest) Reset() { + *x = MapperRegisterRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MapperRegisterRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MapperRegisterRequest) ProtoMessage() {} + +func (x *MapperRegisterRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MapperRegisterRequest.ProtoReflect.Descriptor instead. +func (*MapperRegisterRequest) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{0} +} + +func (x *MapperRegisterRequest) GetWithData() bool { + if x != nil { + return x.WithData + } + return false +} + +func (x *MapperRegisterRequest) GetMapper() *MapperInfo { + if x != nil { + return x.Mapper + } + return nil +} + +type MapperRegisterResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // List of device models which the mapper maintains. + ModelList []*DeviceModel `protobuf:"bytes,1,rep,name=modelList,proto3" json:"modelList,omitempty"` + // List of devices which the mapper maintains. + DeviceList []*Device `protobuf:"bytes,2,rep,name=deviceList,proto3" json:"deviceList,omitempty"` +} + +func (x *MapperRegisterResponse) Reset() { + *x = MapperRegisterResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MapperRegisterResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MapperRegisterResponse) ProtoMessage() {} + +func (x *MapperRegisterResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MapperRegisterResponse.ProtoReflect.Descriptor instead. +func (*MapperRegisterResponse) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{1} +} + +func (x *MapperRegisterResponse) GetModelList() []*DeviceModel { + if x != nil { + return x.ModelList + } + return nil +} + +func (x *MapperRegisterResponse) GetDeviceList() []*Device { + if x != nil { + return x.DeviceList + } + return nil +} + +// DeviceModel specifies the information of a device model. +type DeviceModel struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of a device model. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Specification of a device model. + Spec *DeviceModelSpec `protobuf:"bytes,2,opt,name=spec,proto3" json:"spec,omitempty"` +} + +func (x *DeviceModel) Reset() { + *x = DeviceModel{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeviceModel) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceModel) ProtoMessage() {} + +func (x *DeviceModel) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceModel.ProtoReflect.Descriptor instead. +func (*DeviceModel) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{2} +} + +func (x *DeviceModel) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DeviceModel) GetSpec() *DeviceModelSpec { + if x != nil { + return x.Spec + } + return nil +} + +// DeviceModelSpec is the specification of a device model. +type DeviceModelSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The properties provided by the device of this device model. + Properties []*ModelProperty `protobuf:"bytes,1,rep,name=properties,proto3" json:"properties,omitempty"` + // The commands executed by the device of this device model. + Commands []*DeviceCommand `protobuf:"bytes,2,rep,name=commands,proto3" json:"commands,omitempty"` +} + +func (x *DeviceModelSpec) Reset() { + *x = DeviceModelSpec{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeviceModelSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceModelSpec) ProtoMessage() {} + +func (x *DeviceModelSpec) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceModelSpec.ProtoReflect.Descriptor instead. +func (*DeviceModelSpec) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{3} +} + +func (x *DeviceModelSpec) GetProperties() []*ModelProperty { + if x != nil { + return x.Properties + } + return nil +} + +func (x *DeviceModelSpec) GetCommands() []*DeviceCommand { + if x != nil { + return x.Commands + } + return nil +} + +// ModelProperty is the property of a device. +type ModelProperty struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of this property. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // The description of this property. + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + // The specific type of this property. + Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` + // The access mode of this property, ReadOnly or ReadWrite. + AccessMode string `protobuf:"bytes,4,opt,name=accessMode,proto3" json:"accessMode,omitempty"` + // The minimum value of this property. + Minimum string `protobuf:"bytes,5,opt,name=minimum,proto3" json:"minimum,omitempty"` + // The maximum value of this property. + Maximum string `protobuf:"bytes,6,opt,name=maximum,proto3" json:"maximum,omitempty"` + // The unit of this property. + Unit string `protobuf:"bytes,7,opt,name=unit,proto3" json:"unit,omitempty"` +} + +func (x *ModelProperty) Reset() { + *x = ModelProperty{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ModelProperty) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ModelProperty) ProtoMessage() {} + +func (x *ModelProperty) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ModelProperty.ProtoReflect.Descriptor instead. +func (*ModelProperty) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{4} +} + +func (x *ModelProperty) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ModelProperty) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *ModelProperty) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *ModelProperty) GetAccessMode() string { + if x != nil { + return x.AccessMode + } + return "" +} + +func (x *ModelProperty) GetMinimum() string { + if x != nil { + return x.Minimum + } + return "" +} + +func (x *ModelProperty) GetMaximum() string { + if x != nil { + return x.Maximum + } + return "" +} + +func (x *ModelProperty) GetUnit() string { + if x != nil { + return x.Unit + } + return "" +} + +// DeviceCommond is the description of a command which the device supports. +type DeviceCommand struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the command. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Url of the command to access. + Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` + // Method of the command. + Method string `protobuf:"bytes,3,opt,name=method,proto3" json:"method,omitempty"` + // Status code list which the command can return. + StatusCode []string `protobuf:"bytes,4,rep,name=status_code,json=statusCode,proto3" json:"status_code,omitempty"` + // Parameter list which the command carries. + Parameters []string `protobuf:"bytes,5,rep,name=parameters,proto3" json:"parameters,omitempty"` + // Response examples of the command. + Response []byte `protobuf:"bytes,6,opt,name=response,proto3" json:"response,omitempty"` +} + +func (x *DeviceCommand) Reset() { + *x = DeviceCommand{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeviceCommand) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceCommand) ProtoMessage() {} + +func (x *DeviceCommand) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceCommand.ProtoReflect.Descriptor instead. +func (*DeviceCommand) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{5} +} + +func (x *DeviceCommand) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DeviceCommand) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *DeviceCommand) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *DeviceCommand) GetStatusCode() []string { + if x != nil { + return x.StatusCode + } + return nil +} + +func (x *DeviceCommand) GetParameters() []string { + if x != nil { + return x.Parameters + } + return nil +} + +func (x *DeviceCommand) GetResponse() []byte { + if x != nil { + return x.Response + } + return nil +} + +// Device is the description of a device instance. +type Device struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the device. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Specification of the device. + Spec *DeviceSpec `protobuf:"bytes,2,opt,name=spec,proto3" json:"spec,omitempty"` + // Status of the device. + Status *DeviceStatus `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"` +} + +func (x *Device) Reset() { + *x = Device{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Device) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Device) ProtoMessage() {} + +func (x *Device) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Device.ProtoReflect.Descriptor instead. +func (*Device) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{6} +} + +func (x *Device) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Device) GetSpec() *DeviceSpec { + if x != nil { + return x.Spec + } + return nil +} + +func (x *Device) GetStatus() *DeviceStatus { + if x != nil { + return x.Status + } + return nil +} + +// DeviceSpec is the specification of the device. +type DeviceSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The device model which the device references. + DeviceModelReference string `protobuf:"bytes,1,opt,name=deviceModelReference,proto3" json:"deviceModelReference,omitempty"` + // The specific config of the protocol to access to the device. + Protocol *ProtocolConfig `protobuf:"bytes,2,opt,name=protocol,proto3" json:"protocol,omitempty"` + // List of properties which describe the device properties. + Properties []*DeviceProperty `protobuf:"bytes,3,rep,name=properties,proto3" json:"properties,omitempty"` +} + +func (x *DeviceSpec) Reset() { + *x = DeviceSpec{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeviceSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceSpec) ProtoMessage() {} + +func (x *DeviceSpec) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceSpec.ProtoReflect.Descriptor instead. +func (*DeviceSpec) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{7} +} + +func (x *DeviceSpec) GetDeviceModelReference() string { + if x != nil { + return x.DeviceModelReference + } + return "" +} + +func (x *DeviceSpec) GetProtocol() *ProtocolConfig { + if x != nil { + return x.Protocol + } + return nil +} + +func (x *DeviceSpec) GetProperties() []*DeviceProperty { + if x != nil { + return x.Properties + } + return nil +} + +// DeviceProperty describes the specifics all the properties of the device. +type DeviceProperty struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The device property name to be accessed. It must be unique. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // the desired value of the property configured by device manager. + Desired *TwinProperty `protobuf:"bytes,2,opt,name=desired,proto3" json:"desired,omitempty"` + // Visitors are intended to be consumed by device mappers which connect to devices + // and collect data / perform actions on the device. + Visitors *VisitorConfig `protobuf:"bytes,3,opt,name=visitors,proto3" json:"visitors,omitempty"` + // Define how frequent mapper will report the value. + ReportCycle int64 `protobuf:"varint,4,opt,name=reportCycle,proto3" json:"reportCycle,omitempty"` + // Define how frequent mapper will collect from device. + CollectCycle int64 `protobuf:"varint,5,opt,name=collectCycle,proto3" json:"collectCycle,omitempty"` + // whether be reported to the cloud + ReportToCloud bool `protobuf:"varint,6,opt,name=reportToCloud,proto3" json:"reportToCloud,omitempty"` + // PushMethod represents the protocol used to push data, + PushMethod *PushMethod `protobuf:"bytes,7,opt,name=pushMethod,proto3" json:"pushMethod,omitempty"` +} + +func (x *DeviceProperty) Reset() { + *x = DeviceProperty{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeviceProperty) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceProperty) ProtoMessage() {} + +func (x *DeviceProperty) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceProperty.ProtoReflect.Descriptor instead. +func (*DeviceProperty) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{8} +} + +func (x *DeviceProperty) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DeviceProperty) GetDesired() *TwinProperty { + if x != nil { + return x.Desired + } + return nil +} + +func (x *DeviceProperty) GetVisitors() *VisitorConfig { + if x != nil { + return x.Visitors + } + return nil +} + +func (x *DeviceProperty) GetReportCycle() int64 { + if x != nil { + return x.ReportCycle + } + return 0 +} + +func (x *DeviceProperty) GetCollectCycle() int64 { + if x != nil { + return x.CollectCycle + } + return 0 +} + +func (x *DeviceProperty) GetReportToCloud() bool { + if x != nil { + return x.ReportToCloud + } + return false +} + +func (x *DeviceProperty) GetPushMethod() *PushMethod { + if x != nil { + return x.PushMethod + } + return nil +} + +// ProtocolConfig is the specific config of the protocol to access to the device. +type ProtocolConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the name of the customized protocol. + ProtocolName string `protobuf:"bytes,1,opt,name=protocolName,proto3" json:"protocolName,omitempty"` + // the config data of the customized protocol. + ConfigData *CustomizedValue `protobuf:"bytes,2,opt,name=configData,proto3" json:"configData,omitempty"` +} + +func (x *ProtocolConfig) Reset() { + *x = ProtocolConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProtocolConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProtocolConfig) ProtoMessage() {} + +func (x *ProtocolConfig) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProtocolConfig.ProtoReflect.Descriptor instead. +func (*ProtocolConfig) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{9} +} + +func (x *ProtocolConfig) GetProtocolName() string { + if x != nil { + return x.ProtocolName + } + return "" +} + +func (x *ProtocolConfig) GetConfigData() *CustomizedValue { + if x != nil { + return x.ConfigData + } + return nil +} + +// the visitor to collect the properties of the device of customized protocol. +type VisitorConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the name of the customized protocol. + ProtocolName string `protobuf:"bytes,1,opt,name=protocolName,proto3" json:"protocolName,omitempty"` + // the config data of the customized protocol. + ConfigData *CustomizedValue `protobuf:"bytes,2,opt,name=configData,proto3" json:"configData,omitempty"` +} + +func (x *VisitorConfig) Reset() { + *x = VisitorConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VisitorConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VisitorConfig) ProtoMessage() {} + +func (x *VisitorConfig) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VisitorConfig.ProtoReflect.Descriptor instead. +func (*VisitorConfig) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{10} +} + +func (x *VisitorConfig) GetProtocolName() string { + if x != nil { + return x.ProtocolName + } + return "" +} + +func (x *VisitorConfig) GetConfigData() *CustomizedValue { + if x != nil { + return x.ConfigData + } + return nil +} + +// CustomizedValue is the customized value for developers. +type CustomizedValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // data is the customized value and it can be any form. + Data map[string]*anypb.Any `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *CustomizedValue) Reset() { + *x = CustomizedValue{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CustomizedValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CustomizedValue) ProtoMessage() {} + +func (x *CustomizedValue) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CustomizedValue.ProtoReflect.Descriptor instead. +func (*CustomizedValue) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{11} +} + +func (x *CustomizedValue) GetData() map[string]*anypb.Any { + if x != nil { + return x.Data + } + return nil +} + +type PushMethod struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Http *PushMethodHTTP `protobuf:"bytes,1,opt,name=http,proto3" json:"http,omitempty"` + Mqtt *PushMethodMQTT `protobuf:"bytes,2,opt,name=mqtt,proto3" json:"mqtt,omitempty"` + DBMethod *DBMethod `protobuf:"bytes,3,opt,name=dbMethod,proto3" json:"dbMethod,omitempty"` +} + +func (x *PushMethod) Reset() { + *x = PushMethod{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PushMethod) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PushMethod) ProtoMessage() {} + +func (x *PushMethod) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PushMethod.ProtoReflect.Descriptor instead. +func (*PushMethod) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{12} +} + +func (x *PushMethod) GetHttp() *PushMethodHTTP { + if x != nil { + return x.Http + } + return nil +} + +func (x *PushMethod) GetMqtt() *PushMethodMQTT { + if x != nil { + return x.Mqtt + } + return nil +} + +func (x *PushMethod) GetDBMethod() *DBMethod { + if x != nil { + return x.DBMethod + } + return nil +} + +type PushMethodHTTP struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hostname string `protobuf:"bytes,1,opt,name=hostname,proto3" json:"hostname,omitempty"` + Port int64 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` + Requestpath string `protobuf:"bytes,3,opt,name=requestpath,proto3" json:"requestpath,omitempty"` + Timeout int64 `protobuf:"varint,4,opt,name=timeout,proto3" json:"timeout,omitempty"` +} + +func (x *PushMethodHTTP) Reset() { + *x = PushMethodHTTP{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PushMethodHTTP) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PushMethodHTTP) ProtoMessage() {} + +func (x *PushMethodHTTP) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PushMethodHTTP.ProtoReflect.Descriptor instead. +func (*PushMethodHTTP) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{13} +} + +func (x *PushMethodHTTP) GetHostname() string { + if x != nil { + return x.Hostname + } + return "" +} + +func (x *PushMethodHTTP) GetPort() int64 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *PushMethodHTTP) GetRequestpath() string { + if x != nil { + return x.Requestpath + } + return "" +} + +func (x *PushMethodHTTP) GetTimeout() int64 { + if x != nil { + return x.Timeout + } + return 0 +} + +type PushMethodMQTT struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // broker address, like mqtt://127.0.0.1:1883 + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + // publish topic for mqtt + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + // qos of mqtt publish param + Qos int32 `protobuf:"varint,3,opt,name=qos,proto3" json:"qos,omitempty"` + // Is the message retained + Retained bool `protobuf:"varint,4,opt,name=retained,proto3" json:"retained,omitempty"` +} + +func (x *PushMethodMQTT) Reset() { + *x = PushMethodMQTT{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PushMethodMQTT) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PushMethodMQTT) ProtoMessage() {} + +func (x *PushMethodMQTT) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PushMethodMQTT.ProtoReflect.Descriptor instead. +func (*PushMethodMQTT) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{14} +} + +func (x *PushMethodMQTT) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *PushMethodMQTT) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *PushMethodMQTT) GetQos() int32 { + if x != nil { + return x.Qos + } + return 0 +} + +func (x *PushMethodMQTT) GetRetained() bool { + if x != nil { + return x.Retained + } + return false +} + +type DBMethod struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the config of database . + Influxdb2 *DBMethodInfluxdb2 `protobuf:"bytes,1,opt,name=influxdb2,proto3" json:"influxdb2,omitempty"` +} + +func (x *DBMethod) Reset() { + *x = DBMethod{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DBMethod) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DBMethod) ProtoMessage() {} + +func (x *DBMethod) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DBMethod.ProtoReflect.Descriptor instead. +func (*DBMethod) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{15} +} + +func (x *DBMethod) GetInfluxdb2() *DBMethodInfluxdb2 { + if x != nil { + return x.Influxdb2 + } + return nil +} + +type DBMethodInfluxdb2 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the config of influx database. + Influxdb2ClientConfig *Influxdb2ClientConfig `protobuf:"bytes,1,opt,name=influxdb2ClientConfig,proto3" json:"influxdb2ClientConfig,omitempty"` + Influxdb2DataConfig *Influxdb2DataConfig `protobuf:"bytes,2,opt,name=influxdb2DataConfig,proto3" json:"influxdb2DataConfig,omitempty"` +} + +func (x *DBMethodInfluxdb2) Reset() { + *x = DBMethodInfluxdb2{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DBMethodInfluxdb2) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DBMethodInfluxdb2) ProtoMessage() {} + +func (x *DBMethodInfluxdb2) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DBMethodInfluxdb2.ProtoReflect.Descriptor instead. +func (*DBMethodInfluxdb2) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{16} +} + +func (x *DBMethodInfluxdb2) GetInfluxdb2ClientConfig() *Influxdb2ClientConfig { + if x != nil { + return x.Influxdb2ClientConfig + } + return nil +} + +func (x *DBMethodInfluxdb2) GetInfluxdb2DataConfig() *Influxdb2DataConfig { + if x != nil { + return x.Influxdb2DataConfig + } + return nil +} + +type Influxdb2DataConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // data config when push data to influx + Measurement string `protobuf:"bytes,1,opt,name=measurement,proto3" json:"measurement,omitempty"` + Tag map[string]string `protobuf:"bytes,2,rep,name=tag,proto3" json:"tag,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + FieldKey string `protobuf:"bytes,3,opt,name=fieldKey,proto3" json:"fieldKey,omitempty"` +} + +func (x *Influxdb2DataConfig) Reset() { + *x = Influxdb2DataConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Influxdb2DataConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Influxdb2DataConfig) ProtoMessage() {} + +func (x *Influxdb2DataConfig) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Influxdb2DataConfig.ProtoReflect.Descriptor instead. +func (*Influxdb2DataConfig) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{17} +} + +func (x *Influxdb2DataConfig) GetMeasurement() string { + if x != nil { + return x.Measurement + } + return "" +} + +func (x *Influxdb2DataConfig) GetTag() map[string]string { + if x != nil { + return x.Tag + } + return nil +} + +func (x *Influxdb2DataConfig) GetFieldKey() string { + if x != nil { + return x.FieldKey + } + return "" +} + +type Influxdb2ClientConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // influx database url + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` + // usr org in influx database + Org string `protobuf:"bytes,2,opt,name=org,proto3" json:"org,omitempty"` + // usr bucket in influx database + Bucket string `protobuf:"bytes,3,opt,name=bucket,proto3" json:"bucket,omitempty"` +} + +func (x *Influxdb2ClientConfig) Reset() { + *x = Influxdb2ClientConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Influxdb2ClientConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Influxdb2ClientConfig) ProtoMessage() {} + +func (x *Influxdb2ClientConfig) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Influxdb2ClientConfig.ProtoReflect.Descriptor instead. +func (*Influxdb2ClientConfig) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{18} +} + +func (x *Influxdb2ClientConfig) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *Influxdb2ClientConfig) GetOrg() string { + if x != nil { + return x.Org + } + return "" +} + +func (x *Influxdb2ClientConfig) GetBucket() string { + if x != nil { + return x.Bucket + } + return "" +} + +// MapperInfo is the information of mapper. +type MapperInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name of the mapper. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // version of the mapper. + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + // api version of the mapper. + ApiVersion string `protobuf:"bytes,3,opt,name=api_version,json=apiVersion,proto3" json:"api_version,omitempty"` + // the protocol of the mapper. + Protocol string `protobuf:"bytes,4,opt,name=protocol,proto3" json:"protocol,omitempty"` + // the address of the mapper. it is a unix domain socket of grpc. + Address []byte `protobuf:"bytes,5,opt,name=address,proto3" json:"address,omitempty"` + // the state of the mapper. + State string `protobuf:"bytes,6,opt,name=state,proto3" json:"state,omitempty"` +} + +func (x *MapperInfo) Reset() { + *x = MapperInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MapperInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MapperInfo) ProtoMessage() {} + +func (x *MapperInfo) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MapperInfo.ProtoReflect.Descriptor instead. +func (*MapperInfo) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{19} +} + +func (x *MapperInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *MapperInfo) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *MapperInfo) GetApiVersion() string { + if x != nil { + return x.ApiVersion + } + return "" +} + +func (x *MapperInfo) GetProtocol() string { + if x != nil { + return x.Protocol + } + return "" +} + +func (x *MapperInfo) GetAddress() []byte { + if x != nil { + return x.Address + } + return nil +} + +func (x *MapperInfo) GetState() string { + if x != nil { + return x.State + } + return "" +} + +type ReportDeviceStatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DeviceName string `protobuf:"bytes,1,opt,name=deviceName,proto3" json:"deviceName,omitempty"` + ReportedDevice *DeviceStatus `protobuf:"bytes,2,opt,name=reportedDevice,proto3" json:"reportedDevice,omitempty"` +} + +func (x *ReportDeviceStatusRequest) Reset() { + *x = ReportDeviceStatusRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReportDeviceStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReportDeviceStatusRequest) ProtoMessage() {} + +func (x *ReportDeviceStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReportDeviceStatusRequest.ProtoReflect.Descriptor instead. +func (*ReportDeviceStatusRequest) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{20} +} + +func (x *ReportDeviceStatusRequest) GetDeviceName() string { + if x != nil { + return x.DeviceName + } + return "" +} + +func (x *ReportDeviceStatusRequest) GetReportedDevice() *DeviceStatus { + if x != nil { + return x.ReportedDevice + } + return nil +} + +// DeviceStatus is the status of the device. +type DeviceStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the device twins of the device. + Twins []*Twin `protobuf:"bytes,1,rep,name=twins,proto3" json:"twins,omitempty"` +} + +func (x *DeviceStatus) Reset() { + *x = DeviceStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeviceStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceStatus) ProtoMessage() {} + +func (x *DeviceStatus) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceStatus.ProtoReflect.Descriptor instead. +func (*DeviceStatus) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{21} +} + +func (x *DeviceStatus) GetTwins() []*Twin { + if x != nil { + return x.Twins + } + return nil +} + +// Twin is the digital model of a device. It contains a series of properties. +type Twin struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the name of the property. + PropertyName string `protobuf:"bytes,1,opt,name=propertyName,proto3" json:"propertyName,omitempty"` + // the observedDesired value of the property configured by mapper. + ObservedDesired *TwinProperty `protobuf:"bytes,2,opt,name=observedDesired,proto3" json:"observedDesired,omitempty"` + // the reported value of the property from the real device. + Reported *TwinProperty `protobuf:"bytes,3,opt,name=reported,proto3" json:"reported,omitempty"` +} + +func (x *Twin) Reset() { + *x = Twin{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Twin) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Twin) ProtoMessage() {} + +func (x *Twin) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Twin.ProtoReflect.Descriptor instead. +func (*Twin) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{22} +} + +func (x *Twin) GetPropertyName() string { + if x != nil { + return x.PropertyName + } + return "" +} + +func (x *Twin) GetObservedDesired() *TwinProperty { + if x != nil { + return x.ObservedDesired + } + return nil +} + +func (x *Twin) GetReported() *TwinProperty { + if x != nil { + return x.Reported + } + return nil +} + +// TwinProperty is the specification of the property. +type TwinProperty struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the value of the property. + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + // the metadata to describe this property. + Metadata map[string]string `protobuf:"bytes,2,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *TwinProperty) Reset() { + *x = TwinProperty{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TwinProperty) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TwinProperty) ProtoMessage() {} + +func (x *TwinProperty) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TwinProperty.ProtoReflect.Descriptor instead. +func (*TwinProperty) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{23} +} + +func (x *TwinProperty) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *TwinProperty) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +type ReportDeviceStatusResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ReportDeviceStatusResponse) Reset() { + *x = ReportDeviceStatusResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReportDeviceStatusResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReportDeviceStatusResponse) ProtoMessage() {} + +func (x *ReportDeviceStatusResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReportDeviceStatusResponse.ProtoReflect.Descriptor instead. +func (*ReportDeviceStatusResponse) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{24} +} + +type RegisterDeviceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Device *Device `protobuf:"bytes,1,opt,name=device,proto3" json:"device,omitempty"` +} + +func (x *RegisterDeviceRequest) Reset() { + *x = RegisterDeviceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterDeviceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterDeviceRequest) ProtoMessage() {} + +func (x *RegisterDeviceRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterDeviceRequest.ProtoReflect.Descriptor instead. +func (*RegisterDeviceRequest) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{25} +} + +func (x *RegisterDeviceRequest) GetDevice() *Device { + if x != nil { + return x.Device + } + return nil +} + +type RegisterDeviceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DeviceName string `protobuf:"bytes,1,opt,name=deviceName,proto3" json:"deviceName,omitempty"` +} + +func (x *RegisterDeviceResponse) Reset() { + *x = RegisterDeviceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterDeviceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterDeviceResponse) ProtoMessage() {} + +func (x *RegisterDeviceResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterDeviceResponse.ProtoReflect.Descriptor instead. +func (*RegisterDeviceResponse) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{26} +} + +func (x *RegisterDeviceResponse) GetDeviceName() string { + if x != nil { + return x.DeviceName + } + return "" +} + +type CreateDeviceModelRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Model *DeviceModel `protobuf:"bytes,1,opt,name=model,proto3" json:"model,omitempty"` +} + +func (x *CreateDeviceModelRequest) Reset() { + *x = CreateDeviceModelRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateDeviceModelRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateDeviceModelRequest) ProtoMessage() {} + +func (x *CreateDeviceModelRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateDeviceModelRequest.ProtoReflect.Descriptor instead. +func (*CreateDeviceModelRequest) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{27} +} + +func (x *CreateDeviceModelRequest) GetModel() *DeviceModel { + if x != nil { + return x.Model + } + return nil +} + +type CreateDeviceModelResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DeviceModelName string `protobuf:"bytes,1,opt,name=deviceModelName,proto3" json:"deviceModelName,omitempty"` +} + +func (x *CreateDeviceModelResponse) Reset() { + *x = CreateDeviceModelResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateDeviceModelResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateDeviceModelResponse) ProtoMessage() {} + +func (x *CreateDeviceModelResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateDeviceModelResponse.ProtoReflect.Descriptor instead. +func (*CreateDeviceModelResponse) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{28} +} + +func (x *CreateDeviceModelResponse) GetDeviceModelName() string { + if x != nil { + return x.DeviceModelName + } + return "" +} + +type RemoveDeviceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DeviceName string `protobuf:"bytes,1,opt,name=deviceName,proto3" json:"deviceName,omitempty"` +} + +func (x *RemoveDeviceRequest) Reset() { + *x = RemoveDeviceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveDeviceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveDeviceRequest) ProtoMessage() {} + +func (x *RemoveDeviceRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveDeviceRequest.ProtoReflect.Descriptor instead. +func (*RemoveDeviceRequest) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{29} +} + +func (x *RemoveDeviceRequest) GetDeviceName() string { + if x != nil { + return x.DeviceName + } + return "" +} + +type RemoveDeviceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *RemoveDeviceResponse) Reset() { + *x = RemoveDeviceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveDeviceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveDeviceResponse) ProtoMessage() {} + +func (x *RemoveDeviceResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveDeviceResponse.ProtoReflect.Descriptor instead. +func (*RemoveDeviceResponse) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{30} +} + +type RemoveDeviceModelRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ModelName string `protobuf:"bytes,1,opt,name=modelName,proto3" json:"modelName,omitempty"` +} + +func (x *RemoveDeviceModelRequest) Reset() { + *x = RemoveDeviceModelRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveDeviceModelRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveDeviceModelRequest) ProtoMessage() {} + +func (x *RemoveDeviceModelRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveDeviceModelRequest.ProtoReflect.Descriptor instead. +func (*RemoveDeviceModelRequest) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{31} +} + +func (x *RemoveDeviceModelRequest) GetModelName() string { + if x != nil { + return x.ModelName + } + return "" +} + +type RemoveDeviceModelResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *RemoveDeviceModelResponse) Reset() { + *x = RemoveDeviceModelResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveDeviceModelResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveDeviceModelResponse) ProtoMessage() {} + +func (x *RemoveDeviceModelResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveDeviceModelResponse.ProtoReflect.Descriptor instead. +func (*RemoveDeviceModelResponse) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{32} +} + +type UpdateDeviceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Device *Device `protobuf:"bytes,1,opt,name=device,proto3" json:"device,omitempty"` +} + +func (x *UpdateDeviceRequest) Reset() { + *x = UpdateDeviceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateDeviceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateDeviceRequest) ProtoMessage() {} + +func (x *UpdateDeviceRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateDeviceRequest.ProtoReflect.Descriptor instead. +func (*UpdateDeviceRequest) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{33} +} + +func (x *UpdateDeviceRequest) GetDevice() *Device { + if x != nil { + return x.Device + } + return nil +} + +type UpdateDeviceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *UpdateDeviceResponse) Reset() { + *x = UpdateDeviceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateDeviceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateDeviceResponse) ProtoMessage() {} + +func (x *UpdateDeviceResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateDeviceResponse.ProtoReflect.Descriptor instead. +func (*UpdateDeviceResponse) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{34} +} + +type UpdateDeviceModelRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Model *DeviceModel `protobuf:"bytes,1,opt,name=model,proto3" json:"model,omitempty"` +} + +func (x *UpdateDeviceModelRequest) Reset() { + *x = UpdateDeviceModelRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateDeviceModelRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateDeviceModelRequest) ProtoMessage() {} + +func (x *UpdateDeviceModelRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateDeviceModelRequest.ProtoReflect.Descriptor instead. +func (*UpdateDeviceModelRequest) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{35} +} + +func (x *UpdateDeviceModelRequest) GetModel() *DeviceModel { + if x != nil { + return x.Model + } + return nil +} + +type UpdateDeviceModelResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *UpdateDeviceModelResponse) Reset() { + *x = UpdateDeviceModelResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateDeviceModelResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateDeviceModelResponse) ProtoMessage() {} + +func (x *UpdateDeviceModelResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateDeviceModelResponse.ProtoReflect.Descriptor instead. +func (*UpdateDeviceModelResponse) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{36} +} + +type GetDeviceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DeviceName string `protobuf:"bytes,1,opt,name=deviceName,proto3" json:"deviceName,omitempty"` +} + +func (x *GetDeviceRequest) Reset() { + *x = GetDeviceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetDeviceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDeviceRequest) ProtoMessage() {} + +func (x *GetDeviceRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDeviceRequest.ProtoReflect.Descriptor instead. +func (*GetDeviceRequest) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{37} +} + +func (x *GetDeviceRequest) GetDeviceName() string { + if x != nil { + return x.DeviceName + } + return "" +} + +type GetDeviceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Device *Device `protobuf:"bytes,1,opt,name=device,proto3" json:"device,omitempty"` +} + +func (x *GetDeviceResponse) Reset() { + *x = GetDeviceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetDeviceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDeviceResponse) ProtoMessage() {} + +func (x *GetDeviceResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[38] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDeviceResponse.ProtoReflect.Descriptor instead. +func (*GetDeviceResponse) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{38} +} + +func (x *GetDeviceResponse) GetDevice() *Device { + if x != nil { + return x.Device + } + return nil +} + +var File_api_proto protoreflect.FileDescriptor + +var file_api_proto_rawDesc = []byte{ + 0x0a, 0x09, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0x60, 0x0a, 0x15, 0x4d, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x69, 0x74, 0x68, + 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x69, 0x74, 0x68, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x2b, 0x0a, 0x06, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, + 0x61, 0x70, 0x70, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x6d, 0x61, 0x70, 0x70, 0x65, + 0x72, 0x22, 0x7d, 0x0a, 0x16, 0x4d, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x09, 0x6d, + 0x6f, 0x64, 0x65, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, + 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x09, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x2f, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, + 0x22, 0x4f, 0x0a, 0x0b, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, + 0x63, 0x22, 0x7d, 0x0a, 0x0f, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, + 0x53, 0x70, 0x65, 0x63, 0x12, 0x36, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x08, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, + 0x22, 0xc1, 0x01, 0x0a, 0x0d, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, + 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, + 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, + 0x12, 0x12, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x75, 0x6e, 0x69, 0x74, 0x22, 0xaa, 0x01, 0x0a, 0x0d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, + 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, + 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x74, 0x0a, 0x06, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x27, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x70, + 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x2d, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xae, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x32, 0x0a, 0x14, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, + 0x6c, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, + 0x37, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x0a, 0x70, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0xaa, 0x02, 0x0a, 0x0e, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x2f, 0x0a, 0x07, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x77, 0x69, 0x6e, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x07, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, + 0x12, 0x32, 0x0a, 0x08, 0x76, 0x69, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x56, 0x69, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x76, 0x69, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x79, + 0x63, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, + 0x74, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, + 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x72, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x54, 0x6f, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x6f, 0x43, 0x6c, 0x6f, 0x75, 0x64, + 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, + 0x75, 0x73, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0a, 0x70, 0x75, 0x73, 0x68, 0x4d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x22, 0x6e, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0a, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x69, 0x7a, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x44, 0x61, 0x74, 0x61, 0x22, 0x6d, 0x0a, 0x0d, 0x56, 0x69, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, + 0x7a, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x44, 0x61, 0x74, 0x61, 0x22, 0x98, 0x01, 0x0a, 0x0f, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, + 0x7a, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x1a, 0x4d, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x95, 0x01, 0x0a, 0x0a, 0x50, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x2b, + 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x48, 0x54, 0x54, 0x50, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x2b, 0x0a, 0x04, 0x6d, + 0x71, 0x74, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4d, 0x51, + 0x54, 0x54, 0x52, 0x04, 0x6d, 0x71, 0x74, 0x74, 0x12, 0x2d, 0x0a, 0x08, 0x64, 0x62, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x42, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x08, 0x64, + 0x62, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x22, 0x7c, 0x0a, 0x0e, 0x50, 0x75, 0x73, 0x68, 0x4d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x48, 0x54, 0x54, 0x50, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, + 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, + 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x70, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x74, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x6e, 0x0a, 0x0e, 0x50, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x4d, 0x51, 0x54, 0x54, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x71, 0x6f, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x71, 0x6f, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x64, 0x22, 0x44, 0x0a, 0x08, 0x44, 0x42, 0x4d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x12, 0x38, 0x0a, 0x09, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x64, 0x62, 0x32, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, + 0x42, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x49, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x64, 0x62, 0x32, + 0x52, 0x09, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x64, 0x62, 0x32, 0x22, 0xb9, 0x01, 0x0a, 0x11, + 0x44, 0x42, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x49, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x64, 0x62, + 0x32, 0x12, 0x54, 0x0a, 0x15, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x64, 0x62, 0x32, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6c, 0x75, + 0x78, 0x64, 0x62, 0x32, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x15, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x64, 0x62, 0x32, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4e, 0x0a, 0x13, 0x69, 0x6e, 0x66, 0x6c, 0x75, + 0x78, 0x64, 0x62, 0x32, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, + 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x64, 0x62, 0x32, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x13, 0x69, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x64, 0x62, 0x32, 0x44, 0x61, 0x74, + 0x61, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xc4, 0x01, 0x0a, 0x13, 0x49, 0x6e, 0x66, 0x6c, + 0x75, 0x78, 0x64, 0x62, 0x32, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x20, 0x0a, 0x0b, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x37, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x64, + 0x62, 0x32, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x61, 0x67, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x1a, 0x36, 0x0a, 0x08, 0x54, 0x61, 0x67, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x53, + 0x0a, 0x15, 0x49, 0x6e, 0x66, 0x6c, 0x75, 0x78, 0x64, 0x62, 0x32, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x72, 0x67, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x72, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x62, + 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x75, 0x63, + 0x6b, 0x65, 0x74, 0x22, 0xa7, 0x01, 0x0a, 0x0a, 0x4d, 0x61, 0x70, 0x70, 0x65, 0x72, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x18, 0x0a, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x7a, 0x0a, + 0x19, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x72, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x22, 0x33, 0x0a, 0x0c, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x05, 0x74, 0x77, 0x69, + 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x54, 0x77, 0x69, 0x6e, 0x52, 0x05, 0x74, 0x77, 0x69, 0x6e, 0x73, 0x22, 0x9e, + 0x01, 0x0a, 0x04, 0x54, 0x77, 0x69, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x0f, 0x6f, + 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, + 0x77, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x0f, 0x6f, 0x62, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x64, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x12, 0x31, 0x0a, 0x08, + 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x77, 0x69, 0x6e, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x22, + 0xa2, 0x01, 0x0a, 0x0c, 0x54, 0x77, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3f, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x54, 0x77, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x40, 0x0a, 0x15, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x06, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x22, 0x38, 0x0a, 0x16, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, + 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x46, + 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, + 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x05, 0x6d, 0x6f, + 0x64, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, + 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x22, 0x45, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, + 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x35, 0x0a, + 0x13, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x0a, 0x18, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, + 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x64, + 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x1b, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x3e, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x06, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0x0a, 0x18, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x05, 0x6d, 0x6f, + 0x64, 0x65, 0x6c, 0x22, 0x1b, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x32, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3c, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x32, 0xcc, 0x01, 0x0a, 0x14, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x53, 0x0a, 0x0e, 0x4d, + 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x5f, 0x0a, 0x12, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x22, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x32, 0xe8, 0x04, 0x0a, 0x13, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, + 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x53, 0x0a, 0x0e, 0x52, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1e, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4d, + 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1c, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4d, 0x0a, + 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1c, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x11, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, + 0x6c, 0x12, 0x21, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x11, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, + 0x21, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x21, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x22, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x19, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x0c, 0x5a, 0x0a, + 0x2e, 0x2f, 0x3b, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_api_proto_rawDescOnce sync.Once + file_api_proto_rawDescData = file_api_proto_rawDesc +) + +func file_api_proto_rawDescGZIP() []byte { + file_api_proto_rawDescOnce.Do(func() { + file_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_proto_rawDescData) + }) + return file_api_proto_rawDescData +} + +var file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 42) +var file_api_proto_goTypes = []interface{}{ + (*MapperRegisterRequest)(nil), // 0: v1beta1.MapperRegisterRequest + (*MapperRegisterResponse)(nil), // 1: v1beta1.MapperRegisterResponse + (*DeviceModel)(nil), // 2: v1beta1.DeviceModel + (*DeviceModelSpec)(nil), // 3: v1beta1.DeviceModelSpec + (*ModelProperty)(nil), // 4: v1beta1.ModelProperty + (*DeviceCommand)(nil), // 5: v1beta1.DeviceCommand + (*Device)(nil), // 6: v1beta1.Device + (*DeviceSpec)(nil), // 7: v1beta1.DeviceSpec + (*DeviceProperty)(nil), // 8: v1beta1.DeviceProperty + (*ProtocolConfig)(nil), // 9: v1beta1.ProtocolConfig + (*VisitorConfig)(nil), // 10: v1beta1.VisitorConfig + (*CustomizedValue)(nil), // 11: v1beta1.CustomizedValue + (*PushMethod)(nil), // 12: v1beta1.PushMethod + (*PushMethodHTTP)(nil), // 13: v1beta1.PushMethodHTTP + (*PushMethodMQTT)(nil), // 14: v1beta1.PushMethodMQTT + (*DBMethod)(nil), // 15: v1beta1.DBMethod + (*DBMethodInfluxdb2)(nil), // 16: v1beta1.DBMethodInfluxdb2 + (*Influxdb2DataConfig)(nil), // 17: v1beta1.Influxdb2DataConfig + (*Influxdb2ClientConfig)(nil), // 18: v1beta1.Influxdb2ClientConfig + (*MapperInfo)(nil), // 19: v1beta1.MapperInfo + (*ReportDeviceStatusRequest)(nil), // 20: v1beta1.ReportDeviceStatusRequest + (*DeviceStatus)(nil), // 21: v1beta1.DeviceStatus + (*Twin)(nil), // 22: v1beta1.Twin + (*TwinProperty)(nil), // 23: v1beta1.TwinProperty + (*ReportDeviceStatusResponse)(nil), // 24: v1beta1.ReportDeviceStatusResponse + (*RegisterDeviceRequest)(nil), // 25: v1beta1.RegisterDeviceRequest + (*RegisterDeviceResponse)(nil), // 26: v1beta1.RegisterDeviceResponse + (*CreateDeviceModelRequest)(nil), // 27: v1beta1.CreateDeviceModelRequest + (*CreateDeviceModelResponse)(nil), // 28: v1beta1.CreateDeviceModelResponse + (*RemoveDeviceRequest)(nil), // 29: v1beta1.RemoveDeviceRequest + (*RemoveDeviceResponse)(nil), // 30: v1beta1.RemoveDeviceResponse + (*RemoveDeviceModelRequest)(nil), // 31: v1beta1.RemoveDeviceModelRequest + (*RemoveDeviceModelResponse)(nil), // 32: v1beta1.RemoveDeviceModelResponse + (*UpdateDeviceRequest)(nil), // 33: v1beta1.UpdateDeviceRequest + (*UpdateDeviceResponse)(nil), // 34: v1beta1.UpdateDeviceResponse + (*UpdateDeviceModelRequest)(nil), // 35: v1beta1.UpdateDeviceModelRequest + (*UpdateDeviceModelResponse)(nil), // 36: v1beta1.UpdateDeviceModelResponse + (*GetDeviceRequest)(nil), // 37: v1beta1.GetDeviceRequest + (*GetDeviceResponse)(nil), // 38: v1beta1.GetDeviceResponse + nil, // 39: v1beta1.CustomizedValue.DataEntry + nil, // 40: v1beta1.Influxdb2DataConfig.TagEntry + nil, // 41: v1beta1.TwinProperty.MetadataEntry + (*anypb.Any)(nil), // 42: google.protobuf.Any +} +var file_api_proto_depIdxs = []int32{ + 19, // 0: v1beta1.MapperRegisterRequest.mapper:type_name -> v1beta1.MapperInfo + 2, // 1: v1beta1.MapperRegisterResponse.modelList:type_name -> v1beta1.DeviceModel + 6, // 2: v1beta1.MapperRegisterResponse.deviceList:type_name -> v1beta1.Device + 3, // 3: v1beta1.DeviceModel.spec:type_name -> v1beta1.DeviceModelSpec + 4, // 4: v1beta1.DeviceModelSpec.properties:type_name -> v1beta1.ModelProperty + 5, // 5: v1beta1.DeviceModelSpec.commands:type_name -> v1beta1.DeviceCommand + 7, // 6: v1beta1.Device.spec:type_name -> v1beta1.DeviceSpec + 21, // 7: v1beta1.Device.status:type_name -> v1beta1.DeviceStatus + 9, // 8: v1beta1.DeviceSpec.protocol:type_name -> v1beta1.ProtocolConfig + 8, // 9: v1beta1.DeviceSpec.properties:type_name -> v1beta1.DeviceProperty + 23, // 10: v1beta1.DeviceProperty.desired:type_name -> v1beta1.TwinProperty + 10, // 11: v1beta1.DeviceProperty.visitors:type_name -> v1beta1.VisitorConfig + 12, // 12: v1beta1.DeviceProperty.pushMethod:type_name -> v1beta1.PushMethod + 11, // 13: v1beta1.ProtocolConfig.configData:type_name -> v1beta1.CustomizedValue + 11, // 14: v1beta1.VisitorConfig.configData:type_name -> v1beta1.CustomizedValue + 39, // 15: v1beta1.CustomizedValue.data:type_name -> v1beta1.CustomizedValue.DataEntry + 13, // 16: v1beta1.PushMethod.http:type_name -> v1beta1.PushMethodHTTP + 14, // 17: v1beta1.PushMethod.mqtt:type_name -> v1beta1.PushMethodMQTT + 15, // 18: v1beta1.PushMethod.dbMethod:type_name -> v1beta1.DBMethod + 16, // 19: v1beta1.DBMethod.influxdb2:type_name -> v1beta1.DBMethodInfluxdb2 + 18, // 20: v1beta1.DBMethodInfluxdb2.influxdb2ClientConfig:type_name -> v1beta1.Influxdb2ClientConfig + 17, // 21: v1beta1.DBMethodInfluxdb2.influxdb2DataConfig:type_name -> v1beta1.Influxdb2DataConfig + 40, // 22: v1beta1.Influxdb2DataConfig.tag:type_name -> v1beta1.Influxdb2DataConfig.TagEntry + 21, // 23: v1beta1.ReportDeviceStatusRequest.reportedDevice:type_name -> v1beta1.DeviceStatus + 22, // 24: v1beta1.DeviceStatus.twins:type_name -> v1beta1.Twin + 23, // 25: v1beta1.Twin.observedDesired:type_name -> v1beta1.TwinProperty + 23, // 26: v1beta1.Twin.reported:type_name -> v1beta1.TwinProperty + 41, // 27: v1beta1.TwinProperty.metadata:type_name -> v1beta1.TwinProperty.MetadataEntry + 6, // 28: v1beta1.RegisterDeviceRequest.device:type_name -> v1beta1.Device + 2, // 29: v1beta1.CreateDeviceModelRequest.model:type_name -> v1beta1.DeviceModel + 6, // 30: v1beta1.UpdateDeviceRequest.device:type_name -> v1beta1.Device + 2, // 31: v1beta1.UpdateDeviceModelRequest.model:type_name -> v1beta1.DeviceModel + 6, // 32: v1beta1.GetDeviceResponse.device:type_name -> v1beta1.Device + 42, // 33: v1beta1.CustomizedValue.DataEntry.value:type_name -> google.protobuf.Any + 0, // 34: v1beta1.DeviceManagerService.MapperRegister:input_type -> v1beta1.MapperRegisterRequest + 20, // 35: v1beta1.DeviceManagerService.ReportDeviceStatus:input_type -> v1beta1.ReportDeviceStatusRequest + 25, // 36: v1beta1.DeviceMapperService.RegisterDevice:input_type -> v1beta1.RegisterDeviceRequest + 29, // 37: v1beta1.DeviceMapperService.RemoveDevice:input_type -> v1beta1.RemoveDeviceRequest + 33, // 38: v1beta1.DeviceMapperService.UpdateDevice:input_type -> v1beta1.UpdateDeviceRequest + 27, // 39: v1beta1.DeviceMapperService.CreateDeviceModel:input_type -> v1beta1.CreateDeviceModelRequest + 31, // 40: v1beta1.DeviceMapperService.RemoveDeviceModel:input_type -> v1beta1.RemoveDeviceModelRequest + 35, // 41: v1beta1.DeviceMapperService.UpdateDeviceModel:input_type -> v1beta1.UpdateDeviceModelRequest + 37, // 42: v1beta1.DeviceMapperService.GetDevice:input_type -> v1beta1.GetDeviceRequest + 1, // 43: v1beta1.DeviceManagerService.MapperRegister:output_type -> v1beta1.MapperRegisterResponse + 24, // 44: v1beta1.DeviceManagerService.ReportDeviceStatus:output_type -> v1beta1.ReportDeviceStatusResponse + 26, // 45: v1beta1.DeviceMapperService.RegisterDevice:output_type -> v1beta1.RegisterDeviceResponse + 30, // 46: v1beta1.DeviceMapperService.RemoveDevice:output_type -> v1beta1.RemoveDeviceResponse + 34, // 47: v1beta1.DeviceMapperService.UpdateDevice:output_type -> v1beta1.UpdateDeviceResponse + 28, // 48: v1beta1.DeviceMapperService.CreateDeviceModel:output_type -> v1beta1.CreateDeviceModelResponse + 32, // 49: v1beta1.DeviceMapperService.RemoveDeviceModel:output_type -> v1beta1.RemoveDeviceModelResponse + 36, // 50: v1beta1.DeviceMapperService.UpdateDeviceModel:output_type -> v1beta1.UpdateDeviceModelResponse + 38, // 51: v1beta1.DeviceMapperService.GetDevice:output_type -> v1beta1.GetDeviceResponse + 43, // [43:52] is the sub-list for method output_type + 34, // [34:43] is the sub-list for method input_type + 34, // [34:34] is the sub-list for extension type_name + 34, // [34:34] is the sub-list for extension extendee + 0, // [0:34] is the sub-list for field type_name +} + +func init() { file_api_proto_init() } +func file_api_proto_init() { + if File_api_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MapperRegisterRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MapperRegisterResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeviceModel); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeviceModelSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ModelProperty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeviceCommand); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Device); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeviceSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeviceProperty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProtocolConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VisitorConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CustomizedValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PushMethod); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PushMethodHTTP); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PushMethodMQTT); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DBMethod); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DBMethodInfluxdb2); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Influxdb2DataConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Influxdb2ClientConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MapperInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReportDeviceStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeviceStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Twin); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TwinProperty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReportDeviceStatusResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterDeviceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterDeviceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateDeviceModelRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateDeviceModelResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveDeviceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveDeviceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveDeviceModelRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveDeviceModelResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateDeviceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateDeviceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateDeviceModelRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateDeviceModelResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetDeviceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetDeviceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_proto_rawDesc, + NumEnums: 0, + NumMessages: 42, + NumExtensions: 0, + NumServices: 2, + }, + GoTypes: file_api_proto_goTypes, + DependencyIndexes: file_api_proto_depIdxs, + MessageInfos: file_api_proto_msgTypes, + }.Build() + File_api_proto = out.File + file_api_proto_rawDesc = nil + file_api_proto_goTypes = nil + file_api_proto_depIdxs = nil +} + +func NewMapperClient(cc grpc.ClientConnInterface) DeviceMapperServiceClient { + return &deviceMapperServiceClient{cc} +} + +func NewDeviceManageClient(cc grpc.ClientConnInterface) DeviceManagerServiceClient { + return &deviceManagerServiceClient{cc} +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/dmi-api/api.proto b/mappers/kubeedge-v1.15.0/modbus/pkg/dmi-api/api.proto new file mode 100644 index 00000000..a6f94859 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/dmi-api/api.proto @@ -0,0 +1,365 @@ +/* +Copyright 2023 The KubeEdge Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// To regenerate api.pb.go run hack/generate-dmi.sh +syntax = "proto3"; + +//option go_package = "path;name"; +option go_package = "./;v1beta1"; +package v1beta1; + +import "google/protobuf/any.proto"; + +// DeviceManagerService defines the public APIS for remote device management. +// The server is implemented by the module of device manager in edgecore +// and the client is implemented by the device mapper for upstreaming. +// The mapper should register itself to the device manager when it is online +// to get the list of devices. And then the mapper can report the device status to the device manager. +service DeviceManagerService { + // MapperRegister registers the information of the mapper to device manager + // when the mapper is online. Device manager returns the list of devices and device models which + // this mapper should manage. + rpc MapperRegister(MapperRegisterRequest) returns (MapperRegisterResponse) {} + // ReportDeviceStatus reports the status of devices to device manager. + // When the mapper collects some properties of a device, it can make them a map of device twins + // and report it to the device manager through the interface of ReportDeviceStatus. + rpc ReportDeviceStatus(ReportDeviceStatusRequest) returns (ReportDeviceStatusResponse) {} +} + +// DeviceMapperService defines the public APIS for remote device management. +// The server is implemented by the device mapper +// and the client is implemented by the module of device manager in edgecore for downstreaming. +// The device manager can manage the device life cycle through these interfaces provided by DeviceMapperService. +// When device manager gets a message of device management from cloudcore, it should call the corresponding grpc interface +// to make the mapper maintain the list of device information. +service DeviceMapperService { + // RegisterDevice registers a device to the device mapper. + // Device manager registers a device instance with the information of device + // to the mapper through the interface of RegisterDevice. + // When the mapper gets the request of register with device information, + // it should add the device to the device list and connect to the real physical device via the specific protocol. + rpc RegisterDevice(RegisterDeviceRequest) returns (RegisterDeviceResponse) {} + // RemoveDevice unregisters a device to the device mapper. + // Device manager unregisters a device instance with the name of device + // to the mapper through the interface of RemoveDevice. + // When the mapper gets the request of unregister with device name, + // it should remove the device from the device list and disconnect to the real physical device. + rpc RemoveDevice(RemoveDeviceRequest) returns (RemoveDeviceResponse) {} + // UpdateDevice updates a device to the device mapper + // Device manager updates the information of a device used by the mapper + // through the interface of UpdateDevice. + // The information of a device includes the meta data and the status data of a device. + // When the mapper gets the request of updating with the information of a device, + // it should update the device of the device list and connect to the real physical device via the updated information. + rpc UpdateDevice(UpdateDeviceRequest) returns (UpdateDeviceResponse) {} + // CreateDeviceModel creates a device model to the device mapper. + // Device manager sends the information of device model to the mapper + // through the interface of CreateDeviceModel. + // When the mapper gets the request of creating with the information of device model, + // it should create a new device model to the list of device models. + rpc CreateDeviceModel(CreateDeviceModelRequest) returns (CreateDeviceModelResponse) {} + // RemoveDeviceModel remove a device model to the device mapper. + // Device manager sends the name of device model to the mapper + // through the interface of RemoveDeviceModel. + // When the mapper gets the request of removing with the name of device model, + // it should remove the device model to the list of device models. + rpc RemoveDeviceModel(RemoveDeviceModelRequest) returns (RemoveDeviceModelResponse) {} + // UpdateDeviceModel update a device model to the device mapper. + // Device manager sends the information of device model to the mapper + // through the interface of UpdateDeviceModel. + // When the mapper gets the request of updating with the information of device model, + // it should update the device model to the list of device models. + rpc UpdateDeviceModel(UpdateDeviceModelRequest) returns (UpdateDeviceModelResponse) {} + // GetDevice get the information of a device from the device mapper. + // Device sends the request of querying device information with the device name to the mapper + // through the interface of GetDevice. + // When the mapper gets the request of querying with the device name, + // it should return the device information. + rpc GetDevice(GetDeviceRequest) returns (GetDeviceResponse) {} +} + +message MapperRegisterRequest { + // The flag to show how device manager returns. + // True means device manager should return the device list in the response. + // False means device manager should just return nothing. + bool withData = 1; + // Mapper information to be registered to the device manager. + MapperInfo mapper = 2; +} + +message MapperRegisterResponse { + // List of device models which the mapper maintains. + repeated DeviceModel modelList = 1; + // List of devices which the mapper maintains. + repeated Device deviceList = 2; +} + +// DeviceModel specifies the information of a device model. +message DeviceModel { + // Name of a device model. + string name = 1; + // Specification of a device model. + DeviceModelSpec spec = 2; +} + +// DeviceModelSpec is the specification of a device model. +message DeviceModelSpec { + // The properties provided by the device of this device model. + repeated ModelProperty properties = 1; + // The commands executed by the device of this device model. + repeated DeviceCommand commands = 2; +} + +// ModelProperty is the property of a device. +message ModelProperty { + // The name of this property. + string name = 1; + // The description of this property. + string description = 2; + // The specific type of this property. + string type = 3; + // The access mode of this property, ReadOnly or ReadWrite. + string accessMode = 4; + // The minimum value of this property. + string minimum = 5; + // The maximum value of this property. + string maximum = 6; + // The unit of this property. + string unit = 7; +} + +// DeviceCommond is the description of a command which the device supports. +message DeviceCommand { + // Name of the command. + string name = 1; + // Url of the command to access. + string url = 2; + // Method of the command. + string method = 3; + // Status code list which the command can return. + repeated string status_code = 4; + // Parameter list which the command carries. + repeated string parameters = 5; + // Response examples of the command. + bytes response = 6; +} + +// Device is the description of a device instance. +message Device { + // Name of the device. + string name = 1; + // Specification of the device. + DeviceSpec spec = 2; + // Status of the device. + DeviceStatus status = 3; +} + +// DeviceSpec is the specification of the device. +message DeviceSpec { + // The device model which the device references. + string deviceModelReference = 1; + // The specific config of the protocol to access to the device. + ProtocolConfig protocol = 2; + // List of properties which describe the device properties. + repeated DeviceProperty properties = 3; +} + +// DeviceProperty describes the specifics all the properties of the device. +message DeviceProperty { + // The device property name to be accessed. It must be unique. + string name = 1; + // the desired value of the property configured by device manager. + TwinProperty desired = 2; + // Visitors are intended to be consumed by device mappers which connect to devices + // and collect data / perform actions on the device. + VisitorConfig visitors = 3; + // Define how frequent mapper will report the value. + int64 reportCycle = 4; + // Define how frequent mapper will collect from device. + int64 collectCycle = 5; + // whether be reported to the cloud + bool reportToCloud = 6; + // PushMethod represents the protocol used to push data, + PushMethod pushMethod = 7; +} + +// ProtocolConfig is the specific config of the protocol to access to the device. +message ProtocolConfig { + // the name of the customized protocol. + string protocolName = 1; + // the config data of the customized protocol. + CustomizedValue configData = 2; +} + +// the visitor to collect the properties of the device of customized protocol. +message VisitorConfig { + // the name of the customized protocol. + string protocolName = 1; + // the config data of the customized protocol. + CustomizedValue configData = 2; +} + +// CustomizedValue is the customized value for developers. +message CustomizedValue { + // data is the customized value and it can be any form. + map data = 1; +} + +message PushMethod { + PushMethodHTTP http = 1; + PushMethodMQTT mqtt = 2; + DBMethod dbMethod = 3; +} + +message PushMethodHTTP { + string hostname = 1; + int64 port = 2; + string requestpath = 3; + int64 timeout = 4; +} + +message PushMethodMQTT { + // broker address, like mqtt://127.0.0.1:1883 + string address = 1; + // publish topic for mqtt + string topic = 2; + // qos of mqtt publish param + int32 qos = 3; + // Is the message retained + bool retained = 4; +} + +message DBMethod{ + // the config of database . + DBMethodInfluxdb2 influxdb2 = 1; +} + +message DBMethodInfluxdb2{ + // the config of influx database. + Influxdb2ClientConfig influxdb2ClientConfig = 1; + Influxdb2DataConfig influxdb2DataConfig = 2; +} + +message Influxdb2DataConfig{ + // data config when push data to influx + string measurement = 1; + map tag = 2; + string fieldKey = 3; +} + +message Influxdb2ClientConfig{ + // influx database url + string url = 1; + // usr org in influx database + string org = 2; + // usr bucket in influx database + string bucket = 3; +} + +// MapperInfo is the information of mapper. +message MapperInfo { + // name of the mapper. + string name = 1; + // version of the mapper. + string version = 2; + // api version of the mapper. + string api_version = 3; + // the protocol of the mapper. + string protocol = 4; + // the address of the mapper. it is a unix domain socket of grpc. + bytes address = 5; + // the state of the mapper. + string state = 6; +} + +message ReportDeviceStatusRequest { + string deviceName = 1; + DeviceStatus reportedDevice = 2; +} + +// DeviceStatus is the status of the device. +message DeviceStatus { + // the device twins of the device. + repeated Twin twins = 1; +} + +// Twin is the digital model of a device. It contains a series of properties. +message Twin { + // the name of the property. + string propertyName = 1; + // the observedDesired value of the property configured by mapper. + TwinProperty observedDesired = 2; + // the reported value of the property from the real device. + TwinProperty reported = 3; +} + +// TwinProperty is the specification of the property. +message TwinProperty { + // the value of the property. + string value = 1; + // the metadata to describe this property. + map metadata = 2; +} + +message ReportDeviceStatusResponse {} + +message RegisterDeviceRequest { + Device device = 1; +} + +message RegisterDeviceResponse { + string deviceName = 1; +} + +message CreateDeviceModelRequest { + DeviceModel model = 1; +} + +message CreateDeviceModelResponse { + string deviceModelName = 1; +} + +message RemoveDeviceRequest { + string deviceName = 1; +} + +message RemoveDeviceResponse {} + +message RemoveDeviceModelRequest { + string modelName = 1; +} + +message RemoveDeviceModelResponse {} + +message UpdateDeviceRequest { + Device device = 1; +} + +message UpdateDeviceResponse {} + +message UpdateDeviceModelRequest { + DeviceModel model = 1; +} + +message UpdateDeviceModelResponse {} + +message GetDeviceRequest { + string deviceName = 1; +} + +message GetDeviceResponse { + Device device = 1; +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/dmi-api/api_grpc.pb.go b/mappers/kubeedge-v1.15.0/modbus/pkg/dmi-api/api_grpc.pb.go new file mode 100644 index 00000000..092fdb34 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/dmi-api/api_grpc.pb.go @@ -0,0 +1,559 @@ +// +//Copyright 2023 The KubeEdge Authors. +// +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. + +// To regenerate api.pb.go run hack/generate-dmi.sh + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.19.4 +// source: api.proto + +package v1beta1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + DeviceManagerService_MapperRegister_FullMethodName = "/v1beta1.DeviceManagerService/MapperRegister" + DeviceManagerService_ReportDeviceStatus_FullMethodName = "/v1beta1.DeviceManagerService/ReportDeviceStatus" +) + +// DeviceManagerServiceClient is the client API for DeviceManagerService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type DeviceManagerServiceClient interface { + // MapperRegister registers the information of the mapper to device manager + // when the mapper is online. Device manager returns the list of devices and device models which + // this mapper should manage. + MapperRegister(ctx context.Context, in *MapperRegisterRequest, opts ...grpc.CallOption) (*MapperRegisterResponse, error) + // ReportDeviceStatus reports the status of devices to device manager. + // When the mapper collects some properties of a device, it can make them a map of device twins + // and report it to the device manager through the interface of ReportDeviceStatus. + ReportDeviceStatus(ctx context.Context, in *ReportDeviceStatusRequest, opts ...grpc.CallOption) (*ReportDeviceStatusResponse, error) +} + +type deviceManagerServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewDeviceManagerServiceClient(cc grpc.ClientConnInterface) DeviceManagerServiceClient { + return &deviceManagerServiceClient{cc} +} + +func (c *deviceManagerServiceClient) MapperRegister(ctx context.Context, in *MapperRegisterRequest, opts ...grpc.CallOption) (*MapperRegisterResponse, error) { + out := new(MapperRegisterResponse) + err := c.cc.Invoke(ctx, DeviceManagerService_MapperRegister_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceManagerServiceClient) ReportDeviceStatus(ctx context.Context, in *ReportDeviceStatusRequest, opts ...grpc.CallOption) (*ReportDeviceStatusResponse, error) { + out := new(ReportDeviceStatusResponse) + err := c.cc.Invoke(ctx, DeviceManagerService_ReportDeviceStatus_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DeviceManagerServiceServer is the server API for DeviceManagerService service. +// All implementations must embed UnimplementedDeviceManagerServiceServer +// for forward compatibility +type DeviceManagerServiceServer interface { + // MapperRegister registers the information of the mapper to device manager + // when the mapper is online. Device manager returns the list of devices and device models which + // this mapper should manage. + MapperRegister(context.Context, *MapperRegisterRequest) (*MapperRegisterResponse, error) + // ReportDeviceStatus reports the status of devices to device manager. + // When the mapper collects some properties of a device, it can make them a map of device twins + // and report it to the device manager through the interface of ReportDeviceStatus. + ReportDeviceStatus(context.Context, *ReportDeviceStatusRequest) (*ReportDeviceStatusResponse, error) + mustEmbedUnimplementedDeviceManagerServiceServer() +} + +// UnimplementedDeviceManagerServiceServer must be embedded to have forward compatible implementations. +type UnimplementedDeviceManagerServiceServer struct { +} + +func (UnimplementedDeviceManagerServiceServer) MapperRegister(context.Context, *MapperRegisterRequest) (*MapperRegisterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MapperRegister not implemented") +} +func (UnimplementedDeviceManagerServiceServer) ReportDeviceStatus(context.Context, *ReportDeviceStatusRequest) (*ReportDeviceStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReportDeviceStatus not implemented") +} +func (UnimplementedDeviceManagerServiceServer) mustEmbedUnimplementedDeviceManagerServiceServer() {} + +// UnsafeDeviceManagerServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to DeviceManagerServiceServer will +// result in compilation errors. +type UnsafeDeviceManagerServiceServer interface { + mustEmbedUnimplementedDeviceManagerServiceServer() +} + +func RegisterDeviceManagerServiceServer(s grpc.ServiceRegistrar, srv DeviceManagerServiceServer) { + s.RegisterService(&DeviceManagerService_ServiceDesc, srv) +} + +func _DeviceManagerService_MapperRegister_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MapperRegisterRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceManagerServiceServer).MapperRegister(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DeviceManagerService_MapperRegister_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceManagerServiceServer).MapperRegister(ctx, req.(*MapperRegisterRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceManagerService_ReportDeviceStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReportDeviceStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceManagerServiceServer).ReportDeviceStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DeviceManagerService_ReportDeviceStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceManagerServiceServer).ReportDeviceStatus(ctx, req.(*ReportDeviceStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// DeviceManagerService_ServiceDesc is the grpc.ServiceDesc for DeviceManagerService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var DeviceManagerService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "v1beta1.DeviceManagerService", + HandlerType: (*DeviceManagerServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "MapperRegister", + Handler: _DeviceManagerService_MapperRegister_Handler, + }, + { + MethodName: "ReportDeviceStatus", + Handler: _DeviceManagerService_ReportDeviceStatus_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api.proto", +} + +const ( + DeviceMapperService_RegisterDevice_FullMethodName = "/v1beta1.DeviceMapperService/RegisterDevice" + DeviceMapperService_RemoveDevice_FullMethodName = "/v1beta1.DeviceMapperService/RemoveDevice" + DeviceMapperService_UpdateDevice_FullMethodName = "/v1beta1.DeviceMapperService/UpdateDevice" + DeviceMapperService_CreateDeviceModel_FullMethodName = "/v1beta1.DeviceMapperService/CreateDeviceModel" + DeviceMapperService_RemoveDeviceModel_FullMethodName = "/v1beta1.DeviceMapperService/RemoveDeviceModel" + DeviceMapperService_UpdateDeviceModel_FullMethodName = "/v1beta1.DeviceMapperService/UpdateDeviceModel" + DeviceMapperService_GetDevice_FullMethodName = "/v1beta1.DeviceMapperService/GetDevice" +) + +// DeviceMapperServiceClient is the client API for DeviceMapperService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type DeviceMapperServiceClient interface { + // RegisterDevice registers a device to the device mapper. + // Device manager registers a device instance with the information of device + // to the mapper through the interface of RegisterDevice. + // When the mapper gets the request of register with device information, + // it should add the device to the device list and connect to the real physical device via the specific protocol. + RegisterDevice(ctx context.Context, in *RegisterDeviceRequest, opts ...grpc.CallOption) (*RegisterDeviceResponse, error) + // RemoveDevice unregisters a device to the device mapper. + // Device manager unregisters a device instance with the name of device + // to the mapper through the interface of RemoveDevice. + // When the mapper gets the request of unregister with device name, + // it should remove the device from the device list and disconnect to the real physical device. + RemoveDevice(ctx context.Context, in *RemoveDeviceRequest, opts ...grpc.CallOption) (*RemoveDeviceResponse, error) + // UpdateDevice updates a device to the device mapper + // Device manager updates the information of a device used by the mapper + // through the interface of UpdateDevice. + // The information of a device includes the meta data and the status data of a device. + // When the mapper gets the request of updating with the information of a device, + // it should update the device of the device list and connect to the real physical device via the updated information. + UpdateDevice(ctx context.Context, in *UpdateDeviceRequest, opts ...grpc.CallOption) (*UpdateDeviceResponse, error) + // CreateDeviceModel creates a device model to the device mapper. + // Device manager sends the information of device model to the mapper + // through the interface of CreateDeviceModel. + // When the mapper gets the request of creating with the information of device model, + // it should create a new device model to the list of device models. + CreateDeviceModel(ctx context.Context, in *CreateDeviceModelRequest, opts ...grpc.CallOption) (*CreateDeviceModelResponse, error) + // RemoveDeviceModel remove a device model to the device mapper. + // Device manager sends the name of device model to the mapper + // through the interface of RemoveDeviceModel. + // When the mapper gets the request of removing with the name of device model, + // it should remove the device model to the list of device models. + RemoveDeviceModel(ctx context.Context, in *RemoveDeviceModelRequest, opts ...grpc.CallOption) (*RemoveDeviceModelResponse, error) + // UpdateDeviceModel update a device model to the device mapper. + // Device manager sends the information of device model to the mapper + // through the interface of UpdateDeviceModel. + // When the mapper gets the request of updating with the information of device model, + // it should update the device model to the list of device models. + UpdateDeviceModel(ctx context.Context, in *UpdateDeviceModelRequest, opts ...grpc.CallOption) (*UpdateDeviceModelResponse, error) + // GetDevice get the information of a device from the device mapper. + // Device sends the request of querying device information with the device name to the mapper + // through the interface of GetDevice. + // When the mapper gets the request of querying with the device name, + // it should return the device information. + GetDevice(ctx context.Context, in *GetDeviceRequest, opts ...grpc.CallOption) (*GetDeviceResponse, error) +} + +type deviceMapperServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewDeviceMapperServiceClient(cc grpc.ClientConnInterface) DeviceMapperServiceClient { + return &deviceMapperServiceClient{cc} +} + +func (c *deviceMapperServiceClient) RegisterDevice(ctx context.Context, in *RegisterDeviceRequest, opts ...grpc.CallOption) (*RegisterDeviceResponse, error) { + out := new(RegisterDeviceResponse) + err := c.cc.Invoke(ctx, DeviceMapperService_RegisterDevice_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceMapperServiceClient) RemoveDevice(ctx context.Context, in *RemoveDeviceRequest, opts ...grpc.CallOption) (*RemoveDeviceResponse, error) { + out := new(RemoveDeviceResponse) + err := c.cc.Invoke(ctx, DeviceMapperService_RemoveDevice_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceMapperServiceClient) UpdateDevice(ctx context.Context, in *UpdateDeviceRequest, opts ...grpc.CallOption) (*UpdateDeviceResponse, error) { + out := new(UpdateDeviceResponse) + err := c.cc.Invoke(ctx, DeviceMapperService_UpdateDevice_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceMapperServiceClient) CreateDeviceModel(ctx context.Context, in *CreateDeviceModelRequest, opts ...grpc.CallOption) (*CreateDeviceModelResponse, error) { + out := new(CreateDeviceModelResponse) + err := c.cc.Invoke(ctx, DeviceMapperService_CreateDeviceModel_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceMapperServiceClient) RemoveDeviceModel(ctx context.Context, in *RemoveDeviceModelRequest, opts ...grpc.CallOption) (*RemoveDeviceModelResponse, error) { + out := new(RemoveDeviceModelResponse) + err := c.cc.Invoke(ctx, DeviceMapperService_RemoveDeviceModel_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceMapperServiceClient) UpdateDeviceModel(ctx context.Context, in *UpdateDeviceModelRequest, opts ...grpc.CallOption) (*UpdateDeviceModelResponse, error) { + out := new(UpdateDeviceModelResponse) + err := c.cc.Invoke(ctx, DeviceMapperService_UpdateDeviceModel_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deviceMapperServiceClient) GetDevice(ctx context.Context, in *GetDeviceRequest, opts ...grpc.CallOption) (*GetDeviceResponse, error) { + out := new(GetDeviceResponse) + err := c.cc.Invoke(ctx, DeviceMapperService_GetDevice_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DeviceMapperServiceServer is the server API for DeviceMapperService service. +// All implementations must embed UnimplementedDeviceMapperServiceServer +// for forward compatibility +type DeviceMapperServiceServer interface { + // RegisterDevice registers a device to the device mapper. + // Device manager registers a device instance with the information of device + // to the mapper through the interface of RegisterDevice. + // When the mapper gets the request of register with device information, + // it should add the device to the device list and connect to the real physical device via the specific protocol. + RegisterDevice(context.Context, *RegisterDeviceRequest) (*RegisterDeviceResponse, error) + // RemoveDevice unregisters a device to the device mapper. + // Device manager unregisters a device instance with the name of device + // to the mapper through the interface of RemoveDevice. + // When the mapper gets the request of unregister with device name, + // it should remove the device from the device list and disconnect to the real physical device. + RemoveDevice(context.Context, *RemoveDeviceRequest) (*RemoveDeviceResponse, error) + // UpdateDevice updates a device to the device mapper + // Device manager updates the information of a device used by the mapper + // through the interface of UpdateDevice. + // The information of a device includes the meta data and the status data of a device. + // When the mapper gets the request of updating with the information of a device, + // it should update the device of the device list and connect to the real physical device via the updated information. + UpdateDevice(context.Context, *UpdateDeviceRequest) (*UpdateDeviceResponse, error) + // CreateDeviceModel creates a device model to the device mapper. + // Device manager sends the information of device model to the mapper + // through the interface of CreateDeviceModel. + // When the mapper gets the request of creating with the information of device model, + // it should create a new device model to the list of device models. + CreateDeviceModel(context.Context, *CreateDeviceModelRequest) (*CreateDeviceModelResponse, error) + // RemoveDeviceModel remove a device model to the device mapper. + // Device manager sends the name of device model to the mapper + // through the interface of RemoveDeviceModel. + // When the mapper gets the request of removing with the name of device model, + // it should remove the device model to the list of device models. + RemoveDeviceModel(context.Context, *RemoveDeviceModelRequest) (*RemoveDeviceModelResponse, error) + // UpdateDeviceModel update a device model to the device mapper. + // Device manager sends the information of device model to the mapper + // through the interface of UpdateDeviceModel. + // When the mapper gets the request of updating with the information of device model, + // it should update the device model to the list of device models. + UpdateDeviceModel(context.Context, *UpdateDeviceModelRequest) (*UpdateDeviceModelResponse, error) + // GetDevice get the information of a device from the device mapper. + // Device sends the request of querying device information with the device name to the mapper + // through the interface of GetDevice. + // When the mapper gets the request of querying with the device name, + // it should return the device information. + GetDevice(context.Context, *GetDeviceRequest) (*GetDeviceResponse, error) + mustEmbedUnimplementedDeviceMapperServiceServer() +} + +// UnimplementedDeviceMapperServiceServer must be embedded to have forward compatible implementations. +type UnimplementedDeviceMapperServiceServer struct { +} + +func (UnimplementedDeviceMapperServiceServer) RegisterDevice(context.Context, *RegisterDeviceRequest) (*RegisterDeviceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterDevice not implemented") +} +func (UnimplementedDeviceMapperServiceServer) RemoveDevice(context.Context, *RemoveDeviceRequest) (*RemoveDeviceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveDevice not implemented") +} +func (UnimplementedDeviceMapperServiceServer) UpdateDevice(context.Context, *UpdateDeviceRequest) (*UpdateDeviceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateDevice not implemented") +} +func (UnimplementedDeviceMapperServiceServer) CreateDeviceModel(context.Context, *CreateDeviceModelRequest) (*CreateDeviceModelResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateDeviceModel not implemented") +} +func (UnimplementedDeviceMapperServiceServer) RemoveDeviceModel(context.Context, *RemoveDeviceModelRequest) (*RemoveDeviceModelResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveDeviceModel not implemented") +} +func (UnimplementedDeviceMapperServiceServer) UpdateDeviceModel(context.Context, *UpdateDeviceModelRequest) (*UpdateDeviceModelResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateDeviceModel not implemented") +} +func (UnimplementedDeviceMapperServiceServer) GetDevice(context.Context, *GetDeviceRequest) (*GetDeviceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDevice not implemented") +} +func (UnimplementedDeviceMapperServiceServer) mustEmbedUnimplementedDeviceMapperServiceServer() {} + +// UnsafeDeviceMapperServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to DeviceMapperServiceServer will +// result in compilation errors. +type UnsafeDeviceMapperServiceServer interface { + mustEmbedUnimplementedDeviceMapperServiceServer() +} + +func RegisterDeviceMapperServiceServer(s grpc.ServiceRegistrar, srv DeviceMapperServiceServer) { + s.RegisterService(&DeviceMapperService_ServiceDesc, srv) +} + +func _DeviceMapperService_RegisterDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterDeviceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceMapperServiceServer).RegisterDevice(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DeviceMapperService_RegisterDevice_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceMapperServiceServer).RegisterDevice(ctx, req.(*RegisterDeviceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceMapperService_RemoveDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveDeviceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceMapperServiceServer).RemoveDevice(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DeviceMapperService_RemoveDevice_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceMapperServiceServer).RemoveDevice(ctx, req.(*RemoveDeviceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceMapperService_UpdateDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateDeviceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceMapperServiceServer).UpdateDevice(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DeviceMapperService_UpdateDevice_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceMapperServiceServer).UpdateDevice(ctx, req.(*UpdateDeviceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceMapperService_CreateDeviceModel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateDeviceModelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceMapperServiceServer).CreateDeviceModel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DeviceMapperService_CreateDeviceModel_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceMapperServiceServer).CreateDeviceModel(ctx, req.(*CreateDeviceModelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceMapperService_RemoveDeviceModel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveDeviceModelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceMapperServiceServer).RemoveDeviceModel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DeviceMapperService_RemoveDeviceModel_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceMapperServiceServer).RemoveDeviceModel(ctx, req.(*RemoveDeviceModelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceMapperService_UpdateDeviceModel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateDeviceModelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceMapperServiceServer).UpdateDeviceModel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DeviceMapperService_UpdateDeviceModel_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceMapperServiceServer).UpdateDeviceModel(ctx, req.(*UpdateDeviceModelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeviceMapperService_GetDevice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetDeviceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeviceMapperServiceServer).GetDevice(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DeviceMapperService_GetDevice_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeviceMapperServiceServer).GetDevice(ctx, req.(*GetDeviceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// DeviceMapperService_ServiceDesc is the grpc.ServiceDesc for DeviceMapperService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var DeviceMapperService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "v1beta1.DeviceMapperService", + HandlerType: (*DeviceMapperServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "RegisterDevice", + Handler: _DeviceMapperService_RegisterDevice_Handler, + }, + { + MethodName: "RemoveDevice", + Handler: _DeviceMapperService_RemoveDevice_Handler, + }, + { + MethodName: "UpdateDevice", + Handler: _DeviceMapperService_UpdateDevice_Handler, + }, + { + MethodName: "CreateDeviceModel", + Handler: _DeviceMapperService_CreateDeviceModel_Handler, + }, + { + MethodName: "RemoveDeviceModel", + Handler: _DeviceMapperService_RemoveDeviceModel_Handler, + }, + { + MethodName: "UpdateDeviceModel", + Handler: _DeviceMapperService_UpdateDeviceModel_Handler, + }, + { + MethodName: "GetDevice", + Handler: _DeviceMapperService_GetDevice_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api.proto", +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/global/global.go b/mappers/kubeedge-v1.15.0/modbus/pkg/global/global.go new file mode 100644 index 00000000..730e7584 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/global/global.go @@ -0,0 +1,58 @@ +package global + +import ( + "github.com/kubeedge/modbus/pkg/common" + "github.com/kubeedge/modbus/pkg/config" +) + +// DevPanel defined operations on devices, manage the lifecycle of devices +type DevPanel interface { + // DevStart start device to collect/push/save data to edgecore/app/database + DevStart() + // DevInit get device info by dmi interface + DevInit(cfg *config.Config) error + // UpdateDev update device's config and restart the device + UpdateDev(model *common.DeviceModel, device *common.DeviceInstance, protocol *common.ProtocolConfig) + // UpdateDevTwins update device twin's config and restart the device + UpdateDevTwins(deviceID string, twins []common.Twin) error + // DealDeviceTwinGet get device's twin data + DealDeviceTwinGet(deviceID string, twinName string) (interface{}, error) + // GetDevice get device's instance info + GetDevice(deviceID string) (interface{}, error) + // RemoveDevice stop device and remove device + RemoveDevice(deviceID string) error + // GetModel get model's info + GetModel(modelName string) (common.DeviceModel, error) + // UpdateModel update model in map only + UpdateModel(model *common.DeviceModel) + // RemoveModel remove model in map only + RemoveModel(modelName string) + // GetTwinResult get device's property value and datatype + GetTwinResult(deviceID string, twinName string) (string, string, error) +} + +// DataPanel defined push method, parse the push operation in CRD and execute it +type DataPanel interface { + // TODO add more interface + + // InitPushMethod initialization operation before push + InitPushMethod() error + // Push implement push operation + Push(data *common.DataModel) +} + +// DataBaseClient defined database interface, save data and provide data to REST API +type DataBaseClient interface { + // TODO add more interface + + InitDbClient() error + CloseSession() + + AddData(data *common.DataModel) + + GetDataByDeviceName(deviceName string) ([]*common.DataModel, error) + GetPropertyDataByDeviceName(deviceName string, propertyData string) ([]*common.DataModel, error) + GetDataByTimeRange(start int64, end int64) ([]*common.DataModel, error) + + DeleteDataByTimeRange(start int64, end int64) ([]*common.DataModel, error) +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/grpcclient/config.go b/mappers/kubeedge-v1.15.0/modbus/pkg/grpcclient/config.go new file mode 100644 index 00000000..2ec979b4 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/grpcclient/config.go @@ -0,0 +1,12 @@ +package grpcclient + +import ( + "github.com/kubeedge/modbus/pkg/config" +) + +var cfg *config.Config + +func Init(c *config.Config) { + cfg = &config.Config{} + cfg = c +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/grpcclient/register.go b/mappers/kubeedge-v1.15.0/modbus/pkg/grpcclient/register.go new file mode 100644 index 00000000..140dcc9f --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/grpcclient/register.go @@ -0,0 +1,59 @@ +package grpcclient + +import ( + "context" + "fmt" + "net" + "time" + + "google.golang.org/grpc" + + "github.com/kubeedge/modbus/pkg/common" + dmiapi "github.com/kubeedge/modbus/pkg/dmi-api" +) + +// RegisterMapper if withData is true, edgecore will send device and model list. +func RegisterMapper(withData bool) ([]*dmiapi.Device, []*dmiapi.DeviceModel, error) { + // connect grpc server + conn, err := grpc.Dial(cfg.Common.EdgeCoreSock, + grpc.WithInsecure(), + grpc.WithBlock(), + grpc.WithContextDialer( + func(ctx context.Context, s string) (net.Conn, error) { + unixAddress, err := net.ResolveUnixAddr("unix", cfg.Common.EdgeCoreSock) + if err != nil { + return nil, err + } + return net.DialUnix("unix", nil, unixAddress) + }, + ), + ) + if err != nil { + return nil, nil, fmt.Errorf("did not connect: %v", err) + } + defer conn.Close() + + // init Greeter client + c := dmiapi.NewDeviceManagerServiceClient(conn) + + // init ctx,set timeout + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + resp, err := c.MapperRegister(ctx, &dmiapi.MapperRegisterRequest{ + WithData: withData, + Mapper: &dmiapi.MapperInfo{ + Name: cfg.Common.Name, + Version: cfg.Common.Version, + ApiVersion: cfg.Common.APIVersion, + Protocol: cfg.Common.Protocol, + Address: []byte(cfg.GrpcServer.SocketPath), + State: common.DEVSTOK, + }, + }) + if err != nil { + return nil, nil, err + } + + return resp.DeviceList, resp.ModelList, err +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/grpcclient/report.go b/mappers/kubeedge-v1.15.0/modbus/pkg/grpcclient/report.go new file mode 100644 index 00000000..f430b443 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/grpcclient/report.go @@ -0,0 +1,43 @@ +package grpcclient + +import ( + "context" + "fmt" + "net" + "time" + + "google.golang.org/grpc" + + dmiapi "github.com/kubeedge/modbus/pkg/dmi-api" +) + +// ReportDeviceStatus report device status to edgecore +func ReportDeviceStatus(request *dmiapi.ReportDeviceStatusRequest) error { + conn, err := grpc.Dial(cfg.Common.EdgeCoreSock, + grpc.WithInsecure(), + grpc.WithBlock(), + grpc.WithContextDialer( + func(ctx context.Context, s string) (net.Conn, error) { + unixAddress, err := net.ResolveUnixAddr("unix", cfg.Common.EdgeCoreSock) + if err != nil { + return nil, err + } + return net.DialUnix("unix", nil, unixAddress) + }, + ), + ) + if err != nil { + return fmt.Errorf("did not connect: %v", err) + } + defer conn.Close() + + // init Greeter client + c := dmiapi.NewDeviceManagerServiceClient(conn) + + // init context,set timeout + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + _, err = c.ReportDeviceStatus(ctx, request) + return err +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/grpcserver/device.go b/mappers/kubeedge-v1.15.0/modbus/pkg/grpcserver/device.go new file mode 100644 index 00000000..2bb424a3 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/grpcserver/device.go @@ -0,0 +1,159 @@ +package grpcserver + +import ( + "context" + "errors" + "fmt" + "time" + + "k8s.io/klog/v2" + "reflect" + + "github.com/kubeedge/modbus/pkg/common" + dmiapi "github.com/kubeedge/modbus/pkg/dmi-api" + "github.com/kubeedge/modbus/pkg/util/parse" +) + +func (s *Server) RegisterDevice(ctx context.Context, request *dmiapi.RegisterDeviceRequest) (*dmiapi.RegisterDeviceResponse, error) { + klog.V(3).Info("RegisterDevice") + device := request.GetDevice() + if device == nil { + return nil, errors.New("device is nil") + } + if _, err := s.devPanel.GetDevice(device.Name); err == nil { + // The device has been registered + return &dmiapi.RegisterDeviceResponse{DeviceName: device.Name}, nil + } + + var model common.DeviceModel + var err error + for i := 0; i < 3; i++ { + model, err = s.devPanel.GetModel(device.Spec.DeviceModelReference) + if err != nil { + klog.Errorf("deviceModel %s not found, err: %s", device.Spec.DeviceModelReference, err) + time.Sleep(1 * time.Second) + } else { + break + } + } + if err != nil { + return nil, fmt.Errorf("deviceModel %s not found, err: %s", device.Spec.DeviceModelReference, err) + } + protocol, err := parse.BuildProtocolFromGrpc(device) + if err != nil { + return nil, fmt.Errorf("parse device %s protocol failed, err: %s", device.Name, err) + } + klog.Infof("model: %+v", model) + deviceInstance, err := parse.ParseDeviceFromGrpc(device, &model) + + if err != nil { + return nil, fmt.Errorf("parse device %s instance failed, err: %s", device.Name, err) + } + + deviceInstance.PProtocol = protocol + s.devPanel.UpdateDev(&model, deviceInstance, &protocol) + + return &dmiapi.RegisterDeviceResponse{DeviceName: device.Name}, nil +} + +func (s *Server) RemoveDevice(ctx context.Context, request *dmiapi.RemoveDeviceRequest) (*dmiapi.RemoveDeviceResponse, error) { + if request.GetDeviceName() == "" { + return nil, errors.New("device name is nil") + } + + return &dmiapi.RemoveDeviceResponse{}, s.devPanel.RemoveDevice(request.GetDeviceName()) +} + +func (s *Server) UpdateDevice(ctx context.Context, request *dmiapi.UpdateDeviceRequest) (*dmiapi.UpdateDeviceResponse, error) { + klog.V(3).Info("UpdateDevice") + device := request.GetDevice() + if device == nil { + return nil, errors.New("device is nil") + } + + model, err := s.devPanel.GetModel(device.Spec.DeviceModelReference) + if err != nil { + return nil, fmt.Errorf("deviceModel %s not found, err: %s", device.Spec.DeviceModelReference, err) + } + protocol, err := parse.BuildProtocolFromGrpc(device) + if err != nil { + return nil, fmt.Errorf("parse device %s protocol failed, err: %s", device.Name, err) + } + + klog.V(3).Infof("model: %+v", model) + deviceInstance, err := parse.ParseDeviceFromGrpc(device, &model) + if err != nil { + return nil, fmt.Errorf("parse device %s instance failed, err: %s", device.Name, err) + } + deviceInstance.PProtocol = protocol + + s.devPanel.UpdateDev(&model, deviceInstance, &protocol) + + return &dmiapi.UpdateDeviceResponse{}, nil +} + +func (s *Server) CreateDeviceModel(ctx context.Context, request *dmiapi.CreateDeviceModelRequest) (*dmiapi.CreateDeviceModelResponse, error) { + deviceModel := request.GetModel() + klog.Infof("start create deviceModel: %v", deviceModel.Name) + if deviceModel == nil { + return nil, errors.New("deviceModel is nil") + } + + model := parse.ParseDeviceModelFromGrpc(deviceModel) + + s.devPanel.UpdateModel(&model) + + klog.Infof("create deviceModel done: %v", deviceModel.Name) + + return &dmiapi.CreateDeviceModelResponse{DeviceModelName: deviceModel.Name}, nil +} + +func (s *Server) UpdateDeviceModel(ctx context.Context, request *dmiapi.UpdateDeviceModelRequest) (*dmiapi.UpdateDeviceModelResponse, error) { + deviceModel := request.GetModel() + if deviceModel == nil { + return nil, errors.New("deviceModel is nil") + } + if _, err := s.devPanel.GetModel(deviceModel.Name); err != nil { + return nil, fmt.Errorf("update deviceModel %s failed, not existed", deviceModel.Name) + } + + model := parse.ParseDeviceModelFromGrpc(deviceModel) + + s.devPanel.UpdateModel(&model) + + return &dmiapi.UpdateDeviceModelResponse{}, nil +} + +func (s *Server) RemoveDeviceModel(ctx context.Context, request *dmiapi.RemoveDeviceModelRequest) (*dmiapi.RemoveDeviceModelResponse, error) { + s.devPanel.RemoveModel(request.ModelName) + + return &dmiapi.RemoveDeviceModelResponse{}, nil +} + +func (s *Server) GetDevice(ctx context.Context, request *dmiapi.GetDeviceRequest) (*dmiapi.GetDeviceResponse, error) { + if request.GetDeviceName() == "" { + return nil, errors.New("device name is nil") + } + + device, err := s.devPanel.GetDevice(request.GetDeviceName()) + if err != nil { + return nil, err + } + res := &dmiapi.GetDeviceResponse{ + Device: &dmiapi.Device{ + Status: &dmiapi.DeviceStatus{}, + }, + } + deviceValue := reflect.ValueOf(device) + twinsValue := deviceValue.FieldByName("Instance").FieldByName("Twins") + if !twinsValue.IsValid() { + return nil, fmt.Errorf("twins field not found") + } + twins, err := parse.ConvTwinsToGrpc(twinsValue.Interface().([]common.Twin)) + if err != nil { + return nil, err + } + res.Device.Status.Twins = twins + //res.Device.Status.State = common.DEVSTOK + return res, nil +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/grpcserver/server.go b/mappers/kubeedge-v1.15.0/modbus/pkg/grpcserver/server.go new file mode 100644 index 00000000..5f42b21c --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/grpcserver/server.go @@ -0,0 +1,79 @@ +package grpcserver + +import ( + "fmt" + "net" + "os" + + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" + "k8s.io/klog/v2" + + dmiapi "github.com/kubeedge/modbus/pkg/dmi-api" + "github.com/kubeedge/modbus/pkg/global" +) + +type Config struct { + SockPath string `json:"sock_path"` + Protocol string `json:"protocol"` +} + +type Server struct { + dmiapi.UnimplementedDeviceMapperServiceServer + lis net.Listener + cfg Config + devPanel global.DevPanel +} + +func NewServer(cfg Config, devPanel global.DevPanel) Server { + s := Server{cfg: cfg} + s.devPanel = devPanel + return s +} + +func (s *Server) Start() error { + klog.Infof("uds socket path: %s", s.cfg.SockPath) + err := initSock(s.cfg.SockPath) + if err != nil { + klog.Fatalf("failed to remove uds socket with err: %v", err) + return err + } + + s.lis, err = net.Listen("unix", s.cfg.SockPath) + if err != nil { + klog.Fatalf("failed to remove uds socket with err: %v", err) + return err + } + grpcServer := grpc.NewServer() + dmiapi.RegisterDeviceMapperServiceServer(grpcServer, s) + reflection.Register(grpcServer) + klog.V(2).Info("start grpc server") + return grpcServer.Serve(s.lis) +} + +func (s *Server) Stop() { + err := s.lis.Close() + if err != nil { + return + } + err = os.Remove(s.cfg.SockPath) + if err != nil { + return + } +} + +func initSock(sockPath string) error { + klog.V(2).Infof("init uds socket: %s", sockPath) + _, err := os.Stat(sockPath) + if err == nil { + err = os.Remove(sockPath) + if err != nil { + return err + } + return nil + } else if os.IsNotExist(err) { + return nil + } else { + return fmt.Errorf("fail to stat uds socket path") + } +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/callback.go b/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/callback.go new file mode 100644 index 00000000..001d8988 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/callback.go @@ -0,0 +1,86 @@ +package httpserver + +import ( + "fmt" + "net/http" + "reflect" + "strings" + + "github.com/kubeedge/modbus/pkg/common" +) + +func (rs *RestServer) Ping(writer http.ResponseWriter, request *http.Request) { + response := &PingResponse{ + BaseResponse: NewBaseResponse(http.StatusOK), + Message: fmt.Sprintf("This is %s API, the server is running normally.", APIVersion), + } + rs.sendResponse(writer, request, response, http.StatusOK) +} + +func (rs *RestServer) DeviceRead(writer http.ResponseWriter, request *http.Request) { + urlItem := strings.Split(request.URL.Path, "/") + deviceName := urlItem[len(urlItem)-2] + propertyName := urlItem[len(urlItem)-1] + res, dataType, err := rs.devPanel.GetTwinResult(urlItem[len(urlItem)-2], urlItem[len(urlItem)-1]) + if err != nil { + http.Error(writer, fmt.Sprintf("Get device data error: %v", err), http.StatusInternalServerError) + } else { + response := &DeviceReadResponse{ + BaseResponse: NewBaseResponse(http.StatusOK), + Data: common.NewDataModel( + deviceName, + propertyName, + common.WithValue(res), + common.WithType(dataType), + ), + } + rs.sendResponse(writer, request, response, http.StatusOK) + } +} + +func (rs *RestServer) MetaGetModel(writer http.ResponseWriter, request *http.Request) { + urlItem := strings.Split(request.URL.Path, "/") + deviceName := urlItem[len(urlItem)-1] + device, err := rs.devPanel.GetDevice(deviceName) + if err != nil { + http.Error(writer, fmt.Sprintf("Get device error: %v", err), http.StatusInternalServerError) + return + } + driverInstancePtr := reflect.ValueOf(device) + if driverInstancePtr.IsNil() { + http.Error(writer, fmt.Sprintf("Get device error: %v", err), http.StatusInternalServerError) + return + } + instance := driverInstancePtr.Elem().FieldByName("Instance") + if instance.IsValid() { + instance, ok := instance.Interface().(common.DeviceInstance) + if ok { + model, err := rs.devPanel.GetModel(instance.Model) + if err != nil { + http.Error(writer, fmt.Sprintf("Get device model error: %v", err), http.StatusInternalServerError) + } + response := &MetaGetModelResponse{ + BaseResponse: NewBaseResponse(http.StatusOK), + DeviceModel: &model, + } + rs.sendResponse(writer, request, response, http.StatusOK) + } else { + http.Error(writer, fmt.Sprintf("Get device instance error: %v", err), http.StatusInternalServerError) + } + } else { + http.Error(writer, fmt.Sprintf("Get device instance error: %v", err), http.StatusInternalServerError) + } + +} + +func (rs *RestServer) DataBaseGetDataByID(writer http.ResponseWriter, request *http.Request) { + if rs.databaseClient == nil { + http.Error(writer, "The database is not enabled. Please configure mapper and try again", http.StatusServiceUnavailable) + return + } + response := &DataBaseResponse{ + BaseResponse: NewBaseResponse(http.StatusOK), + Data: nil, + } + rs.sendResponse(writer, request, response, http.StatusOK) +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/responsetype.go b/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/responsetype.go new file mode 100644 index 00000000..ea830b04 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/responsetype.go @@ -0,0 +1,45 @@ +package httpserver + +import ( + "time" + + "github.com/kubeedge/modbus/pkg/common" +) + +// BaseResponse the base response struct of all response +type BaseResponse struct { + APIVersion string `json:"apiVersion"` + StatusCode int `json:"statusCode"` + TimeStamp string `json:"timeStamp"` +} + +// NewBaseResponse get BaseResponse by statusCode +func NewBaseResponse(statusCode int) *BaseResponse { + return &BaseResponse{ + APIVersion: APIVersion, + StatusCode: statusCode, + TimeStamp: time.Now().Format(time.RFC3339), + } +} + +type PingResponse struct { + *BaseResponse + Message string +} + +type DeviceReadResponse struct { + *BaseResponse + Data *common.DataModel +} + +type MetaGetModelResponse struct { + *BaseResponse + *common.DeviceModel +} + +// DataBaseResponse just for test +type DataBaseResponse struct { + // TODO DataBase API need to add + *BaseResponse + Data []common.DataModel +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/restapi.go b/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/restapi.go new file mode 100644 index 00000000..c379d570 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/restapi.go @@ -0,0 +1,46 @@ +package httpserver + +// API path +const ( + // APIVersion description API version + APIVersion = "v1" + // APIBase to build RESTful API + APIBase = "/api/" + APIVersion + + // APIPing ping API that get server status + APIPing = APIBase + "/ping" + + // APIDeviceRoute to build device RESTful API + APIDeviceRoute = APIBase + "/device" + // APIDeviceReadRoute API that read device's property + APIDeviceReadRoute = APIDeviceRoute + "/" + DeviceID + "/" + PropertyName + + // APIMetaRoute to build meta RESTful API + APIMetaRoute = APIBase + "/meta" + // APIMetaGetModelRoute API that get device model by device id + APIMetaGetModelRoute = APIMetaRoute + "/model" + "/" + DeviceID + + // APIDataBaseRoute to build database RESTful API + APIDataBaseRoute = APIBase + "/database" + // APIDataBaseGetDataByID API that get data by device id + APIDataBaseGetDataByID = APIDataBaseRoute + "/" + DeviceID +) + +// API field pattern +const ( + // DeviceID pattern for deviceID + DeviceID = "{id}" + // PropertyName pattern for property + PropertyName = "{property}" +) + +// Response Header +const ( + // ContentType content header Key + ContentType = "Content-Type" + // ContentTypeJSON content type is json + ContentTypeJSON = "application/json" + + // CorrelationHeader correlation header key + CorrelationHeader = "X-Correlation-ID" +) diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/router.go b/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/router.go new file mode 100644 index 00000000..269b671c --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/router.go @@ -0,0 +1,17 @@ +package httpserver + +import "net/http" + +func (rs *RestServer) InitRouter() { + // Common + rs.Router.HandleFunc(APIPing, rs.Ping).Methods(http.MethodGet) + + // Device + rs.Router.HandleFunc(APIDeviceReadRoute, rs.DeviceRead).Methods(http.MethodGet) + + // Meta + rs.Router.HandleFunc(APIMetaGetModelRoute, rs.MetaGetModel).Methods(http.MethodGet) + + // DataBase + rs.Router.HandleFunc(APIDataBaseGetDataByID, rs.DataBaseGetDataByID).Methods(http.MethodGet) +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/server.go b/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/server.go new file mode 100644 index 00000000..def1fe9a --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/httpserver/server.go @@ -0,0 +1,170 @@ +package httpserver + +import ( + "crypto/tls" + "crypto/x509" + "encoding/json" + "io/ioutil" + "net/http" + "time" + + "github.com/gorilla/mux" + "k8s.io/klog/v2" + + "github.com/kubeedge/modbus/pkg/global" +) + +type RestServer struct { + IP string + Port string + WriteTimeout time.Duration + ReadTimeout time.Duration + CertFilePath string + KeyFilePath string + CaCertFilePath string + server *http.Server + Router *mux.Router + devPanel global.DevPanel + databaseClient global.DataBaseClient +} + +type Option func(server *RestServer) + +func NewRestServer(devPanel global.DevPanel, options ...Option) *RestServer { + rest := &RestServer{ + IP: "0.0.0.0", + Port: "7777", + Router: mux.NewRouter(), + WriteTimeout: 10 * time.Second, + ReadTimeout: 10 * time.Second, + devPanel: devPanel, + } + for _, option := range options { + option(rest) + } + return rest +} + +func (rs *RestServer) StartServer() { + rs.InitRouter() + rs.server = &http.Server{ + Addr: rs.IP + ":" + rs.Port, + WriteTimeout: rs.WriteTimeout, + ReadTimeout: rs.ReadTimeout, + Handler: rs.Router, + } + if rs.CaCertFilePath == "" && (rs.KeyFilePath == "" || rs.CertFilePath == "") { + // insecure + klog.V(3).Info("Insecure communication, skipping server verification") + err := rs.server.ListenAndServe() + if err != nil { + klog.Errorf("insecure http server error: %v", err) + return + } + } else if rs.CaCertFilePath == "" && rs.KeyFilePath != "" && rs.CertFilePath != "" { + // tls + klog.V(3).Info("tls communication, https server start") + err := rs.server.ListenAndServeTLS(rs.CertFilePath, rs.KeyFilePath) + if err != nil { + klog.Errorf("tls http server error: %v", err) + return + } + } else if rs.CaCertFilePath != "" && rs.KeyFilePath != "" && rs.CertFilePath != "" { + // mtls + klog.V(3).Info("mtls communication, please provide client-key and client-cert to access service") + // Configure the server to trust TLS client cert issued by your CA. + certPool := x509.NewCertPool() + if caCertPEM, err := ioutil.ReadFile(rs.CaCertFilePath); err != nil { + klog.Errorf("Error loading ca certificate file: %v", err) + return + } else if ok := certPool.AppendCertsFromPEM(caCertPEM); !ok { + klog.Error("invalid cert in CA PEM") + return + } + tlsConfig := &tls.Config{ + ClientAuth: tls.RequireAndVerifyClientCert, + ClientCAs: certPool, + } + rs.server.TLSConfig = tlsConfig + err := rs.server.ListenAndServeTLS(rs.CertFilePath, rs.KeyFilePath) + if err != nil { + klog.Errorf("tls http server error: %v", err) + return + } + } else { + klog.Error("the certificate file provided is incomplete or does not match") + } +} + +// sendResponse build response and put response's payload to writer +func (rs *RestServer) sendResponse( + writer http.ResponseWriter, + request *http.Request, + response interface{}, + statusCode int) { + + correlationID := request.Header.Get(CorrelationHeader) + if correlationID != "" { + writer.Header().Set(CorrelationHeader, correlationID) + } + writer.Header().Set(ContentType, ContentTypeJSON) + writer.WriteHeader(statusCode) + data, err := json.Marshal(response) + if err != nil { + klog.Errorf("marshal %s response error: %v", request.URL.Path, err) + http.Error(writer, err.Error(), http.StatusInternalServerError) + } + _, err = writer.Write(data) + if err != nil { + klog.Errorf("write %s response error: %v", request.URL.Path, err) + http.Error(writer, err.Error(), http.StatusInternalServerError) + } +} + +func WithIP(ip string) Option { + return func(server *RestServer) { + server.IP = ip + } +} + +func WithPort(port string) Option { + return func(server *RestServer) { + server.Port = port + } +} + +func WithWriteTimeout(timeout time.Duration) Option { + return func(server *RestServer) { + server.WriteTimeout = timeout + } +} + +func WithReadTimeout(timeout time.Duration) Option { + return func(server *RestServer) { + server.ReadTimeout = timeout + } +} + +func WithCertFile(certPath string) Option { + return func(server *RestServer) { + server.CertFilePath = certPath + } +} + +func WithKeyFile(keyFilePath string) Option { + return func(server *RestServer) { + server.KeyFilePath = keyFilePath + } +} + +func WithCaCertFile(caCertPath string) Option { + return func(server *RestServer) { + server.CaCertFilePath = caCertPath + } +} + +func WithDbClient(dbClient global.DataBaseClient) Option { + return func(server *RestServer) { + server.databaseClient = dbClient + } +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/util/parse/grpc.go b/mappers/kubeedge-v1.15.0/modbus/pkg/util/parse/grpc.go new file mode 100644 index 00000000..962f3478 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/util/parse/grpc.go @@ -0,0 +1,265 @@ +package parse + +import ( + "encoding/json" + "errors" + + "k8s.io/klog/v2" + + "github.com/kubeedge/modbus/pkg/common" + dmiapi "github.com/kubeedge/modbus/pkg/dmi-api" +) + +type TwinResultResponse struct { + PropertyName string `json:"property_name"` + Payload []byte `json:"payload"` +} + +func getProtocolNameFromGrpc(device *dmiapi.Device) (string, error) { + + return device.Spec.Protocol.ProtocolName, nil +} + +func getPushMethodFromGrpc(visitor *dmiapi.DeviceProperty) (string, error) { + // TODO add more push method + if visitor.PushMethod.Http != nil { + return "http", nil + } + if visitor.PushMethod.Mqtt != nil { + return "mqtt", nil + } + return "", errors.New("can not parse publish method") +} + +func getDBMethodFromGrpc(visitor *dmiapi.DeviceProperty) (string, error) { + // TODO add more dbMethod + if visitor.PushMethod.DBMethod.Influxdb2 != nil { + return "influx", nil + } + return "", errors.New("can not parse dbMethod") +} + +func BuildProtocolFromGrpc(device *dmiapi.Device) (common.ProtocolConfig, error) { + protocolName, err := getProtocolNameFromGrpc(device) + if err != nil { + return common.ProtocolConfig{}, err + } + + var protocolConfig []byte + + customizedProtocol := make(map[string]interface{}) + customizedProtocol["protocolName"] = protocolName + if device.Spec.Protocol.ConfigData != nil { + recvAdapter := make(map[string]interface{}) + for k, v := range device.Spec.Protocol.ConfigData.Data { + value, err := common.DecodeAnyValue(v) + if err != nil { + continue + } + recvAdapter[k] = value + } + customizedProtocol["configData"] = recvAdapter + } + protocolConfig, err = json.Marshal(customizedProtocol) + if err != nil { + return common.ProtocolConfig{}, err + } + + return common.ProtocolConfig{ + ProtocolName: protocolName, + ConfigData: protocolConfig, + }, nil +} + +func buildTwinsFromGrpc(device *dmiapi.Device) []common.Twin { + if len(device.Spec.Properties) == 0 { + return nil + } + res := make([]common.Twin, 0, len(device.Spec.Properties)) + for _, property := range device.Spec.Properties { + cur := common.Twin{ + PropertyName: property.Name, + ObservedDesired: common.TwinProperty{ + Value: property.Desired.Value, + Metadata: common.Metadata{ + Timestamp: property.Desired.Metadata["timestamp"], + Type: property.Desired.Metadata["type"], + }, + }, + } + res = append(res, cur) + } + return res +} + +func buildPropertiesFromGrpc(device *dmiapi.Device) []common.DeviceProperty { + if len(device.Spec.Properties) == 0 { + return nil + } + protocolName, err := getProtocolNameFromGrpc(device) + if err != nil { + return nil + } + res := make([]common.DeviceProperty, 0, len(device.Spec.Properties)) + klog.V(3).Infof("In buildPropertiesFromGrpc, PropertyVisitors = %v", device.Spec.Properties) + for _, pptv := range device.Spec.Properties { + + // get visitorConfig filed by grpc device instance + var visitorConfig []byte + recvAdapter := make(map[string]interface{}) + for k, v := range pptv.Visitors.ConfigData.Data { + value, err := common.DecodeAnyValue(v) + if err != nil { + continue + } + recvAdapter[k] = value + } + customizedProtocol := make(map[string]interface{}) + customizedProtocol["protocolName"] = pptv.Visitors.ProtocolName + customizedProtocol["configData"] = recvAdapter + visitorConfig, err = json.Marshal(customizedProtocol) + if err != nil { + klog.Errorf("err: %+v", err) + return nil + } + + // get dbMethod filed by grpc device instance + var dbMethodName string + var dbconfig common.DBConfig + var pushMethod []byte + var pushMethodName string + if pptv.PushMethod != nil { + if pptv.PushMethod.DBMethod != nil { + dbMethodName, err = getDBMethodFromGrpc(pptv) + if err != nil { + klog.Errorf("err: %+v", err) + return nil + } + switch dbMethodName { + case "influx": + clientconfig, err := json.Marshal(pptv.PushMethod.DBMethod.Influxdb2.Influxdb2ClientConfig) + if err != nil { + klog.Errorf("err: %+v", err) + return nil + } + dataconfig, err := json.Marshal(pptv.PushMethod.DBMethod.Influxdb2.Influxdb2DataConfig) + if err != nil { + klog.Errorf("err: %+v", err) + return nil + } + dbconfig = common.DBConfig{ + Influxdb2ClientConfig: clientconfig, + Influxdb2DataConfig: dataconfig, + } + } + } + // get pushMethod filed by grpc device instance + pushMethodName, err = getPushMethodFromGrpc(pptv) + if err != nil { + klog.Errorf("err: %+v", err) + return nil + } + switch pushMethodName { + case "http": + pushMethod, err = json.Marshal(pptv.PushMethod.Http) + if err != nil { + klog.Errorf("err: %+v", err) + return nil + } + case "mqtt": + pushMethod, err = json.Marshal(pptv.PushMethod.Mqtt) + if err != nil { + klog.Errorf("err: %+v", err) + return nil + } + } + } + + // get the final Properties + cur := common.DeviceProperty{ + Name: pptv.GetName(), + PropertyName: pptv.GetName(), + ModelName: device.Spec.DeviceModelReference, + CollectCycle: pptv.GetCollectCycle(), + ReportCycle: pptv.GetReportCycle(), + ReportToCloud: pptv.GetReportToCloud(), + Protocol: protocolName, + Visitors: visitorConfig, + PushMethod: common.PushMethodConfig{ + MethodName: pushMethodName, + MethodConfig: pushMethod, + DBMethod: common.DBMethodConfig{ + DBMethodName: dbMethodName, + DBConfig: dbconfig, + }, + }, + } + res = append(res, cur) + + } + return res +} + +func ParseDeviceModelFromGrpc(model *dmiapi.DeviceModel) common.DeviceModel { + cur := common.DeviceModel{ + Name: model.GetName(), + } + if model.GetSpec() == nil || len(model.GetSpec().GetProperties()) == 0 { + return cur + } + properties := make([]common.ModelProperty, 0, len(model.Spec.Properties)) + for _, property := range model.Spec.Properties { + p := common.ModelProperty{ + Name: property.GetName(), + Description: property.GetDescription(), + DataType: property.Type, + AccessMode: property.AccessMode, + Minimum: property.Minimum, + Maximum: property.Maximum, + Unit: property.Unit, + } + properties = append(properties, p) + } + cur.Properties = properties + return cur +} + +func ParseDeviceFromGrpc(device *dmiapi.Device, commonModel *common.DeviceModel) (*common.DeviceInstance, error) { + + protocolName, err := getProtocolNameFromGrpc(device) + if err != nil { + return nil, err + } + instance := &common.DeviceInstance{ + ID: device.GetName(), + Name: device.GetName(), + ProtocolName: protocolName + "-" + device.GetName(), + Model: device.Spec.DeviceModelReference, + Twins: buildTwinsFromGrpc(device), + Properties: buildPropertiesFromGrpc(device), + } + // copy Properties to twin + propertiesMap := make(map[string]common.DeviceProperty) + for i := 0; i < len(instance.Properties); i++ { + if commonModel == nil { + klog.Errorf("commonModel == nil") + continue + } + + // parse the content of the modelproperty field into instance + for _, property := range commonModel.Properties { + if property.Name == instance.Properties[i].PropertyName { + instance.Properties[i].PProperty = property + break + } + } + propertiesMap[instance.Properties[i].PProperty.Name] = instance.Properties[i] + } + for i := 0; i < len(instance.Twins); i++ { + if v, ok := propertiesMap[instance.Twins[i].PropertyName]; ok { + instance.Twins[i].Property = &v + } + } + klog.V(2).Infof("final instance data from grpc = %v", instance) + return instance, nil +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/util/parse/parse.go b/mappers/kubeedge-v1.15.0/modbus/pkg/util/parse/parse.go new file mode 100644 index 00000000..4f8b1273 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/util/parse/parse.go @@ -0,0 +1,66 @@ +/* +Copyright 2023 The KubeEdge Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package parse + +import ( + "errors" + + "k8s.io/klog/v2" + + "github.com/kubeedge/modbus/pkg/common" + "github.com/kubeedge/modbus/pkg/grpcclient" +) + +var ErrEmptyData error = errors.New("device or device model list is empty") + +func ParseByUsingRegister(devices map[string]*common.DeviceInstance, + dms map[string]common.DeviceModel, + protocols map[string]common.ProtocolConfig) error { + deviceList, deviceModelList, err := grpcclient.RegisterMapper(true) + if err != nil { + return err + } + + if len(deviceList) == 0 || len(deviceModelList) == 0 { + return ErrEmptyData + } + modelMap := make(map[string]common.DeviceModel) + for _, model := range deviceModelList { + cur := ParseDeviceModelFromGrpc(model) + modelMap[model.Name] = cur + } + + for _, device := range deviceList { + commonModel := modelMap[device.Spec.DeviceModelReference] + protocol, err := BuildProtocolFromGrpc(device) + if err != nil { + return err + } + instance, err := ParseDeviceFromGrpc(device, &commonModel) + if err != nil { + return err + } + instance.PProtocol = protocol + devices[instance.ID] = new(common.DeviceInstance) + devices[instance.ID] = instance + klog.V(4).Info("Instance: ", instance.ID) + dms[instance.Model] = modelMap[instance.Model] + protocols[instance.ProtocolName] = protocol + } + + return nil +} diff --git a/mappers/kubeedge-v1.15.0/modbus/pkg/util/parse/type.go b/mappers/kubeedge-v1.15.0/modbus/pkg/util/parse/type.go new file mode 100644 index 00000000..ce32b43d --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/pkg/util/parse/type.go @@ -0,0 +1,99 @@ +package parse + +import ( + "fmt" + + "github.com/kubeedge/modbus/pkg/common" + dmiapi "github.com/kubeedge/modbus/pkg/dmi-api" +) + +func ConvTwinsToGrpc(twins []common.Twin) ([]*dmiapi.Twin, error) { + res := make([]*dmiapi.Twin, 0, len(twins)) + for _, twin := range twins { + cur := &dmiapi.Twin{ + PropertyName: twin.PropertyName, + ObservedDesired: &dmiapi.TwinProperty{ + Value: twin.ObservedDesired.Value, + Metadata: map[string]string{ + "type": twin.ObservedDesired.Metadata.Type, + "timestamp": twin.ObservedDesired.Metadata.Timestamp, + }, + }, + Reported: &dmiapi.TwinProperty{ + Value: twin.Reported.Value, + Metadata: map[string]string{ + "type": twin.Reported.Metadata.Type, + "timestamp": twin.Reported.Metadata.Timestamp, + }, + }, + } + res = append(res, cur) + } + return res, nil +} + +func ConvGrpcToTwins(twins []*dmiapi.Twin, srcTwins []common.Twin) ([]common.Twin, error) { + res := make([]common.Twin, 0, len(twins)) + for _, twin := range twins { + var srcTwin common.Twin + for _, found := range srcTwins { + if twin.GetPropertyName() == found.PropertyName { + srcTwin = found + break + } + } + if srcTwin.PropertyName == "" { + return nil, fmt.Errorf("not found src twin name %s while update status", twin.GetPropertyName()) + } + desiredMeta := twin.ObservedDesired.GetMetadata() + reportedMeta := twin.Reported.GetMetadata() + cur := common.Twin{ + PropertyName: twin.GetPropertyName(), + Property: srcTwin.Property, + ObservedDesired: common.TwinProperty{ + Value: twin.ObservedDesired.GetValue(), + }, + Reported: common.TwinProperty{ + Value: twin.Reported.GetValue(), + }, + } + if desiredMeta != nil { + cur.ObservedDesired.Metadata = common.Metadata{ + Timestamp: twin.ObservedDesired.GetMetadata()["timestamp"], + Type: twin.ObservedDesired.GetMetadata()["type"], + } + } + if reportedMeta != nil { + cur.Reported.Metadata = common.Metadata{ + Timestamp: twin.Reported.GetMetadata()["timestamp"], + Type: twin.Reported.GetMetadata()["type"], + } + } + res = append(res, cur) + } + return res, nil +} + +func ConvMsgTwinToGrpc(msgTwin map[string]*common.MsgTwin) []*dmiapi.Twin { + var twins []*dmiapi.Twin + for name, twin := range msgTwin { + twinData := &dmiapi.Twin{ + PropertyName: name, + Reported: &dmiapi.TwinProperty{ + Value: *twin.Actual.Value, + Metadata: map[string]string{ + "type": twin.Metadata.Type, + "timestamp": twin.Actual.Metadata.Timestamp, + }}, + ObservedDesired: &dmiapi.TwinProperty{ + Value: *twin.Expected.Value, + Metadata: map[string]string{ + "type": twin.Metadata.Type, + "timestamp": twin.Actual.Metadata.Timestamp, + }}, + } + twins = append(twins, twinData) + } + + return twins +} diff --git a/mappers/kubeedge-v1.15.0/modbus/resource/modbus-instance.yaml b/mappers/kubeedge-v1.15.0/modbus/resource/modbus-instance.yaml new file mode 100644 index 00000000..b3599b37 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/resource/modbus-instance.yaml @@ -0,0 +1,53 @@ +apiVersion: devices.kubeedge.io/v1beta1 +kind: Device +metadata: + name: modbus-instance-01 + labels: + model: modbus-01 +spec: + deviceModelRef: + name: modbus-01 + protocol: + protocolName: modbus + configData: + slaveID: 1 + serialPort: '1' + baudRate: 115200 + dataBits: 8 + parity: even + stopBits: 1 + nodeName: edge-node + properties: + - name: temperature + visitors: + protocolName: modbus + configData: + register: CoilRegister + offset: 2 + limit: 1 + scale: 1 + isSwap: true + isRegisterSwap: true + reportCycle: 10000000000 + collectCycle: 10000000000 + reportToCloud: true + pushMethod: + mqtt: + address: tcp://127.0.0.1:1883 + topic: temperature + qos: 0 + retained: false + +status: + twins: + - propertyName: temperature + reported: + metadata: + timestamp: '1550049403598' + type: int + value: "20" + observedDesired: + metadata: + timestamp: '1550049403598' + type: int + value: "20" \ No newline at end of file diff --git a/mappers/kubeedge-v1.15.0/modbus/resource/modbus-model.yaml b/mappers/kubeedge-v1.15.0/modbus/resource/modbus-model.yaml new file mode 100644 index 00000000..790973a5 --- /dev/null +++ b/mappers/kubeedge-v1.15.0/modbus/resource/modbus-model.yaml @@ -0,0 +1,12 @@ +apiVersion: devices.kubeedge.io/v1beta1 +kind: DeviceModel +metadata: + name: modbus-01 + namespace: default +spec: + protocol: modbus + properties: + - name: temperature + description: temperature in degree celsius + type: INT + accessMode: ReadWrite \ No newline at end of file