Compare commits

...

30 Commits

Author SHA1 Message Date
Elias Wang bd14c0473a
Merge pull request #29 from wbc6080/sync-6.28
Synchronize changes from the kubeedge/staging directory on 2025.6.28
2025-06-28 18:31:14 +08:00
wbc6080 967ace7fb7 Synchronize changes from the kubeedge/staging directory on 2025.6.28
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2025-06-28 18:28:08 +08:00
Elias Wang 620cd01fcc
Sync Mapper-Framework from KubeEdge repo based on v1.20.0
Fix mod version in mapper about v1.20.0
2025-02-11 15:00:21 +08:00
wbc6080 898b5edcb1 Fix mod version in mapper about v1.20.0
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2025-02-11 14:57:52 +08:00
Elias Wang 669fd9b7a5
Merge pull request #20 from wbc6080/sync-2.10
Synchronize changes from the kubeedge/staging directory on 2025.2.10
2025-02-10 20:50:43 +08:00
wbc6080 a408ea0341 Synchronize changes from the kubeedge/staging directory on 2025.2.10
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2025-02-10 20:48:23 +08:00
Elias Wang 96009b7561
Merge pull request #19 from wbc6080/sync-12.16
Synchronize changes from the kubeedge/staging directory on 2024.12.16
2024-12-16 10:50:50 +08:00
wbc6080 72cfcb4890 sync in 2024.12.16
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2024-12-16 10:49:09 +08:00
Elias Wang 6d21d341a2
Merge pull request #18 from wbc6080/fix-vendor-version
Fix mod version in mapper
2024-11-06 17:12:57 +08:00
wbc6080 8cf4f9da2a fix vendor version
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2024-11-06 17:11:19 +08:00
Elias Wang 77b73b42c2
Merge pull request #17 from wbc6080/sync-10.29
Synchronize changes from the kubeedge/staging directory on 2024.10.29
2024-10-29 19:43:41 +08:00
wbc6080 be7967f9e3 sync in 2024.10.29
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2024-10-29 19:39:44 +08:00
Elias Wang 740af01b0f
Merge pull request #16 from wbc6080/fix-bug-release1.18
Fix mod version in mapper
2024-07-27 15:55:52 +08:00
wbc6080 55fb8e110a fix mod version in mapper
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2024-07-27 15:34:49 +08:00
KubeEdge Bot 23ae39c118
Merge pull request #15 from wbc6080/sync-7.27
Synchronize changes from the kubeedge/staging directory on 2024.7.27
2024-07-27 15:19:08 +08:00
wbc6080 95a475dfa1 sync-7.27
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2024-07-27 15:06:20 +08:00
wbc6080 1a78cfc501
Merge pull request #14 from wbc6080/sync-6.20
Synchronize changes from the kubeedge/staging directory on 2024.6.15
2024-06-24 09:32:13 +08:00
wbc6080 7389bfd808 sync-6.20
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2024-06-20 20:04:45 +08:00
wbc6080 0533327f84
Merge pull request #13 from wbc6080/sync-6.15
Synchronize changes from the kubeedge/staging directory on 2024.6.15
2024-06-15 11:25:03 +08:00
wbc6080 186b50d113 sync-6.15
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2024-06-15 11:00:18 +08:00
wbc6080 e52ebca353
Merge pull request #12 from wbc6080/sync-5.16
Synchronize changes from the kubeedge/staging directory on 2024.5.16
2024-05-16 11:41:55 +08:00
wbc6080 d11f2765ae sync-5.16
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2024-05-16 11:38:34 +08:00
wbc6080 fdf93b0eb7
Merge pull request #11 from wbc6080/fix-go-vendor
Replace dependency versions during development
2024-04-24 16:43:52 +08:00
wbc6080 83b7dc26cb fix-go-mod
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2024-04-24 16:41:52 +08:00
wbc6080 62ddff0c5c
Merge pull request #10 from wbc6080/sync-4.24
Synchronize changes from the kubeedge/staging directory on 2024.4.24
2024-04-24 09:58:40 +08:00
wbc6080 d2c12b5f72 sync-4.24
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2024-04-24 09:54:54 +08:00
wbc6080 3faa5198ae
Merge pull request #9 from wbc6080/sync-4.23
Synchronize changes from the kubeedge/staging directory on 2024.4.23
2024-04-24 09:20:20 +08:00
wbc6080 459dd4c80c sync in 2024.4.23
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2024-04-23 21:28:32 +08:00
wbc6080 fcae29c635
Merge pull request #8 from wbc6080/sync-in-2.20
Synchronize changes from the kubeedge/staging directory on 2024.2.20
2024-03-26 19:19:47 +08:00
wbc6080 26e3ec2e41 sync the change from kubeedge in 2.20
Signed-off-by: wbc6080 <wangbincheng4@huawei.com>
2024-02-20 14:57:59 +08:00
47 changed files with 1635 additions and 4744 deletions

3
CODE_OF_CONDUCT.md Normal file
View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}
}
}()
}

View File

@ -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")
}

View File

@ -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
}

View File

@ -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")
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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.")
}

View File

@ -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))
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}
}
}

View File

@ -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"

View File

@ -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
}

View File

@ -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
)

View File

@ -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
View File

@ -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
View File

@ -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=

View File

@ -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

View File

@ -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.

View File

@ -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"
)

33
pkg/common/datamethod.go Normal file
View File

@ -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
}

View File

@ -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 {

View File

@ -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

View File

@ -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;
}

View File

@ -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",
}

View File

@ -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)

View File

@ -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 {

View File

@ -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 contextset timeout
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
_, err = c.ReportDeviceStates(ctx, request)
return err
}

View File

@ -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"
)

View File

@ -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"
)

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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,

View File

@ -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)

View File

@ -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"
)