Compare commits
30 Commits
Author | SHA1 | Date |
---|---|---|
|
bd14c0473a | |
|
967ace7fb7 | |
|
620cd01fcc | |
|
898b5edcb1 | |
|
669fd9b7a5 | |
|
a408ea0341 | |
|
96009b7561 | |
|
72cfcb4890 | |
|
6d21d341a2 | |
|
8cf4f9da2a | |
|
77b73b42c2 | |
|
be7967f9e3 | |
|
740af01b0f | |
|
55fb8e110a | |
|
23ae39c118 | |
|
95a475dfa1 | |
|
1a78cfc501 | |
|
7389bfd808 | |
|
0533327f84 | |
|
186b50d113 | |
|
e52ebca353 | |
|
d11f2765ae | |
|
fdf93b0eb7 | |
|
83b7dc26cb | |
|
62ddff0c5c | |
|
d2c12b5f72 | |
|
3faa5198ae | |
|
459dd4c80c | |
|
fcae29c635 | |
|
26e3ec2e41 |
|
@ -0,0 +1,3 @@
|
|||
# KubeEdge Community Code of Conduct
|
||||
|
||||
Please refer to our [KubeEdge Community Code of Conduct](https://github.com/kubeedge/community/blob/master/CODE_OF_CONDUCT.md)
|
17
README.md
17
README.md
|
@ -11,6 +11,7 @@ The command below will generate a framework for the customized mapper. Run the c
|
|||
```shell
|
||||
make generate
|
||||
Please input the mapper name (like 'Bluetooth', 'BLE'): foo
|
||||
Please input the build method (like 'stream', 'nostream'): nostream
|
||||
```
|
||||
A project named as your input will be generated. The file tree is as below:
|
||||
```
|
||||
|
@ -39,9 +40,21 @@ mapper
|
|||
├── hack
|
||||
│ └── make-rules
|
||||
│ └── mapper.sh
|
||||
├── pkg ------------------------ Mapper register process, almost need not change
|
||||
└── Makefile
|
||||
```
|
||||
|
||||
## 2. Generate the mapper project
|
||||
After generating the mapper project and filling driver folder, users can make their own mapper image
|
||||
based on the Dockerfile file and deploy the mapper in the cluster through deployment and other methods.
|
||||
If your mapper is aimed to processing streaming data
|
||||
```shell
|
||||
docker build -f Dockerfile_stream -t [YOUR MAPPER IMAGE NAME] .
|
||||
```
|
||||
If not, Use the following command:
|
||||
```shell
|
||||
docker build -f Dockerfile_nostream -t [YOUR MAPPER IMAGE NAME] .
|
||||
```
|
||||
|
||||
# Where does it come from?
|
||||
mapper-framework is synced from https://github.com/kubeedge/kubeedge/tree/master/staging/src/github.com/kubeedge/mapper-framework. Code changes are made in that location, merged into kubeedge and later synced here.
|
||||
mapper-framework is synced from https://github.com/kubeedge/kubeedge/tree/master/staging/src/github.com/kubeedge/mapper-framework.
|
||||
Code changes are made in that location, merged into kubeedge and later synced here.
|
|
@ -1,4 +1,4 @@
|
|||
FROM golang:1.20.10-alpine3.18 AS builder
|
||||
FROM golang:1.21.11-alpine3.19 AS builder
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
|
@ -17,4 +17,4 @@ RUN mkdir -p kubeedge
|
|||
COPY --from=builder /build/main kubeedge/
|
||||
COPY ./config.yaml kubeedge/
|
||||
|
||||
WORKDIR kubeedge
|
||||
WORKDIR kubeedge
|
|
@ -0,0 +1,35 @@
|
|||
FROM golang:1.21.11-bullseye AS builder
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
ENV GO111MODULE=on \
|
||||
GOPROXY=https://goproxy.cn,direct
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y bzip2 curl upx-ucl gcc-aarch64-linux-gnu libc6-dev-arm64-cross gcc-arm-linux-gnueabi libc6-dev-armel-cross libva-dev libva-drm2 libx11-dev libvdpau-dev libxext-dev libsdl1.2-dev libxcb1-dev libxau-dev libxdmcp-dev yasm
|
||||
|
||||
RUN curl -sLO https://ffmpeg.org/releases/ffmpeg-4.1.6.tar.bz2 && \
|
||||
tar -jx --strip-components=1 -f ffmpeg-4.1.6.tar.bz2 && \
|
||||
./configure && make && \
|
||||
make install
|
||||
|
||||
RUN GOOS=linux go build -o main cmd/main.go
|
||||
|
||||
FROM ubuntu:18.04
|
||||
|
||||
RUN mkdir -p kubeedge
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y bzip2 curl upx-ucl gcc-aarch64-linux-gnu libc6-dev-arm64-cross gcc-arm-linux-gnueabi libc6-dev-armel-cross libva-dev libva-drm2 libx11-dev libvdpau-dev libxext-dev libsdl1.2-dev libxcb1-dev libxau-dev libxdmcp-dev yasm
|
||||
|
||||
RUN curl -sLO https://ffmpeg.org/releases/ffmpeg-4.1.6.tar.bz2 && \
|
||||
tar -jx --strip-components=1 -f ffmpeg-4.1.6.tar.bz2 && \
|
||||
./configure && make && \
|
||||
make install
|
||||
|
||||
COPY --from=builder /build/main kubeedge/
|
||||
COPY ./config.yaml kubeedge/
|
||||
|
||||
WORKDIR kubeedge
|
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
|
@ -23,7 +22,6 @@ func main() {
|
|||
|
||||
if c, err = config.Parse(); err != nil {
|
||||
klog.Fatal(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
klog.Infof("config: %+v", c)
|
||||
|
||||
|
@ -43,7 +41,7 @@ func main() {
|
|||
go panel.DevStart()
|
||||
|
||||
// start http server
|
||||
httpServer := httpserver.NewRestServer(panel)
|
||||
httpServer := httpserver.NewRestServer(panel, c.Common.HTTPPort)
|
||||
go httpServer.StartServer()
|
||||
|
||||
// start grpc server
|
||||
|
|
|
@ -37,7 +37,7 @@ func DataHandler(ctx context.Context, twin *common.Twin, client *driver.Customiz
|
|||
klog.Errorf("init database client err: %v", err)
|
||||
return
|
||||
}
|
||||
reportCycle := time.Duration(twin.Property.ReportCycle)
|
||||
reportCycle := time.Millisecond * time.Duration(twin.Property.ReportCycle)
|
||||
if reportCycle == 0 {
|
||||
reportCycle = common.DefaultReportCycle
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
Copyright 2024 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 mysql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
)
|
||||
|
||||
var (
|
||||
DB *sql.DB
|
||||
)
|
||||
|
||||
type DataBaseConfig struct {
|
||||
MySQLClientConfig *MySQLClientConfig `json:"mysqlClientConfig"`
|
||||
}
|
||||
|
||||
type MySQLClientConfig struct {
|
||||
Addr string `json:"addr,omitempty"`
|
||||
Database string `json:"database,omitempty"`
|
||||
UserName string `json:"userName,omitempty"`
|
||||
}
|
||||
|
||||
func NewDataBaseClient(config json.RawMessage) (*DataBaseConfig, error) {
|
||||
configdata := new(MySQLClientConfig)
|
||||
err := json.Unmarshal(config, configdata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &DataBaseConfig{
|
||||
MySQLClientConfig: configdata,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *DataBaseConfig) InitDbClient() error {
|
||||
password := os.Getenv("PASSWORD")
|
||||
usrName := d.MySQLClientConfig.UserName
|
||||
addr := d.MySQLClientConfig.Addr
|
||||
dataBase := d.MySQLClientConfig.Database
|
||||
dataSourceName := fmt.Sprintf("%s:%s@tcp(%s)/%s", usrName, password, addr, dataBase)
|
||||
var err error
|
||||
DB, err = sql.Open("mysql", dataSourceName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("connection to %s of mysql faild with err:%v", dataBase, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DataBaseConfig) CloseSession() {
|
||||
err := DB.Close()
|
||||
if err != nil {
|
||||
klog.Errorf("close mysql failed with err:%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DataBaseConfig) AddData(data *common.DataModel) error {
|
||||
tableName := data.Namespace + "/" + data.DeviceName + "/" + data.PropertyName
|
||||
datatime := time.Unix(data.TimeStamp/1e3, 0).Format("2006-01-02 15:04:05")
|
||||
|
||||
createTable := fmt.Sprintf("CREATE TABLE IF NOT EXISTS `%s` (id INT AUTO_INCREMENT PRIMARY KEY, ts DATETIME NOT NULL,field TEXT)", tableName)
|
||||
_, err := DB.Exec(createTable)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create tabe into mysql failed with err:%v", err)
|
||||
}
|
||||
|
||||
stmt, err := DB.Prepare(fmt.Sprintf("INSERT INTO `%s` (ts,field) VALUES (?,?)", tableName))
|
||||
if err != nil {
|
||||
return fmt.Errorf("prepare parament failed with err:%v", err)
|
||||
}
|
||||
defer func(stmt *sql.Stmt) {
|
||||
err := stmt.Close()
|
||||
if err != nil {
|
||||
klog.Errorf("close mysql's statement failed with err:%v", err)
|
||||
}
|
||||
}(stmt)
|
||||
_, err = stmt.Exec(datatime, data.Value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("insert data into msyql failed with err:%v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright 2024 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 mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/kubeedge/Template/driver"
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
)
|
||||
|
||||
func DataHandler(ctx context.Context, twin *common.Twin, client *driver.CustomizedClient, visitorConfig *driver.VisitorConfig, dataModel *common.DataModel) {
|
||||
dbConfig, err := NewDataBaseClient(twin.Property.PushMethod.DBMethod.DBConfig.MySQLClientConfig)
|
||||
if err != nil {
|
||||
klog.Errorf("new database client error: %v", err)
|
||||
return
|
||||
}
|
||||
err = dbConfig.InitDbClient()
|
||||
if err != nil {
|
||||
klog.Errorf("init redis database client err: %v", err)
|
||||
return
|
||||
}
|
||||
reportCycle := time.Duration(twin.Property.ReportCycle)
|
||||
if reportCycle == 0 {
|
||||
reportCycle = common.DefaultReportCycle
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
klog.Errorf("mysql database add data error: %v", err)
|
||||
return
|
||||
}
|
||||
case <-ctx.Done():
|
||||
dbConfig.CloseSession()
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
|
@ -51,9 +51,8 @@ func (d *DataBaseConfig) InitDbClient() error {
|
|||
if err != nil {
|
||||
klog.Errorf("init redis database failed, err = %v", err)
|
||||
return err
|
||||
} else {
|
||||
klog.V(1).Infof("init redis database successfully, with return cmd %s", pong)
|
||||
}
|
||||
klog.V(1).Infof("init redis database successfully, with return cmd %s", pong)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -66,43 +65,27 @@ func (d *DataBaseConfig) CloseSession() {
|
|||
|
||||
func (d *DataBaseConfig) AddData(data *common.DataModel) error {
|
||||
ctx := context.Background()
|
||||
// The key to construct the ordered set, here DeviceName is used as the key
|
||||
klog.V(1).Infof("deviceName:%s", data.DeviceName)
|
||||
tableName := data.Namespace + "/" + data.DeviceName
|
||||
// The key to construct the ordered set, here DeviceID is used as the key
|
||||
klog.V(4).Infof("tableName:%s", tableName)
|
||||
// Check if the current ordered set exists
|
||||
exists, err := RedisCli.Exists(ctx, data.DeviceName).Result()
|
||||
deviceData := "TimeStamp: " + strconv.FormatInt(data.TimeStamp, 10) + " PropertyName: " + data.PropertyName + " data: " + data.Value
|
||||
// Add data to ordered set. If the ordered set does not exist, it will be created.
|
||||
_, err := RedisCli.ZAdd(ctx, data.DeviceName, &redis.Z{
|
||||
Score: float64(data.TimeStamp),
|
||||
Member: deviceData,
|
||||
}).Result()
|
||||
if err != nil {
|
||||
klog.V(4).Info("Exit AddData")
|
||||
return err
|
||||
}
|
||||
deviceData := "TimeStamp: " + strconv.FormatInt(data.TimeStamp, 10) + " PropertyName: " + data.PropertyName + " data: " + data.Value
|
||||
if exists == 0 {
|
||||
// The ordered set does not exist, create a new ordered set and add data
|
||||
_, err = RedisCli.ZAdd(ctx, data.DeviceName, &redis.Z{
|
||||
Score: float64(data.TimeStamp),
|
||||
Member: deviceData,
|
||||
}).Result()
|
||||
if err != nil {
|
||||
klog.V(4).Info("Exit AddData")
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// The ordered set already exists, add data directly
|
||||
_, err = RedisCli.ZAdd(ctx, data.DeviceName, &redis.Z{
|
||||
Score: float64(data.TimeStamp),
|
||||
Member: deviceData,
|
||||
}).Result()
|
||||
if err != nil {
|
||||
klog.V(4).Info("Exit AddData")
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DataBaseConfig) GetDataByDeviceName(deviceName string) ([]*common.DataModel, error) {
|
||||
func (d *DataBaseConfig) GetDataByDeviceID(deviceID string) ([]*common.DataModel, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
dataJSON, err := RedisCli.ZRevRange(ctx, deviceName, 0, -1).Result()
|
||||
dataJSON, err := RedisCli.ZRevRange(ctx, deviceID, 0, -1).Result()
|
||||
if err != nil {
|
||||
klog.V(4).Infof("fail query data for deviceName,err:%v", err)
|
||||
}
|
||||
|
@ -121,7 +104,7 @@ func (d *DataBaseConfig) GetDataByDeviceName(deviceName string) ([]*common.DataM
|
|||
return dataModels, nil
|
||||
}
|
||||
|
||||
func (d *DataBaseConfig) GetPropertyDataByDeviceName(deviceName string, propertyData string) ([]*common.DataModel, error) {
|
||||
func (d *DataBaseConfig) GetPropertyDataByDeviceID(deviceID string, propertyData string) ([]*common.DataModel, error) {
|
||||
//TODO implement me
|
||||
return nil, errors.New("implement me")
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ func DataHandler(ctx context.Context, twin *common.Twin, client *driver.Customiz
|
|||
klog.Errorf("init redis database client err: %v", err)
|
||||
return
|
||||
}
|
||||
reportCycle := time.Duration(twin.Property.ReportCycle)
|
||||
reportCycle := time.Millisecond * time.Duration(twin.Property.ReportCycle)
|
||||
if reportCycle == 0 {
|
||||
reportCycle = common.DefaultReportCycle
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -44,9 +45,8 @@ func (d *DataBaseConfig) InitDbClient() error {
|
|||
DB, err = sql.Open("taosRestful", dsn)
|
||||
if err != nil {
|
||||
klog.Errorf("init TDEngine db fail, err= %v:", err)
|
||||
} else {
|
||||
klog.V(1).Infof("init TDEngine database successfully")
|
||||
}
|
||||
klog.V(1).Infof("init TDEngine database successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -59,17 +59,18 @@ func (d *DataBaseConfig) CloseSessio() {
|
|||
|
||||
func (d *DataBaseConfig) AddData(data *common.DataModel) error {
|
||||
|
||||
legal_table := strings.Replace(data.DeviceName, "-", "_", -1)
|
||||
legal_tag := strings.Replace(data.PropertyName, "-", "_", -1)
|
||||
tableName := data.Namespace + "/" + data.DeviceName
|
||||
legalTable := strings.Replace(tableName, "-", "_", -1)
|
||||
legalTag := strings.Replace(data.PropertyName, "-", "_", -1)
|
||||
|
||||
stable_name := fmt.Sprintf("SHOW STABLES LIKE '%s'", legal_table)
|
||||
stabel := fmt.Sprintf("CREATE STABLE %s (ts timestamp, devicename binary(64), propertyname binary(64), data binary(64),type binary(64)) TAGS (localtion binary(64));", legal_table)
|
||||
stableName := fmt.Sprintf("SHOW STABLES LIKE '%s'", legalTable)
|
||||
stabel := fmt.Sprintf("CREATE STABLE %s (ts timestamp, deviceid binary(64), propertyname binary(64), data binary(64),type binary(64)) TAGS (localtion binary(64));", legalTable)
|
||||
|
||||
datatime := time.Unix(data.TimeStamp/1e3, 0).Format("2006-01-02 15:04:05")
|
||||
insertSQL := fmt.Sprintf("INSERT INTO %s USING %s TAGS ('%s') VALUES('%v','%s', '%s', '%s', '%s');",
|
||||
legal_tag, legal_table, legal_tag, datatime, data.DeviceName, data.PropertyName, data.Value, data.Type)
|
||||
legalTag, legalTable, legalTag, datatime, tableName, data.PropertyName, data.Value, data.Type)
|
||||
|
||||
rows, _ := DB.Query(stable_name)
|
||||
rows, _ := DB.Query(stableName)
|
||||
defer rows.Close()
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
|
@ -97,8 +98,8 @@ func (d *DataBaseConfig) AddData(data *common.DataModel) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
func (d *DataBaseConfig) GetDataByDeviceName(deviceName string) ([]*common.DataModel, error) {
|
||||
querySql := fmt.Sprintf("SELECT ts, devicename, propertyname, data, type FROM %s", deviceName)
|
||||
func (d *DataBaseConfig) GetDataByDeviceID(deviceID string) ([]*common.DataModel, error) {
|
||||
querySql := fmt.Sprintf("SELECT ts, deviceid, propertyname, data, type FROM %s", deviceID)
|
||||
rows, err := DB.Query(querySql)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -119,17 +120,17 @@ func (d *DataBaseConfig) GetDataByDeviceName(deviceName string) ([]*common.DataM
|
|||
}
|
||||
return dataModel, nil
|
||||
}
|
||||
func (d *DataBaseConfig) GetPropertyDataByDeviceName(deviceName string, propertyData string) ([]*common.DataModel, error) {
|
||||
func (d *DataBaseConfig) GetPropertyDataByDeviceID(deviceID string, propertyData string) ([]*common.DataModel, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
return nil, errors.New("implement me")
|
||||
}
|
||||
func (d *DataBaseConfig) GetDataByTimeRange(deviceName string, start int64, end int64) ([]*common.DataModel, error) {
|
||||
func (d *DataBaseConfig) GetDataByTimeRange(deviceID string, start int64, end int64) ([]*common.DataModel, error) {
|
||||
|
||||
legal_table := strings.Replace(deviceName, "-", "_", -1)
|
||||
legalTable := strings.Replace(deviceID, "-", "_", -1)
|
||||
startTime := time.Unix(start, 0).UTC().Format("2006-01-02 15:04:05")
|
||||
endTime := time.Unix(end, 0).UTC().Format("2006-01-02 15:04:05")
|
||||
//Query data within a specified time range
|
||||
querySQL := fmt.Sprintf("SELECT ts, devicename, propertyname, data, type FROM %s WHERE ts >= '%s' AND ts <= '%s'", legal_table, startTime, endTime)
|
||||
querySQL := fmt.Sprintf("SELECT ts, deviceid, propertyname, data, type FROM %s WHERE ts >= '%s' AND ts <= '%s'", legalTable, startTime, endTime)
|
||||
fmt.Println(querySQL)
|
||||
rows, err := DB.Query(querySQL)
|
||||
if err != nil {
|
||||
|
@ -152,5 +153,5 @@ func (d *DataBaseConfig) GetDataByTimeRange(deviceName string, start int64, end
|
|||
}
|
||||
func (d *DataBaseConfig) DeleteDataByTimeRange(start int64, end int64) ([]*common.DataModel, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
return nil, errors.New("implement me")
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ func DataHandler(ctx context.Context, twin *common.Twin, client *driver.Customiz
|
|||
klog.Errorf("init database client err: %v", err)
|
||||
return
|
||||
}
|
||||
reportCycle := time.Duration(twin.Property.ReportCycle)
|
||||
reportCycle := time.Millisecond * time.Duration(twin.Property.ReportCycle)
|
||||
if reportCycle == 0 {
|
||||
reportCycle = common.DefaultReportCycle
|
||||
}
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
Copyright 2024 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 otel
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
|
||||
"go.opentelemetry.io/otel/sdk/metric"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
EndpointURL string `json:"endpointURL,omitempty"`
|
||||
}
|
||||
|
||||
func NewConfig(clientConfig json.RawMessage) (*Config, error) {
|
||||
var cfg Config
|
||||
err := json.Unmarshal(clientConfig, &cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cfg.EndpointURL == "" {
|
||||
return nil, errors.New("endpointURL is required")
|
||||
}
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
func (cfg *Config) InitProvider(reportCycle time.Duration, dataModel *common.DataModel) (*metric.MeterProvider, error) {
|
||||
exp, err := otlpmetrichttp.New(context.Background(), WithEndpointURL(cfg.EndpointURL)...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if reportCycle == 0 {
|
||||
reportCycle = common.DefaultReportCycle
|
||||
}
|
||||
|
||||
res, err := resource.Merge(
|
||||
resource.Default(),
|
||||
resource.NewSchemaless(
|
||||
attribute.String("device.id", dataModel.Namespace+"/"+dataModel.DeviceName),
|
||||
//semconv.DeviceID(dataModel.Namespace+"/"+dataModel.DeviceName), // go.opentelemetry.io/otel/semconv/v1.17.0+
|
||||
))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reader := metric.NewPeriodicReader(exp, metric.WithInterval(reportCycle))
|
||||
return metric.NewMeterProvider(
|
||||
metric.WithResource(res),
|
||||
metric.WithReader(reader),
|
||||
), nil
|
||||
}
|
||||
|
||||
func WithEndpointURL(v string) []otlpmetrichttp.Option {
|
||||
var opts []otlpmetrichttp.Option
|
||||
u, err := url.Parse(v)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
opts = append(opts,
|
||||
otlpmetrichttp.WithEndpoint(u.Host),
|
||||
otlpmetrichttp.WithURLPath(u.Path),
|
||||
)
|
||||
if u.Scheme != "https" {
|
||||
opts = append(opts, otlpmetrichttp.WithInsecure())
|
||||
}
|
||||
|
||||
return opts
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2024 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 otel
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/kubeedge/Template/driver"
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
)
|
||||
|
||||
const meterName = "github.com/kubeedge/Template/data/dbmethod/otel"
|
||||
|
||||
func DataHandler(ctx context.Context, twin *common.Twin, client *driver.CustomizedClient, visitorConfig *driver.VisitorConfig, dataModel *common.DataModel) {
|
||||
cfg, err := NewConfig(twin.Property.PushMethod.MethodConfig)
|
||||
if err != nil {
|
||||
klog.Errorf("new config fail: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
provider, err := cfg.InitProvider(time.Duration(twin.Property.ReportCycle), dataModel)
|
||||
if err != nil {
|
||||
klog.Errorf("init provider fail: %v", err)
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
err = provider.Shutdown(ctx)
|
||||
if err != nil {
|
||||
klog.Errorf("shutdown provider fail: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
meter := provider.Meter(meterName)
|
||||
|
||||
gauge, err := meter.Float64ObservableGauge(dataModel.PropertyName)
|
||||
if err != nil {
|
||||
klog.Errorf("create metric fail: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = meter.RegisterCallback(func(_ context.Context, o metric.Observer) error {
|
||||
data, err := client.GetDeviceData(visitorConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get device data fail: %v", err)
|
||||
}
|
||||
|
||||
o.ObserveFloat64(gauge, data.(float64))
|
||||
return nil
|
||||
}, gauge)
|
||||
if err != nil {
|
||||
klog.Errorf("register callback fail: %v", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
Copyright 2024 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 stream
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/kubeedge/Template/driver"
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
)
|
||||
|
||||
type StreamConfig struct {
|
||||
Format string `json:"format"`
|
||||
OutputDir string `json:"outputDir"`
|
||||
FrameCount int `json:"frameCount"`
|
||||
FrameInterval int `json:"frameInterval"`
|
||||
VideoNum int `json:"videoNum"`
|
||||
}
|
||||
|
||||
func StreamHandler(twin *common.Twin, client *driver.CustomizedClient, visitorConfig *driver.VisitorConfig) error {
|
||||
// Get RTSP URI from camera device
|
||||
streamURI, err := client.GetDeviceData(visitorConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// parse streamConfig data from device visitorConfig
|
||||
var streamConfig StreamConfig
|
||||
visitorConfigData, err := json.Marshal(visitorConfig.VisitorConfigData)
|
||||
err = json.Unmarshal(visitorConfigData, &streamConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unmarshal streamConfigs error: %v", err)
|
||||
}
|
||||
|
||||
switch twin.PropertyName {
|
||||
// Currently, the function of saving frames and saving videos is built-in according to the configuration.
|
||||
// Other functions can be expanded here.
|
||||
case common.SaveFrame:
|
||||
err = SaveFrame(streamURI.(string), streamConfig.OutputDir, streamConfig.Format, streamConfig.FrameCount, streamConfig.FrameInterval)
|
||||
case common.SaveVideo:
|
||||
err = SaveVideo(streamURI.(string), streamConfig.OutputDir, streamConfig.Format, streamConfig.FrameCount, streamConfig.VideoNum)
|
||||
default:
|
||||
err = fmt.Errorf("cannot find the processing method for the corresponding Property %s of the stream data", twin.PropertyName)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
klog.V(2).Infof("Successfully processed streaming data by %s", twin.PropertyName)
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Copyright 2024 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 stream
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/kubeedge/Template/driver"
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
)
|
||||
|
||||
type StreamConfig struct {
|
||||
Format string `json:"format"`
|
||||
OutputDir string `json:"outputDir"`
|
||||
FrameCount int `json:"frameCount"`
|
||||
FrameInterval int `json:"frameInterval"`
|
||||
VideoNum int `json:"videoNum"`
|
||||
}
|
||||
|
||||
func StreamHandler(twin *common.Twin, client *driver.CustomizedClient, visitorConfig *driver.VisitorConfig) error {
|
||||
return errors.New("need to add the stream flag when make generate if you want to enable stream data processing.")
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
Copyright 2024 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 stream
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/sailorvii/goav/avcodec"
|
||||
"github.com/sailorvii/goav/avformat"
|
||||
"github.com/sailorvii/goav/avutil"
|
||||
"github.com/sailorvii/goav/swscale"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
// GenFileName generate file name with current time. Formate f<year><month><day><hour><minute><second><millisecond>.<format>
|
||||
func GenFileName(dir string, format string) string {
|
||||
return fmt.Sprintf("%s/f%s.%s", dir, time.Now().Format(time.RFC3339Nano), format)
|
||||
}
|
||||
|
||||
func save(frame *avutil.Frame, width int, height int, dir string, format string) error {
|
||||
// Save video frames to picture file
|
||||
outputFile := GenFileName(dir, format)
|
||||
var outputFmtCtx *avformat.Context
|
||||
avformat.AvAllocOutputContext2(&outputFmtCtx, nil, nil, &outputFile)
|
||||
if outputFmtCtx == nil {
|
||||
return errors.New("Could not create output context")
|
||||
}
|
||||
defer outputFmtCtx.AvformatFreeContext()
|
||||
|
||||
ofmt := avformat.AvGuessFormat("", outputFile, "")
|
||||
outputFmtCtx.SetOformat(ofmt)
|
||||
|
||||
avIOContext, err := avformat.AvIOOpen(outputFile, avformat.AVIO_FLAG_WRITE)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not open output file '%s'", outputFile)
|
||||
}
|
||||
outputFmtCtx.SetPb(avIOContext)
|
||||
|
||||
outStream := outputFmtCtx.AvformatNewStream(nil)
|
||||
if outStream == nil {
|
||||
return errors.New("Failed allocating output stream")
|
||||
}
|
||||
|
||||
// Set the frame format
|
||||
pCodecCtx := outStream.Codec()
|
||||
pCodecCtx.SetCodecId(ofmt.GetVideoCodec())
|
||||
pCodecCtx.SetCodecType(avformat.AVMEDIA_TYPE_VIDEO)
|
||||
pCodecCtx.SetPixelFormat(avcodec.AV_PIX_FMT_YUVJ420P)
|
||||
pCodecCtx.SetWidth(width)
|
||||
pCodecCtx.SetHeight(height)
|
||||
pCodecCtx.SetTimeBase(1, 25)
|
||||
outputFmtCtx.AvDumpFormat(0, outputFile, 1)
|
||||
|
||||
// Get video codec
|
||||
pCodec := avcodec.AvcodecFindEncoder(pCodecCtx.CodecId())
|
||||
if pCodec == nil {
|
||||
return errors.New("Codec not found.")
|
||||
}
|
||||
defer pCodecCtx.AvcodecClose()
|
||||
|
||||
// open video codec
|
||||
cctx := avcodec.Context(*pCodecCtx)
|
||||
defer cctx.AvcodecClose()
|
||||
if cctx.AvcodecOpen2(pCodec, nil) < 0 {
|
||||
return errors.New("Could not open codec.")
|
||||
}
|
||||
|
||||
outputFmtCtx.AvformatWriteHeader(nil)
|
||||
ySize := width * height
|
||||
|
||||
// Write media data to media files
|
||||
var packet avcodec.Packet
|
||||
packet.AvNewPacket(ySize * 3)
|
||||
defer packet.AvPacketUnref()
|
||||
var gotPicture int
|
||||
if cctx.AvcodecEncodeVideo2(&packet, frame, &gotPicture) < 0 {
|
||||
return errors.New("Encode Error")
|
||||
}
|
||||
if gotPicture == 1 {
|
||||
packet.SetStreamIndex(outStream.Index())
|
||||
outputFmtCtx.AvWriteFrame(&packet)
|
||||
}
|
||||
|
||||
outputFmtCtx.AvWriteTrailer()
|
||||
if outputFmtCtx.Oformat().GetFlags()&avformat.AVFMT_NOFILE == 0 {
|
||||
if err = outputFmtCtx.Pb().Close(); err != nil {
|
||||
return fmt.Errorf("close output fmt context failed: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SaveFrame save frame.
|
||||
func SaveFrame(input string, outDir string, format string, frameCount int, frameInterval int) error {
|
||||
// Open video file
|
||||
avformat.AvDictSet(&avformat.Dict, "rtsp_transport", "tcp", 0)
|
||||
avformat.AvDictSet(&avformat.Dict, "max_delay", "5000000", 0)
|
||||
|
||||
pFormatContext := avformat.AvformatAllocContext()
|
||||
if avformat.AvformatOpenInput(&pFormatContext, input, nil, &avformat.Dict) != 0 {
|
||||
return fmt.Errorf("Unable to open file %s", input)
|
||||
}
|
||||
// Retrieve stream information
|
||||
if pFormatContext.AvformatFindStreamInfo(nil) < 0 {
|
||||
return errors.New("Couldn't find stream information")
|
||||
}
|
||||
// Dump information about file onto standard error
|
||||
pFormatContext.AvDumpFormat(0, input, 0)
|
||||
// Find the first video stream
|
||||
streamIndex := -1
|
||||
for i := 0; i < int(pFormatContext.NbStreams()); i++ {
|
||||
if pFormatContext.Streams()[i].CodecParameters().AvCodecGetType() == avformat.AVMEDIA_TYPE_VIDEO {
|
||||
streamIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if streamIndex == -1 {
|
||||
return errors.New("couldn't find video stream")
|
||||
}
|
||||
// Get a pointer to the codec context for the video stream
|
||||
pCodecCtxOrig := pFormatContext.Streams()[streamIndex].Codec()
|
||||
// Find the decoder for the video stream
|
||||
pCodec := avcodec.AvcodecFindDecoder(pCodecCtxOrig.CodecId())
|
||||
if pCodec == nil {
|
||||
return errors.New("unsupported codec")
|
||||
}
|
||||
// Copy context
|
||||
pCodecCtx := pCodec.AvcodecAllocContext3()
|
||||
if pCodecCtx.AvcodecCopyContext((*avcodec.Context)(unsafe.Pointer(pCodecCtxOrig))) != 0 {
|
||||
return errors.New("couldn't copy codec context")
|
||||
}
|
||||
|
||||
// Open codec
|
||||
if pCodecCtx.AvcodecOpen2(pCodec, nil) < 0 {
|
||||
return errors.New("could not open codec")
|
||||
}
|
||||
|
||||
// Allocate video frame
|
||||
pFrame := avutil.AvFrameAlloc()
|
||||
|
||||
// Allocate an AVFrame structure
|
||||
pFrameRGB := avutil.AvFrameAlloc()
|
||||
if pFrameRGB == nil {
|
||||
return errors.New("unable to allocate RGB Frame")
|
||||
}
|
||||
// Determine required buffer size and allocate buffer
|
||||
numBytes := uintptr(avcodec.AvpictureGetSize(avcodec.AV_PIX_FMT_YUVJ420P, pCodecCtx.Width(),
|
||||
pCodecCtx.Height()))
|
||||
buffer := avutil.AvMalloc(numBytes)
|
||||
|
||||
// Assign appropriate parts of buffer to image planes in pFrameRGB
|
||||
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
|
||||
// of AVPicture
|
||||
avp := (*avcodec.Picture)(unsafe.Pointer(pFrameRGB))
|
||||
avp.AvpictureFill((*uint8)(buffer), avcodec.AV_PIX_FMT_YUVJ420P, pCodecCtx.Width(), pCodecCtx.Height())
|
||||
|
||||
// initialize SWS context for software scaling
|
||||
swsCtx := swscale.SwsGetcontext(
|
||||
pCodecCtx.Width(),
|
||||
pCodecCtx.Height(),
|
||||
(swscale.PixelFormat)(pCodecCtx.PixFmt()),
|
||||
pCodecCtx.Width(),
|
||||
pCodecCtx.Height(),
|
||||
avcodec.AV_PIX_FMT_YUVJ420P,
|
||||
avcodec.SWS_BICUBIC,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
frameNum := 0
|
||||
failureNum := 0
|
||||
failureCount := 5 * frameCount
|
||||
packet := avcodec.AvPacketAlloc()
|
||||
// Start capturing and saving video frames
|
||||
for {
|
||||
if failureNum >= failureCount {
|
||||
klog.Error("the number of failed attempts to save frames has reached the upper limit")
|
||||
return errors.New("the number of failed attempts to save frames has reached the upper limit")
|
||||
}
|
||||
|
||||
if pFormatContext.AvReadFrame(packet) < 0 {
|
||||
klog.Error("Read frame failed")
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
// Is this a packet from the video stream?
|
||||
if packet.StreamIndex() != streamIndex {
|
||||
failureNum++
|
||||
continue
|
||||
}
|
||||
|
||||
// Decode video frame
|
||||
response := pCodecCtx.AvcodecSendPacket(packet)
|
||||
if response < 0 {
|
||||
klog.Errorf("Error while sending a packet to the decoder: %s", avutil.ErrorFromCode(response))
|
||||
failureNum++
|
||||
continue
|
||||
}
|
||||
response = pCodecCtx.AvcodecReceiveFrame((*avutil.Frame)(unsafe.Pointer(pFrame)))
|
||||
if response == avutil.AvErrorEAGAIN || response == avutil.AvErrorEOF {
|
||||
failureNum++
|
||||
continue
|
||||
} else if response < 0 {
|
||||
klog.Errorf("Error while receiving a frame from the decoder: %s", avutil.ErrorFromCode(response))
|
||||
failureNum++
|
||||
continue
|
||||
}
|
||||
// Convert the image from its native format to RGB
|
||||
swscale.SwsScale2(swsCtx, avutil.Data(pFrame),
|
||||
avutil.Linesize(pFrame), 0, pCodecCtx.Height(),
|
||||
avutil.Data(pFrameRGB), avutil.Linesize(pFrameRGB))
|
||||
|
||||
// Save the frame to disk
|
||||
err := save(pFrameRGB, pCodecCtx.Width(), pCodecCtx.Height(), outDir, format)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
continue
|
||||
}
|
||||
frameNum++
|
||||
if frameNum >= frameCount {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(time.Nanosecond * time.Duration(frameInterval))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
Copyright 2024 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 stream
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/sailorvii/goav/avcodec"
|
||||
"github.com/sailorvii/goav/avformat"
|
||||
"github.com/sailorvii/goav/avutil"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
// SaveVideo save video.
|
||||
func SaveVideo(inputFile string, outDir string, format string, frameCount int, videoNum int) error {
|
||||
var fragmentedMp4Options int
|
||||
//initialize input file with Context
|
||||
var inputFmtCtx *avformat.Context
|
||||
|
||||
avformat.AvDictSet(&avformat.Dict, "rtsp_transport", "tcp", 0)
|
||||
avformat.AvDictSet(&avformat.Dict, "max_delay", "5000000", 0)
|
||||
|
||||
if avformat.AvformatOpenInput(&inputFmtCtx, inputFile, nil, &avformat.Dict) < 0 {
|
||||
return fmt.Errorf("could not open input file '%s", inputFile)
|
||||
}
|
||||
defer inputFmtCtx.AvformatFreeContext()
|
||||
//read stream information
|
||||
|
||||
if inputFmtCtx.AvformatFindStreamInfo(nil) < 0 {
|
||||
return errors.New("failed to retrieve input stream information")
|
||||
}
|
||||
|
||||
//initialize streamMapping
|
||||
streamMappingSize := int(inputFmtCtx.NbStreams())
|
||||
streamMapping := make([]int, streamMappingSize)
|
||||
var streamIndex int
|
||||
|
||||
validTypeMap := map[avcodec.MediaType]int{
|
||||
avformat.AVMEDIA_TYPE_VIDEO: 1,
|
||||
avformat.AVMEDIA_TYPE_AUDIO: 1,
|
||||
avformat.AVMEDIA_TYPE_SUBTITLE: 1,
|
||||
}
|
||||
var inCodecParam *avcodec.AvCodecParameters
|
||||
defer inCodecParam.AvCodecParametersFree()
|
||||
|
||||
var outputFmtCtx *avformat.Context
|
||||
outputFile := GenFileName(outDir, format)
|
||||
avformat.AvAllocOutputContext2(&outputFmtCtx, nil, nil, &outputFile)
|
||||
if outputFmtCtx == nil {
|
||||
return errors.New("Could not create output context")
|
||||
}
|
||||
defer outputFmtCtx.AvformatFreeContext()
|
||||
|
||||
for index, inStream := range inputFmtCtx.Streams() {
|
||||
inCodecParam = inStream.CodecParameters()
|
||||
inCodecType := inCodecParam.AvCodecGetType()
|
||||
|
||||
if validTypeMap[inCodecType] == 0 {
|
||||
streamMapping[index] = -1
|
||||
continue
|
||||
}
|
||||
streamMapping[index] = streamIndex
|
||||
streamIndex++
|
||||
outStream := outputFmtCtx.AvformatNewStream(nil)
|
||||
if outStream == nil {
|
||||
return errors.New("Failed allocating output stream")
|
||||
}
|
||||
if inCodecParam.AvCodecParametersCopyTo(outStream.CodecParameters()) < 0 {
|
||||
return errors.New("Failed to copy codec parameters")
|
||||
}
|
||||
}
|
||||
|
||||
// initialize opts
|
||||
var opts *avutil.Dictionary
|
||||
defer opts.AvDictFree()
|
||||
if fragmentedMp4Options != 0 {
|
||||
opts.AvDictSet("movflags", "frag_keyframe+empty_moov+default_base_moof", 0)
|
||||
}
|
||||
var packet avcodec.Packet
|
||||
defer packet.AvPacketUnref()
|
||||
|
||||
// Capture a set number of video segments
|
||||
for idx := 0; idx < videoNum; idx++ {
|
||||
outputFile = GenFileName(outDir, format)
|
||||
// initialize output file with Context
|
||||
outputFmtCtx.AvDumpFormat(0, outputFile, 1)
|
||||
if outputFmtCtx.Oformat().GetFlags()&avformat.AVFMT_NOFILE == 0 {
|
||||
avIOContext, err := avformat.AvIOOpen(outputFile, avformat.AVIO_FLAG_WRITE)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not open output file '%s'", outputFile)
|
||||
}
|
||||
outputFmtCtx.SetPb(avIOContext)
|
||||
}
|
||||
|
||||
if outputFmtCtx.AvformatWriteHeader(&opts) < 0 {
|
||||
return errors.New("Error occurred when opening output file")
|
||||
}
|
||||
// Capture and generate video according to the set number of frames
|
||||
for i := 1; i < frameCount; i++ {
|
||||
if inputFmtCtx.AvReadFrame(&packet) < 0 {
|
||||
return errors.New("read frame failed")
|
||||
}
|
||||
index := packet.StreamIndex()
|
||||
inputStream := inputFmtCtx.Streams()[index]
|
||||
if index >= streamMappingSize || streamMapping[index] < 0 {
|
||||
continue
|
||||
}
|
||||
packet.SetStreamIndex(streamMapping[index])
|
||||
outputStream := outputFmtCtx.Streams()[index]
|
||||
packet.AvPacketRescaleTs(inputStream.TimeBase(), outputStream.TimeBase())
|
||||
packet.SetPos(-1)
|
||||
if outputFmtCtx.AvInterleavedWriteFrame(&packet) < 0 {
|
||||
klog.Error("Error muxing packet")
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
outputFmtCtx.AvWriteTrailer()
|
||||
if outputFmtCtx.Oformat().GetFlags()&avformat.AVFMT_NOFILE == 0 {
|
||||
if outputFmtCtx.Pb().Close() != nil {
|
||||
klog.Error("Error close output context")
|
||||
return errors.New("error close output context")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -14,12 +14,15 @@ import (
|
|||
"k8s.io/klog/v2"
|
||||
|
||||
dbInflux "github.com/kubeedge/Template/data/dbmethod/influxdb2"
|
||||
dbMysql "github.com/kubeedge/Template/data/dbmethod/mysql"
|
||||
dbRedis "github.com/kubeedge/Template/data/dbmethod/redis"
|
||||
dbTdengine "github.com/kubeedge/Template/data/dbmethod/tdengine"
|
||||
httpMethod "github.com/kubeedge/Template/data/publish/http"
|
||||
mqttMethod "github.com/kubeedge/Template/data/publish/mqtt"
|
||||
otelMethod "github.com/kubeedge/Template/data/publish/otel"
|
||||
"github.com/kubeedge/Template/data/stream"
|
||||
"github.com/kubeedge/Template/driver"
|
||||
dmiapi "github.com/kubeedge/kubeedge/pkg/apis/dmi/v1beta1"
|
||||
dmiapi "github.com/kubeedge/api/apis/dmi/v1beta1"
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
"github.com/kubeedge/mapper-framework/pkg/global"
|
||||
"github.com/kubeedge/mapper-framework/pkg/util/parse"
|
||||
|
@ -106,6 +109,16 @@ func (d *DevPanel) start(ctx context.Context, dev *driver.CustomizedDev) {
|
|||
|
||||
// dataHandler initialize the timer to handle data plane and devicetwin.
|
||||
func dataHandler(ctx context.Context, dev *driver.CustomizedDev) {
|
||||
// handle device status report
|
||||
getStates := &DeviceStates{
|
||||
Client: dev.CustomizedClient,
|
||||
DeviceName: dev.Instance.Name,
|
||||
DeviceNamespace: dev.Instance.Namespace,
|
||||
ReportToCloud: dev.Instance.Status.ReportToCloud,
|
||||
ReportCycle: time.Millisecond * time.Duration(dev.Instance.Status.ReportCycle),
|
||||
}
|
||||
go getStates.Run(ctx)
|
||||
// handle device twin report
|
||||
for _, twin := range dev.Instance.Twins {
|
||||
twin.Property.PProperty.DataType = strings.ToLower(twin.Property.PProperty.DataType)
|
||||
var visitorConfig driver.VisitorConfig
|
||||
|
@ -121,6 +134,18 @@ func dataHandler(ctx context.Context, dev *driver.CustomizedDev) {
|
|||
klog.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
// If the device property type is streaming, it will directly enter the streaming data processing function,
|
||||
// such as saving frames or saving videos, and will no longer push it to the user database and application.
|
||||
// If there are other needs for stream data processing, users can add functions in the mapper/data/stream directory.
|
||||
if twin.Property.PProperty.DataType == "stream" {
|
||||
err = stream.StreamHandler(&twin, dev.CustomizedClient, &visitorConfig)
|
||||
if err != nil {
|
||||
klog.Errorf("processed streaming data by %s Error: %v", twin.PropertyName, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// handle twin
|
||||
twinData := &TwinData{
|
||||
DeviceName: dev.Instance.Name,
|
||||
|
@ -131,18 +156,18 @@ func dataHandler(ctx context.Context, dev *driver.CustomizedDev) {
|
|||
ObservedDesired: twin.ObservedDesired,
|
||||
VisitorConfig: &visitorConfig,
|
||||
Topic: fmt.Sprintf(common.TopicTwinUpdate, dev.Instance.ID),
|
||||
CollectCycle: time.Duration(twin.Property.CollectCycle),
|
||||
CollectCycle: time.Millisecond * time.Duration(twin.Property.CollectCycle),
|
||||
ReportToCloud: twin.Property.ReportToCloud,
|
||||
}
|
||||
go twinData.Run(ctx)
|
||||
|
||||
dataModel := common.NewDataModel(dev.Instance.Name, twin.Property.PropertyName, dev.Instance.Namespace, common.WithType(twin.ObservedDesired.Metadata.Type))
|
||||
// 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)
|
||||
switch twin.Property.PushMethod.DBMethod.DBMethodName {
|
||||
// TODO add more database
|
||||
|
@ -152,6 +177,8 @@ func dataHandler(ctx context.Context, dev *driver.CustomizedDev) {
|
|||
dbRedis.DataHandler(ctx, &twin, dev.CustomizedClient, &visitorConfig, dataModel)
|
||||
case "tdengine":
|
||||
dbTdengine.DataHandler(ctx, &twin, dev.CustomizedClient, &visitorConfig, dataModel)
|
||||
case "mysql":
|
||||
dbMysql.DataHandler(ctx, &twin, dev.CustomizedClient, &visitorConfig, dataModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -159,13 +186,18 @@ func dataHandler(ctx context.Context, dev *driver.CustomizedDev) {
|
|||
|
||||
// pushHandler start data panel work
|
||||
func pushHandler(ctx context.Context, twin *common.Twin, client *driver.CustomizedClient, visitorConfig *driver.VisitorConfig, dataModel *common.DataModel) {
|
||||
if twin.Property.PushMethod.MethodName == common.PushMethodOTEL {
|
||||
otelMethod.DataHandler(ctx, twin, client, visitorConfig, dataModel)
|
||||
return
|
||||
}
|
||||
|
||||
var dataPanel global.DataPanel
|
||||
var err error
|
||||
// initialization dataPanel
|
||||
switch twin.Property.PushMethod.MethodName {
|
||||
case "http":
|
||||
case common.PushMethodHTTP:
|
||||
dataPanel, err = httpMethod.NewDataPanel(twin.Property.PushMethod.MethodConfig)
|
||||
case "mqtt":
|
||||
case common.PushMethodMQTT:
|
||||
dataPanel, err = mqttMethod.NewDataPanel(twin.Property.PushMethod.MethodConfig)
|
||||
default:
|
||||
err = errors.New("custom protocols are not currently supported when push data")
|
||||
|
@ -180,7 +212,7 @@ func pushHandler(ctx context.Context, twin *common.Twin, client *driver.Customiz
|
|||
klog.Errorf("init publish method err: %v", err)
|
||||
return
|
||||
}
|
||||
reportCycle := time.Duration(twin.Property.ReportCycle)
|
||||
reportCycle := time.Millisecond * time.Duration(twin.Property.ReportCycle)
|
||||
if reportCycle == 0 {
|
||||
reportCycle = common.DefaultReportCycle
|
||||
}
|
||||
|
@ -221,6 +253,9 @@ func dbHandler(ctx context.Context, twin *common.Twin, client *driver.Customized
|
|||
|
||||
case "tdengine":
|
||||
dbTdengine.DataHandler(ctx, twin, client, visitorConfig, dataModel)
|
||||
|
||||
case "mysql":
|
||||
dbMysql.DataHandler(ctx, twin, client, visitorConfig, dataModel)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,12 +266,18 @@ func setVisitor(visitorConfig *driver.VisitorConfig, twin *common.Twin, dev *dri
|
|||
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
|
||||
var value interface{}
|
||||
if twin.ObservedDesired.Value != "" {
|
||||
convertedValue, 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
|
||||
}
|
||||
value = convertedValue
|
||||
} else {
|
||||
value = twin.ObservedDesired.Value
|
||||
}
|
||||
err = dev.CustomizedClient.SetDeviceData(value, visitorConfig)
|
||||
err := dev.CustomizedClient.SetDeviceData(value, visitorConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s set device data error: %v", twin.PropertyName, err)
|
||||
}
|
||||
|
@ -252,12 +293,14 @@ func (d *DevPanel) DevInit(deviceList []*dmiapi.Device, deviceModelList []*dmiap
|
|||
for i := range deviceModelList {
|
||||
model := deviceModelList[i]
|
||||
cur := parse.GetDeviceModelFromGrpc(model)
|
||||
d.models[model.Name] = cur
|
||||
modelID := parse.GetResourceID(model.Namespace, model.Name)
|
||||
d.models[modelID] = cur
|
||||
}
|
||||
|
||||
for i := range deviceList {
|
||||
device := deviceList[i]
|
||||
commonModel := d.models[device.Spec.DeviceModelReference]
|
||||
modelID := parse.GetResourceID(device.Namespace, device.Spec.DeviceModelReference)
|
||||
commonModel := d.models[modelID]
|
||||
protocol, err := parse.BuildProtocolFromGrpc(device)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -394,6 +437,71 @@ func (d *DevPanel) RemoveDevice(deviceID string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// WriteDevice write value to the device
|
||||
func (d *DevPanel) WriteDevice(deviceMethodName, deviceID, propertyName, data string) error {
|
||||
var dataType string
|
||||
var deviceproperty common.DeviceProperty
|
||||
d.serviceMutex.Lock()
|
||||
defer d.serviceMutex.Unlock()
|
||||
dev, ok := d.devices[deviceID]
|
||||
if !ok {
|
||||
return fmt.Errorf("not found device %s", deviceID)
|
||||
}
|
||||
|
||||
deviceMethodMap := make(map[string][]string)
|
||||
|
||||
// get all deviceMethod of the device
|
||||
for _, method := range dev.Instance.Methods {
|
||||
deviceMethodMap[method.Name] = append(deviceMethodMap[method.Name], method.PropertyNames...)
|
||||
}
|
||||
// Determine whether the called device method exists
|
||||
propertyNames, ok := deviceMethodMap[deviceMethodName]
|
||||
if !ok {
|
||||
return fmt.Errorf("deviceMethod name %s does not exist in device instance", deviceMethodName)
|
||||
}
|
||||
// Determine whether the device property to be written is in the list defined by the device method
|
||||
flag := false
|
||||
for _, name := range propertyNames {
|
||||
if name == propertyName {
|
||||
flag = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !flag {
|
||||
return fmt.Errorf("deviceProperty %s to be written is not in the list defined by devicemethod", propertyName)
|
||||
}
|
||||
// Determine whether the device property to be written is in the device instance
|
||||
flag = false
|
||||
for _, property := range dev.Instance.Properties {
|
||||
if property.PropertyName != propertyName {
|
||||
continue
|
||||
}
|
||||
dataType = property.PProperty.DataType
|
||||
deviceproperty = property
|
||||
flag = true
|
||||
break
|
||||
}
|
||||
if !flag {
|
||||
return fmt.Errorf("can't find device propertyName %s in device instance", propertyName)
|
||||
}
|
||||
klog.V(2).Infof("start writing values %v to device %s property %s", data, deviceID, propertyName)
|
||||
writeData, err := common.Convert(strings.ToLower(dataType), data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("conversion data format failed, datatype is %s, data is %s", strings.ToLower(dataType), data)
|
||||
}
|
||||
var visitorConfig driver.VisitorConfig
|
||||
err = json.Unmarshal(deviceproperty.Visitors, &visitorConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = dev.CustomizedClient.DeviceDataWrite(&visitorConfig, deviceMethodName, propertyName, writeData)
|
||||
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]
|
||||
|
@ -466,3 +574,28 @@ func (d *DevPanel) GetTwinResult(deviceID string, twinName string) (string, stri
|
|||
}
|
||||
return res, dataType, nil
|
||||
}
|
||||
|
||||
// GetDeviceMethod get method and property dataType of device
|
||||
func (d *DevPanel) GetDeviceMethod(deviceID string) (map[string][]string, map[string]string, error) {
|
||||
klog.V(2).Infof("starting get method and property dataType of device %s", deviceID)
|
||||
d.serviceMutex.Lock()
|
||||
defer d.serviceMutex.Unlock()
|
||||
found, ok := d.devices[deviceID]
|
||||
if !ok || found == nil {
|
||||
return nil, nil, fmt.Errorf("device %s not found", deviceID)
|
||||
}
|
||||
|
||||
deviceMethodMap := make(map[string][]string)
|
||||
propertyTypeMap := make(map[string]string)
|
||||
|
||||
// get all deviceMethod of the device
|
||||
for _, method := range found.Instance.Methods {
|
||||
deviceMethodMap[method.Name] = append(deviceMethodMap[method.Name], method.PropertyNames...)
|
||||
}
|
||||
|
||||
// get all deviceProperty type of the device
|
||||
for _, property := range found.Instance.Properties {
|
||||
propertyTypeMap[property.Name] = strings.ToLower(property.PProperty.DataType) // The original data type is an uppercase form such as INT FLOAT and needs to be converted.
|
||||
}
|
||||
return deviceMethodMap, propertyTypeMap, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright 2024 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 device
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/kubeedge/Template/driver"
|
||||
dmiapi "github.com/kubeedge/api/apis/dmi/v1beta1"
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
"github.com/kubeedge/mapper-framework/pkg/grpcclient"
|
||||
)
|
||||
|
||||
// DeviceStates is structure for getting device states.
|
||||
type DeviceStates struct {
|
||||
Client *driver.CustomizedClient
|
||||
DeviceName string
|
||||
DeviceNamespace string
|
||||
ReportToCloud bool
|
||||
ReportCycle time.Duration
|
||||
}
|
||||
|
||||
// Run timer function.
|
||||
func (deviceStates *DeviceStates) PushStatesToEdgeCore() {
|
||||
states, err := deviceStates.Client.GetDeviceStates()
|
||||
if err != nil {
|
||||
klog.Errorf("GetDeviceStates failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
statesRequest := &dmiapi.ReportDeviceStatesRequest{
|
||||
DeviceName: deviceStates.DeviceName,
|
||||
State: states,
|
||||
DeviceNamespace: deviceStates.DeviceNamespace,
|
||||
}
|
||||
|
||||
klog.V(4).Infof("send device %s status %s request to cloud", statesRequest.DeviceName, statesRequest.State)
|
||||
if err = grpcclient.ReportDeviceStates(statesRequest); err != nil {
|
||||
klog.Errorf("fail to report device states of %s with err: %+v", deviceStates.DeviceName, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (deviceStates *DeviceStates) Run(ctx context.Context) {
|
||||
// No need to report device status to the cloud
|
||||
if !deviceStates.ReportToCloud {
|
||||
return
|
||||
}
|
||||
// Set device status report cycle
|
||||
if deviceStates.ReportCycle == 0 {
|
||||
deviceStates.ReportCycle = common.DefaultReportCycle
|
||||
}
|
||||
ticker := time.NewTicker(deviceStates.ReportCycle)
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
deviceStates.PushStatesToEdgeCore()
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ import (
|
|||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/kubeedge/Template/driver"
|
||||
dmiapi "github.com/kubeedge/kubeedge/pkg/apis/dmi/v1beta1"
|
||||
dmiapi "github.com/kubeedge/api/apis/dmi/v1beta1"
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
"github.com/kubeedge/mapper-framework/pkg/grpcclient"
|
||||
"github.com/kubeedge/mapper-framework/pkg/util/parse"
|
||||
|
|
|
@ -2,6 +2,8 @@ package driver
|
|||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
)
|
||||
|
||||
func NewClient(protocol ProtocolConfig) (*CustomizedClient, error) {
|
||||
|
@ -25,6 +27,12 @@ func (c *CustomizedClient) GetDeviceData(visitor *VisitorConfig) (interface{}, e
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *CustomizedClient) DeviceDataWrite(visitor *VisitorConfig, deviceMethodName string, propertyName string, data interface{}) error {
|
||||
// TODO: add the code to write device's data
|
||||
// you can use c.ProtocolConfig and visitor to write data to device
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CustomizedClient) SetDeviceData(data interface{}, visitor *VisitorConfig) error {
|
||||
// TODO: set device's data
|
||||
// you can use c.ProtocolConfig and visitor
|
||||
|
@ -36,3 +44,8 @@ func (c *CustomizedClient) StopDevice() error {
|
|||
// you can use c.ProtocolConfig
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CustomizedClient) GetDeviceStates() (string, error) {
|
||||
// TODO: GetDeviceStates
|
||||
return common.DeviceStatusOK, nil
|
||||
}
|
||||
|
|
|
@ -1,39 +1,58 @@
|
|||
module github.com/kubeedge/Template
|
||||
|
||||
go 1.20
|
||||
go 1.22.0
|
||||
|
||||
toolchain go1.23.2
|
||||
|
||||
require (
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.13.0
|
||||
github.com/kubeedge/kubeedge v1.16.0-beta.0
|
||||
github.com/kubeedge/mapper-framework v0.0.0-20240119021034-e7755b2f421c
|
||||
github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace // indirect
|
||||
github.com/kubeedge/api v0.0.0
|
||||
github.com/kubeedge/mapper-framework v0.0.0
|
||||
github.com/sailorvii/goav v0.1.4
|
||||
github.com/taosdata/driver-go/v3 v3.5.1
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
google.golang.org/grpc v1.53.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/klog/v2 v2.100.1
|
||||
go.opentelemetry.io/otel v1.23.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.23.0
|
||||
go.opentelemetry.io/otel/metric v1.23.0
|
||||
go.opentelemetry.io/otel/sdk v1.23.0
|
||||
go.opentelemetry.io/otel/sdk/metric v1.23.0
|
||||
k8s.io/klog/v2 v2.120.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
||||
github.com/avast/retry-go v3.0.0+incompatible // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
|
||||
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kr/text v0.1.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/oapi-codegen/runtime v1.0.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
|
||||
github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace // indirect
|
||||
go.opentelemetry.io/otel/trace v1.23.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
golang.org/x/net v0.30.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect
|
||||
google.golang.org/grpc v1.67.1 // indirect
|
||||
google.golang.org/protobuf v1.35.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
github.com/kubeedge/api => ../api
|
||||
github.com/kubeedge/mapper-framework => ../mapper-framework
|
||||
)
|
||||
|
|
|
@ -4,8 +4,10 @@ github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP
|
|||
github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0=
|
||||
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
||||
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
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=
|
||||
|
@ -13,25 +15,33 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r
|
|||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0 h1:1F8mhG9+aO5/xpdtFkW4SxOJB67ukuDC3t2y2qayIX0=
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/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/gosuri/uilive v0.0.0-20170323041506-ac356e6e42cd/go.mod h1:qkLSc0A5EXSP6B04TrN4oQoxqFI7A8XvoXSlJi8cwk8=
|
||||
github.com/gosuri/uiprogress v0.0.0-20170224063937-d0567a9d84a1/go.mod h1:C1RTYn4Sc7iEyf6j8ft5dyoZ4212h8G1ol9QQluh5+0=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.13.0 h1:ioBbLmR5NMbAjP4UVA5r9b5xGjpABD7j65pI8kFphDM=
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.13.0/go.mod h1:k+spCbt9hcvqvUiz0sr5D8LolXHqAAOfPw9v/RIRHl4=
|
||||
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU=
|
||||
|
@ -39,56 +49,76 @@ github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1
|
|||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
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/kubeedge/kubeedge v1.16.0-beta.0 h1:wMImL1r1PqwBCLCrZlEHJ83o+h4u2yFOABktHFDeDyQ=
|
||||
github.com/kubeedge/kubeedge v1.16.0-beta.0/go.mod h1:NbL/UWB68wuY5itB/0jMtDyI04Q+Iw2CJshOQz/WJS4=
|
||||
github.com/kubeedge/mapper-framework v0.0.0-20240119021034-e7755b2f421c h1:MgUJkEWzYl29dLDDLPshKEoUwqmJexCJlJTbLQQWneM=
|
||||
github.com/kubeedge/mapper-framework v0.0.0-20240119021034-e7755b2f421c/go.mod h1:at9JLS7mVPMBAvzlRMfn2E4p4ReoVv9/yQ2oYU86t00=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/oapi-codegen/runtime v1.0.0 h1:P4rqFX5fMFWqRzY9M/3YF9+aPSPPB06IzP2P7oOxrWo=
|
||||
github.com/oapi-codegen/runtime v1.0.0/go.mod h1:LmCUMQuPB4M/nLXilQXhHw+BLZdDb18B34OO356yJ/A=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk=
|
||||
github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg=
|
||||
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/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/sailorvii/goav v0.1.4 h1:4FwbikqIxx26dcHlZ8195WSPQSWbNnvRvTSgRTPgh2w=
|
||||
github.com/sailorvii/goav v0.1.4/go.mod h1:upppsyLr1RLWDZ0+U3RYYGTv9NVwCjz14j/zzxRM018=
|
||||
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/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/taosdata/driver-go/v3 v3.5.1 h1:ln8gLJ6HR6gHU6dodmOa9utUjPUpAcdIplh6arFO26Q=
|
||||
github.com/taosdata/driver-go/v3 v3.5.1/go.mod h1:H2vo/At+rOPY1aMzUV9P49SVX7NlXb3LAbKw+MCLrmU=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA=
|
||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
|
||||
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
|
||||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
|
||||
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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
go.opentelemetry.io/otel v1.23.0 h1:Df0pqjqExIywbMCMTxkAwzjLZtRf+bBKLbUcpxO2C9E=
|
||||
go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFufObyB0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.23.0 h1:Lc6m+ytInMOSdTOGl+Y4qPzTlZ7QPb0pL+1JuUEt4Ao=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.23.0/go.mod h1:Rv15/kBGgH1lHvfd6Y0FlnMuy8F7MdSSiqVjn8Q8KUQ=
|
||||
go.opentelemetry.io/otel/metric v1.23.0 h1:pazkx7ss4LFVVYSxYew7L5I6qvLXHA0Ap2pwV+9Cnpo=
|
||||
go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms20Jb7Bbp+HiTo=
|
||||
go.opentelemetry.io/otel/sdk v1.23.0 h1:0KM9Zl2esnl+WSukEmlaAEjVY5HDZANOHferLq36BPc=
|
||||
go.opentelemetry.io/otel/sdk v1.23.0/go.mod h1:wUscup7byToqyKJSilEtMf34FgdCAsFpFOjXnAwFfO0=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.23.0 h1:u81lMvmK6GMgN4Fty7K7S6cSKOZhMKJMK2TB+KaTs0I=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.23.0/go.mod h1:2LUOToN/FdX6wtfpHybOnCZjoZ6ViYajJYMiJ1LKDtQ=
|
||||
go.opentelemetry.io/otel/trace v1.23.0 h1:37Ik5Ib7xfYVb4V1UtnT97T1jI+AoIYkJyPkuL4iJgI=
|
||||
go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5UkggkflQwDScNUsk=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
|
||||
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
|
||||
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
|
||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
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=
|
||||
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
|
||||
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
|
||||
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
|
|
32
go.mod
32
go.mod
|
@ -1,25 +1,31 @@
|
|||
module github.com/kubeedge/mapper-framework
|
||||
|
||||
go 1.20
|
||||
go 1.22.9
|
||||
|
||||
toolchain go1.24.2
|
||||
|
||||
require (
|
||||
github.com/avast/retry-go v3.0.0+incompatible
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/kubeedge/kubeedge v1.15.0-beta.0.0.20240118080528-4237f6f6805e
|
||||
github.com/kubeedge/api v0.0.0
|
||||
github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
google.golang.org/grpc v1.53.0
|
||||
google.golang.org/protobuf v1.30.0
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
google.golang.org/grpc v1.63.0
|
||||
google.golang.org/protobuf v1.35.2
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
k8s.io/klog/v2 v2.100.1
|
||||
k8s.io/klog/v2 v2.120.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
)
|
||||
|
||||
replace github.com/kubeedge/api => ../api
|
||||
|
|
70
go.sum
70
go.sum
|
@ -1,47 +1,51 @@
|
|||
github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0=
|
||||
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
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/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
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/kubeedge/kubeedge v1.15.0-beta.0.0.20240118080528-4237f6f6805e h1:SQD/Z9/z75tQpnZKGs179ugFywJH2tj0bAKlDh0M9Gs=
|
||||
github.com/kubeedge/kubeedge v1.15.0-beta.0.0.20240118080528-4237f6f6805e/go.mod h1:NbL/UWB68wuY5itB/0jMtDyI04Q+Iw2CJshOQz/WJS4=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
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/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
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/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA=
|
||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
|
||||
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
|
||||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
|
||||
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.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
google.golang.org/grpc v1.63.0 h1:WjKe+dnvABXyPJMD7KDNLxtoGk5tgk+YFWN6cBWjZE8=
|
||||
google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
|
||||
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
|
||||
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
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/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
|
||||
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
|
||||
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
|
|
|
@ -11,14 +11,20 @@ MAPPER_DIR="$(cd "$(dirname "$ROOT_DIR")" && pwd -P)"
|
|||
|
||||
function entry() {
|
||||
# copy template
|
||||
if [ $# -eq 0 ] ;then
|
||||
if [ $# -ne 2 ] ;then
|
||||
read -p "Please input the mapper name (like 'Bluetooth', 'BLE'): " -r mapperName
|
||||
if [[ -z "${mapperName}" ]]; then
|
||||
echo "the mapper name is required"
|
||||
exit 1
|
||||
fi
|
||||
read -p "Please input the build method (like 'stream', 'nostream'): " -r buildMethod
|
||||
if [[ -z "${buildMethod}" ]]; then
|
||||
echo "the build method is required"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
mapperName=$1
|
||||
buildMethod=$2
|
||||
fi
|
||||
mapperNameLowercase=$(echo -n "${mapperName}" | tr '[:upper:]' '[:lower:]')
|
||||
mapperPath="${MAPPER_DIR}/${mapperNameLowercase}"
|
||||
|
@ -27,10 +33,26 @@ function entry() {
|
|||
exit 1
|
||||
fi
|
||||
cp -r "${ROOT_DIR}/_template/mapper" "${mapperPath}"
|
||||
if [ "${buildMethod}" = "stream" ]; then
|
||||
rm "${mapperPath}/data/stream/handler_nostream.go"
|
||||
fi
|
||||
|
||||
if [ "${buildMethod}" = "nostream" ]; then
|
||||
cd "${mapperPath}/data/stream"
|
||||
ls |grep -v handler_nostream.go |xargs rm -rf
|
||||
mv handler_nostream.go handler.go
|
||||
cd -
|
||||
fi
|
||||
|
||||
mapperVar=$(echo "${mapperName}" | sed -e "s/\b\(.\)/\\u\1/g")
|
||||
sed -i "s/Template/${mapperVar}/g" `grep Template -rl ${mapperPath}`
|
||||
sed -i "s/kubeedge\/${mapperVar}/kubeedge\/${mapperNameLowercase}/g" `grep "kubeedge\/${mapperVar}" -rl $mapperPath`
|
||||
|
||||
if [ $(uname) = "Darwin" ]; then
|
||||
sed -i "" "s/Template/${mapperVar}/g" `grep Template -rl ${mapperPath}`
|
||||
sed -i "" "s/kubeedge\/${mapperVar}/kubeedge\/${mapperNameLowercase}/g" `grep "kubeedge\/${mapperVar}" -rl $mapperPath`
|
||||
else
|
||||
sed -i "s/Template/${mapperVar}/g" `grep Template -rl ${mapperPath}`
|
||||
sed -i "s/kubeedge\/${mapperVar}/kubeedge\/${mapperNameLowercase}/g" `grep "kubeedge\/${mapperVar}" -rl $mapperPath`
|
||||
fi
|
||||
|
||||
cd ${mapperPath} && go mod tidy
|
||||
|
||||
|
|
|
@ -18,14 +18,7 @@ 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.
|
||||
// DeviceInstance is structure to store detailed information about the device in the mapper.
|
||||
type DeviceInstance struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
|
@ -35,9 +28,11 @@ type DeviceInstance struct {
|
|||
Model string `json:"model,omitempty"`
|
||||
Twins []Twin `json:"twins,omitempty"`
|
||||
Properties []DeviceProperty `json:"properties,omitempty"`
|
||||
Methods []DeviceMethod `json:"methods,omitempty"`
|
||||
Status DeviceStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// DeviceModel is structure to store deviceModel in deviceProfile.json in configmap.
|
||||
// DeviceModel is structure to store detailed information about the devicemodel in the mapper.
|
||||
type DeviceModel struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
|
@ -57,8 +52,7 @@ type ModelProperty struct {
|
|||
Unit string `json:"unit,omitempty"`
|
||||
}
|
||||
|
||||
// Protocol is structure to store protocol in deviceProfile.json in configmap.
|
||||
|
||||
// ProtocolConfig is structure to store protocol information in device.
|
||||
type ProtocolConfig struct {
|
||||
// Unique protocol name
|
||||
// Required.
|
||||
|
@ -69,7 +63,26 @@ type ProtocolConfig struct {
|
|||
ConfigData json.RawMessage `json:"configData,omitempty"`
|
||||
}
|
||||
|
||||
// DeviceProperty is structure to store propertyVisitor in deviceProfile.json in configmap.
|
||||
// DeviceMethod is structure to store method in device.
|
||||
type DeviceMethod struct {
|
||||
// Required: The device method name to be accessed. It must be unique.
|
||||
Name string `json:"name,omitempty"`
|
||||
// Define the description of device method.
|
||||
// +optional
|
||||
Description string `json:"description,omitempty"`
|
||||
// PropertyNames are list of device properties that device methods can control.
|
||||
// Required: A device method can control multiple device properties.
|
||||
PropertyNames []string `json:"propertyNames,omitempty"`
|
||||
}
|
||||
|
||||
// DeviceStatus is structure to store parameters for device status reporting.
|
||||
type DeviceStatus struct {
|
||||
// whether be reported to the cloud
|
||||
ReportToCloud bool `json:"reportToCloud,omitempty"`
|
||||
ReportCycle int64 `json:"reportCycle,omitempty"`
|
||||
}
|
||||
|
||||
// DeviceProperty is structure to store propertyVisitor in device.
|
||||
type DeviceProperty struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
PropertyName string `json:"propertyName,omitempty"`
|
||||
|
@ -91,6 +104,7 @@ type PushMethodConfig struct {
|
|||
DBMethod DBMethodConfig `json:"dbMethod,omitempty"`
|
||||
}
|
||||
|
||||
// DBMethodConfig is structure to store database config
|
||||
type DBMethodConfig struct {
|
||||
DBMethodName string `json:"dbMethodName"`
|
||||
DBConfig DBConfig `json:"dbConfig"`
|
||||
|
@ -101,6 +115,7 @@ type DBConfig struct {
|
|||
Influxdb2DataConfig json.RawMessage `json:"influxdb2DataConfig"`
|
||||
RedisClientConfig json.RawMessage `json:"redisClientConfig"`
|
||||
TDEngineClientConfig json.RawMessage `json:"TDEngineClientConfig"`
|
||||
MySQLClientConfig json.RawMessage `json:"mysqlClientConfig"`
|
||||
}
|
||||
|
||||
// Metadata is the metadata for data.
|
||||
|
|
|
@ -20,11 +20,12 @@ 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"
|
||||
DeviceStatusOK = "ok"
|
||||
DeviceStatusOnline = "online"
|
||||
DeviceStatusOffline = "offline"
|
||||
DeviceStatusDisCONN = "disconnected" /* Disconnected */
|
||||
DeviceStatusUnhealthy = "unhealthy" /* Unhealthy status from device */
|
||||
DeviceStatusUnknown = "unknown"
|
||||
)
|
||||
const (
|
||||
ProtocolCustomized = "customized-protocol"
|
||||
|
@ -33,6 +34,7 @@ const (
|
|||
const (
|
||||
PushMethodHTTP = "http"
|
||||
PushMethodMQTT = "mqtt"
|
||||
PushMethodOTEL = "otel"
|
||||
)
|
||||
|
||||
const DefaultCollectCycle = time.Second
|
||||
|
@ -42,3 +44,8 @@ const (
|
|||
DevInitModeRegister = "register"
|
||||
DevInitModeConfigmap = "configmap"
|
||||
)
|
||||
|
||||
const (
|
||||
SaveFrame = "saveFrame"
|
||||
SaveVideo = "saveVideo"
|
||||
)
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Copyright 2024 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
|
||||
|
||||
// DataMethod defined standard model for deviceMethod
|
||||
type DataMethod struct {
|
||||
Methods []Method
|
||||
}
|
||||
|
||||
type Method struct {
|
||||
Name string
|
||||
Path string
|
||||
Parameters []Parameter
|
||||
}
|
||||
|
||||
type Parameter struct {
|
||||
PropertyName string
|
||||
ValueType string
|
||||
}
|
|
@ -5,6 +5,7 @@ type DataModel struct {
|
|||
// TODO DataModel is standardized data, need add field
|
||||
DeviceName string
|
||||
PropertyName string
|
||||
Namespace string
|
||||
|
||||
Value string
|
||||
Type string
|
||||
|
@ -44,10 +45,11 @@ func WithTimeStamp(timeStamp int64) Option {
|
|||
}
|
||||
}
|
||||
|
||||
func NewDataModel(deviceName string, propertyName string, options ...Option) *DataModel {
|
||||
func NewDataModel(deviceName string, propertyName string, namespace string, options ...Option) *DataModel {
|
||||
dataModel := &DataModel{
|
||||
DeviceName: deviceName,
|
||||
PropertyName: propertyName,
|
||||
Namespace: namespace,
|
||||
TimeStamp: getTimestamp(),
|
||||
}
|
||||
for _, option := range options {
|
||||
|
|
|
@ -44,6 +44,7 @@ type Common struct {
|
|||
Protocol string `yaml:"protocol"`
|
||||
Address string `yaml:"address"`
|
||||
EdgeCoreSock string `yaml:"edgecore_sock"`
|
||||
HTTPPort string `yaml:"http_port"`
|
||||
}
|
||||
|
||||
// Parse the configuration file. If failed, return error.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,395 +0,0 @@
|
|||
/*
|
||||
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<string, google.protobuf.Any> 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;
|
||||
DBMethodRedis redis = 2;
|
||||
DBMethodTDEngine tdengine = 3;
|
||||
}
|
||||
|
||||
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<string, string> 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;
|
||||
}
|
||||
|
||||
message DBMethodRedis{
|
||||
// data config when push data to redis
|
||||
RedisClientConfig redisClientConfig = 1;
|
||||
}
|
||||
|
||||
message RedisClientConfig{
|
||||
// redis address
|
||||
string addr = 1;
|
||||
// number of redis db
|
||||
int32 db = 2;
|
||||
// number of redis poolsize
|
||||
int32 poolsize = 3;
|
||||
// number of redis minidleconns
|
||||
int32 minIdleConns =4;
|
||||
}
|
||||
|
||||
message DBMethodTDEngine{
|
||||
// data config when push data to tdengine
|
||||
TDEngineClientConfig tdEngineClientConfig = 1;
|
||||
}
|
||||
|
||||
message TDEngineClientConfig{
|
||||
// tdengine address,like 127.0.0.1:6041
|
||||
string addr = 1;
|
||||
// tdengine database name
|
||||
string dbname = 2;
|
||||
}
|
||||
|
||||
// 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<string, string> 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;
|
||||
}
|
|
@ -1,559 +0,0 @@
|
|||
//
|
||||
//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.20.3
|
||||
// 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",
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package global
|
||||
|
||||
import (
|
||||
dmiapi "github.com/kubeedge/kubeedge/pkg/apis/dmi/v1beta1"
|
||||
dmiapi "github.com/kubeedge/api/apis/dmi/v1beta1"
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
)
|
||||
|
||||
|
@ -21,6 +21,8 @@ type DevPanel interface {
|
|||
GetDevice(deviceID string) (interface{}, error)
|
||||
// RemoveDevice stop device and remove device
|
||||
RemoveDevice(deviceID string) error
|
||||
// WriteDevice write value to the device
|
||||
WriteDevice(deviceMethodName, deviceID, propertyName, data string) error
|
||||
// GetModel get model's info
|
||||
GetModel(modelID string) (common.DeviceModel, error)
|
||||
// UpdateModel update model in map only
|
||||
|
@ -29,6 +31,8 @@ type DevPanel interface {
|
|||
RemoveModel(modelID string)
|
||||
// GetTwinResult get device's property value and datatype
|
||||
GetTwinResult(deviceID string, twinName string) (string, string, error)
|
||||
// GetDeviceMethod get device's instance info
|
||||
GetDeviceMethod(deviceID string) (map[string][]string, map[string]string, error)
|
||||
}
|
||||
|
||||
// DataPanel defined push method, parse the push operation in CRD and execute it
|
||||
|
@ -50,8 +54,8 @@ type DataBaseClient interface {
|
|||
|
||||
AddData(data *common.DataModel)
|
||||
|
||||
GetDataByDeviceName(deviceName string) ([]*common.DataModel, error)
|
||||
GetPropertyDataByDeviceName(deviceName string, propertyData string) ([]*common.DataModel, error)
|
||||
GetDataByDeviceID(deviceID string) ([]*common.DataModel, error)
|
||||
GetPropertyDataByDeviceID(deviceID string, propertyData string) ([]*common.DataModel, error)
|
||||
GetDataByTimeRange(start int64, end int64) ([]*common.DataModel, error)
|
||||
|
||||
DeleteDataByTimeRange(start int64, end int64) ([]*common.DataModel, error)
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
dmiapi "github.com/kubeedge/kubeedge/pkg/apis/dmi/v1beta1"
|
||||
dmiapi "github.com/kubeedge/api/apis/dmi/v1beta1"
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
"github.com/kubeedge/mapper-framework/pkg/config"
|
||||
)
|
||||
|
@ -51,7 +51,7 @@ func RegisterMapper(withData bool) ([]*dmiapi.Device, []*dmiapi.DeviceModel, err
|
|||
ApiVersion: cfg.Common.APIVersion,
|
||||
Protocol: cfg.Common.Protocol,
|
||||
Address: []byte(cfg.GrpcServer.SocketPath),
|
||||
State: common.DEVSTOK,
|
||||
State: common.DeviceStatusOK,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
dmiapi "github.com/kubeedge/kubeedge/pkg/apis/dmi/v1beta1"
|
||||
dmiapi "github.com/kubeedge/api/apis/dmi/v1beta1"
|
||||
"github.com/kubeedge/mapper-framework/pkg/config"
|
||||
)
|
||||
|
||||
|
@ -44,3 +44,35 @@ func ReportDeviceStatus(request *dmiapi.ReportDeviceStatusRequest) error {
|
|||
_, err = c.ReportDeviceStatus(ctx, request)
|
||||
return err
|
||||
}
|
||||
|
||||
func ReportDeviceStates(request *dmiapi.ReportDeviceStatesRequest) error {
|
||||
cfg := config.Cfg()
|
||||
|
||||
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.ReportDeviceStates(ctx, request)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/avast/retry-go"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
dmiapi "github.com/kubeedge/kubeedge/pkg/apis/dmi/v1beta1"
|
||||
dmiapi "github.com/kubeedge/api/apis/dmi/v1beta1"
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
"github.com/kubeedge/mapper-framework/pkg/util/parse"
|
||||
)
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"google.golang.org/grpc/reflection"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
dmiapi "github.com/kubeedge/kubeedge/pkg/apis/dmi/v1beta1"
|
||||
dmiapi "github.com/kubeedge/api/apis/dmi/v1beta1"
|
||||
"github.com/kubeedge/mapper-framework/pkg/global"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ import (
|
|||
"reflect"
|
||||
"strings"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
"github.com/kubeedge/mapper-framework/pkg/util/parse"
|
||||
)
|
||||
|
@ -33,6 +35,7 @@ func (rs *RestServer) DeviceRead(writer http.ResponseWriter, request *http.Reque
|
|||
Data: common.NewDataModel(
|
||||
deviceName,
|
||||
propertyName,
|
||||
deviceNamespace,
|
||||
common.WithValue(res),
|
||||
common.WithType(dataType),
|
||||
),
|
||||
|
@ -41,6 +44,85 @@ func (rs *RestServer) DeviceRead(writer http.ResponseWriter, request *http.Reque
|
|||
}
|
||||
}
|
||||
|
||||
// GetDeviceMethod get all methods of the specified device
|
||||
func (rs *RestServer) GetDeviceMethod(writer http.ResponseWriter, request *http.Request) {
|
||||
// Parse device name, namespace and other information from api request
|
||||
urlItem := strings.Split(request.URL.Path, "/")
|
||||
deviceNamespace := urlItem[len(urlItem)-2]
|
||||
deviceName := urlItem[len(urlItem)-1]
|
||||
deviceID := parse.GetResourceID(deviceNamespace, deviceName)
|
||||
klog.V(2).Infof("Starting get all method of device %s in namespace %s.", deviceName, deviceNamespace)
|
||||
|
||||
// Get all methods of the device from the devplane
|
||||
deviceMethodMap, propertyTypeMap, err := rs.devPanel.GetDeviceMethod(deviceID)
|
||||
if err != nil {
|
||||
http.Error(writer, fmt.Sprintf("Get device method error: %v", err), http.StatusInternalServerError)
|
||||
} else {
|
||||
deviceMethod, err := rs.ParseMethodParameter(deviceMethodMap, propertyTypeMap, deviceName, deviceNamespace)
|
||||
if err != nil {
|
||||
http.Error(writer, fmt.Sprintf("Get device method error: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
response := &DeviceMethodReadResponse{
|
||||
BaseResponse: NewBaseResponse(http.StatusOK),
|
||||
Data: deviceMethod,
|
||||
}
|
||||
rs.sendResponse(writer, request, response, http.StatusOK)
|
||||
klog.V(2).Infof("Successfully obtained all methods of device %s", deviceName)
|
||||
}
|
||||
}
|
||||
|
||||
// ParseMethodParameter add calling method, propertyName and property datatype to devicemethod parameter
|
||||
func (rs *RestServer) ParseMethodParameter(deviceMethodMap map[string][]string, propertyTypeMap map[string]string, deviceName string, deviceNamespace string) (*common.DataMethod, error) {
|
||||
deviceMethod := common.DataMethod{
|
||||
Methods: make([]common.Method, 0),
|
||||
}
|
||||
for methodName, propertyList := range deviceMethodMap {
|
||||
method := common.Method{}
|
||||
method.Name = methodName
|
||||
method.Path = APIDeviceMethodRoute + "/" + deviceNamespace + "/" + deviceName + "/" + methodName + "/{propertyName}/{data}"
|
||||
parameter := make([]common.Parameter, 0)
|
||||
// get datatype of device property
|
||||
for _, propertyName := range propertyList {
|
||||
valueType, ok := propertyTypeMap[propertyName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unable to find device property %s defined in device method", propertyName)
|
||||
}
|
||||
parameter = append(parameter, common.Parameter{
|
||||
PropertyName: propertyName,
|
||||
ValueType: valueType,
|
||||
})
|
||||
}
|
||||
method.Parameters = parameter
|
||||
deviceMethod.Methods = append(deviceMethod.Methods, method)
|
||||
}
|
||||
return &deviceMethod, nil
|
||||
}
|
||||
|
||||
// DeviceWrite receive device method call request and complete data writing
|
||||
func (rs *RestServer) DeviceWrite(writer http.ResponseWriter, request *http.Request) {
|
||||
// Parse device name, namespace and other information from api request
|
||||
urlItem := strings.Split(request.URL.Path, "/")
|
||||
deviceNamespace := urlItem[len(urlItem)-5]
|
||||
deviceName := urlItem[len(urlItem)-4]
|
||||
deviceMethodName := urlItem[len(urlItem)-3]
|
||||
propertyName := urlItem[len(urlItem)-2]
|
||||
data := urlItem[len(urlItem)-1]
|
||||
|
||||
// Call device write command
|
||||
deviceID := parse.GetResourceID(deviceNamespace, deviceName)
|
||||
err := rs.devPanel.WriteDevice(deviceMethodName, deviceID, propertyName, data)
|
||||
if err != nil {
|
||||
http.Error(writer, fmt.Sprintf("Write device data error: %v", err), http.StatusInternalServerError)
|
||||
} else {
|
||||
response := &DeviceWriteResponse{
|
||||
BaseResponse: NewBaseResponse(http.StatusOK),
|
||||
Message: fmt.Sprintf("Write data %s to device %s successfully.", data, deviceID),
|
||||
}
|
||||
rs.sendResponse(writer, request, response, http.StatusOK)
|
||||
}
|
||||
}
|
||||
|
||||
func (rs *RestServer) MetaGetModel(writer http.ResponseWriter, request *http.Request) {
|
||||
urlItem := strings.Split(request.URL.Path, "/")
|
||||
deviceNamespace := urlItem[len(urlItem)-2]
|
||||
|
|
|
@ -27,11 +27,21 @@ type PingResponse struct {
|
|||
Message string
|
||||
}
|
||||
|
||||
type DeviceWriteResponse struct {
|
||||
*BaseResponse
|
||||
Message string
|
||||
}
|
||||
|
||||
type DeviceReadResponse struct {
|
||||
*BaseResponse
|
||||
Data *common.DataModel
|
||||
}
|
||||
|
||||
type DeviceMethodReadResponse struct {
|
||||
*BaseResponse
|
||||
Data *common.DataMethod
|
||||
}
|
||||
|
||||
type MetaGetModelResponse struct {
|
||||
*BaseResponse
|
||||
*common.DeviceModel
|
||||
|
|
|
@ -12,8 +12,14 @@ const (
|
|||
|
||||
// APIDeviceRoute to build device RESTful API
|
||||
APIDeviceRoute = APIBase + "/device"
|
||||
// APIDeviceMethodRoute to build deviceMethod RESTful API
|
||||
APIDeviceMethodRoute = APIBase + "/devicemethod"
|
||||
// APIGetDeviceMethodRoute to get all deviceMethod of the device
|
||||
APIGetDeviceMethodRoute = APIDeviceMethodRoute + "/" + DeviceNamespace + "/" + DeviceName
|
||||
// APIDeviceReadRoute API that read device's property
|
||||
APIDeviceReadRoute = APIDeviceRoute + "/" + DeviceNamespace + "/" + DeviceName + "/" + PropertyName
|
||||
// APIDeviceWriteRoute API that read device's property
|
||||
APIDeviceWriteRoute = APIDeviceMethodRoute + "/" + DeviceNamespace + "/" + DeviceName + "/" + DeviceMethodName + "/" + PropertyName + "/" + Data
|
||||
|
||||
// APIMetaRoute to build meta RESTful API
|
||||
APIMetaRoute = APIBase + "/meta"
|
||||
|
@ -30,6 +36,10 @@ const (
|
|||
const (
|
||||
// DeviceName pattern for deviceName
|
||||
DeviceName = "{name}"
|
||||
// DeviceMethodName pattern for device method Name
|
||||
DeviceMethodName = "{methodname}"
|
||||
// Data pattern for device write data
|
||||
Data = "{data}"
|
||||
// DeviceNamespace pattern for deviceNamespace
|
||||
DeviceNamespace = "{namespace}"
|
||||
// PropertyName pattern for property
|
||||
|
|
|
@ -6,9 +6,15 @@ func (rs *RestServer) InitRouter() {
|
|||
// Common
|
||||
rs.Router.HandleFunc(APIPing, rs.Ping).Methods(http.MethodGet)
|
||||
|
||||
// Device
|
||||
// DeviceRead
|
||||
rs.Router.HandleFunc(APIDeviceReadRoute, rs.DeviceRead).Methods(http.MethodGet)
|
||||
|
||||
// GetDeviceMethod
|
||||
rs.Router.HandleFunc(APIGetDeviceMethodRoute, rs.GetDeviceMethod).Methods(http.MethodGet)
|
||||
|
||||
// DeviceWrite
|
||||
rs.Router.HandleFunc(APIDeviceWriteRoute, rs.DeviceWrite).Methods(http.MethodGet)
|
||||
|
||||
// Meta
|
||||
rs.Router.HandleFunc(APIMetaGetModelRoute, rs.MetaGetModel).Methods(http.MethodGet)
|
||||
|
||||
|
|
|
@ -30,10 +30,14 @@ type RestServer struct {
|
|||
|
||||
type Option func(server *RestServer)
|
||||
|
||||
func NewRestServer(devPanel global.DevPanel, options ...Option) *RestServer {
|
||||
func NewRestServer(devPanel global.DevPanel, httpPort string, options ...Option) *RestServer {
|
||||
if httpPort == "" {
|
||||
httpPort = "7777"
|
||||
}
|
||||
|
||||
rest := &RestServer{
|
||||
IP: "0.0.0.0",
|
||||
Port: "7777",
|
||||
Port: httpPort,
|
||||
Router: mux.NewRouter(),
|
||||
WriteTimeout: 10 * time.Second,
|
||||
ReadTimeout: 10 * time.Second,
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
dmiapi "github.com/kubeedge/kubeedge/pkg/apis/dmi/v1beta1"
|
||||
dmiapi "github.com/kubeedge/api/apis/dmi/v1beta1"
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
)
|
||||
|
||||
|
@ -106,17 +106,17 @@ func buildPropertiesFromGrpc(device *dmiapi.Device) []common.DeviceProperty {
|
|||
var dbconfig common.DBConfig
|
||||
var pushMethod []byte
|
||||
var pushMethodName string
|
||||
if pptv.PushMethod != nil && pptv.PushMethod.DBMethod != nil {
|
||||
if pptv.PushMethod != nil && pptv.PushMethod.DbMethod != nil {
|
||||
//parse dbmethod filed
|
||||
switch {
|
||||
case pptv.PushMethod.DBMethod.Influxdb2 != nil:
|
||||
case pptv.PushMethod.DbMethod.Influxdb2 != nil:
|
||||
dbMethodName = "influx"
|
||||
clientconfig, err := json.Marshal(pptv.PushMethod.DBMethod.Influxdb2.Influxdb2ClientConfig)
|
||||
clientconfig, err := json.Marshal(pptv.PushMethod.DbMethod.Influxdb2.Influxdb2ClientConfig)
|
||||
if err != nil {
|
||||
klog.Errorf("influx client config err: %+v", err)
|
||||
return nil
|
||||
}
|
||||
dataconfig, err := json.Marshal(pptv.PushMethod.DBMethod.Influxdb2.Influxdb2DataConfig)
|
||||
dataconfig, err := json.Marshal(pptv.PushMethod.DbMethod.Influxdb2.Influxdb2DataConfig)
|
||||
if err != nil {
|
||||
klog.Errorf("influx data config err: %+v", err)
|
||||
return nil
|
||||
|
@ -125,9 +125,9 @@ func buildPropertiesFromGrpc(device *dmiapi.Device) []common.DeviceProperty {
|
|||
Influxdb2ClientConfig: clientconfig,
|
||||
Influxdb2DataConfig: dataconfig,
|
||||
}
|
||||
case pptv.PushMethod.DBMethod.Redis != nil:
|
||||
case pptv.PushMethod.DbMethod.Redis != nil:
|
||||
dbMethodName = "redis"
|
||||
clientConfig, err := json.Marshal(pptv.PushMethod.DBMethod.Redis.RedisClientConfig)
|
||||
clientConfig, err := json.Marshal(pptv.PushMethod.DbMethod.Redis.RedisClientConfig)
|
||||
if err != nil {
|
||||
klog.Errorf("redis config err: %+v", err)
|
||||
return nil
|
||||
|
@ -135,9 +135,9 @@ func buildPropertiesFromGrpc(device *dmiapi.Device) []common.DeviceProperty {
|
|||
dbconfig = common.DBConfig{
|
||||
RedisClientConfig: clientConfig,
|
||||
}
|
||||
case pptv.PushMethod.DBMethod.Tdengine != nil:
|
||||
case pptv.PushMethod.DbMethod.Tdengine != nil:
|
||||
dbMethodName = "tdengine"
|
||||
clientConfig, err := json.Marshal(pptv.PushMethod.DBMethod.Tdengine.TdEngineClientConfig)
|
||||
clientConfig, err := json.Marshal(pptv.PushMethod.DbMethod.Tdengine.TdEngineClientConfig)
|
||||
if err != nil {
|
||||
klog.Errorf("tdengine config err: %+v", err)
|
||||
return nil
|
||||
|
@ -145,6 +145,16 @@ func buildPropertiesFromGrpc(device *dmiapi.Device) []common.DeviceProperty {
|
|||
dbconfig = common.DBConfig{
|
||||
TDEngineClientConfig: clientConfig,
|
||||
}
|
||||
case pptv.PushMethod.DbMethod.Mysql != nil:
|
||||
dbMethodName = "mysql"
|
||||
clientConfig, err := json.Marshal(pptv.PushMethod.DbMethod.Mysql.MysqlClientConfig)
|
||||
if err != nil {
|
||||
klog.Errorf("mysql config err: %+v", err)
|
||||
return nil
|
||||
}
|
||||
dbconfig = common.DBConfig{
|
||||
MySQLClientConfig: clientConfig,
|
||||
}
|
||||
default:
|
||||
klog.Errorf("get DBMethod err: Unsupported database type")
|
||||
}
|
||||
|
@ -166,6 +176,13 @@ func buildPropertiesFromGrpc(device *dmiapi.Device) []common.DeviceProperty {
|
|||
klog.Errorf("err: %+v", err)
|
||||
return nil
|
||||
}
|
||||
case pptv.PushMethod.Otel != nil:
|
||||
dbMethodName = common.PushMethodOTEL
|
||||
pushMethod, err = json.Marshal(pptv.PushMethod.Otel)
|
||||
if err != nil {
|
||||
klog.Errorf("err: %+v", err)
|
||||
return nil
|
||||
}
|
||||
default:
|
||||
klog.Errorf("get PushMethod err: Unsupported pushmethod type")
|
||||
}
|
||||
|
@ -192,6 +209,25 @@ func buildPropertiesFromGrpc(device *dmiapi.Device) []common.DeviceProperty {
|
|||
}
|
||||
res = append(res, cur)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// buildMethodsFromGrpc parse device method from grpc
|
||||
func buildMethodsFromGrpc(device *dmiapi.Device) []common.DeviceMethod {
|
||||
if len(device.Spec.Methods) == 0 {
|
||||
return nil
|
||||
}
|
||||
res := make([]common.DeviceMethod, 0, len(device.Spec.Properties))
|
||||
klog.V(3).Info("Start converting devicemethod information from grpc")
|
||||
for _, method := range device.Spec.Methods {
|
||||
// Convert device method field
|
||||
cur := common.DeviceMethod{
|
||||
Name: method.GetName(),
|
||||
Description: method.GetDescription(),
|
||||
PropertyNames: method.GetPropertyNames(),
|
||||
}
|
||||
res = append(res, cur)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
@ -235,6 +271,11 @@ func GetDeviceFromGrpc(device *dmiapi.Device, commonModel *common.DeviceModel) (
|
|||
Model: device.GetSpec().GetDeviceModelReference(),
|
||||
Twins: buildTwinsFromGrpc(device),
|
||||
Properties: buildPropertiesFromGrpc(device),
|
||||
Methods: buildMethodsFromGrpc(device),
|
||||
Status: common.DeviceStatus{
|
||||
ReportToCloud: device.Status.GetReportToCloud(),
|
||||
ReportCycle: device.Status.GetReportCycle(),
|
||||
},
|
||||
}
|
||||
// copy Properties to twin
|
||||
propertiesMap := make(map[string]common.DeviceProperty)
|
||||
|
|
|
@ -3,7 +3,7 @@ package parse
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
dmiapi "github.com/kubeedge/kubeedge/pkg/apis/dmi/v1beta1"
|
||||
dmiapi "github.com/kubeedge/api/apis/dmi/v1beta1"
|
||||
"github.com/kubeedge/mapper-framework/pkg/common"
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue