Last Updated on : 2024-06-21 07:02:00download
This topic describes how to use the tuya-edge-driver-sdk-go SDK provided by Tuya to develop drivers and serve edge devices. Before the driver development, we recommend that you deploy Tuya Edge Gateway (TEdge).
The tuya-edge-driver-sdk-go
SDK is used to develop southbound device services that are connected to TEdge. The SDK supports the following features:
You can connect to the locally deployed TEdge node at http://your-edge-ip:3000/driver/lib and download the driver configuration template.
The following code block shows the configuration template:
// config.json
{
"deviceServer": {
"driver": {
}
},
// Other configurations.
}
You can define specific configurations in the driver
field in the key-value format. For example, to develop a device service based on Message Queuing Telemetry Transport (MQTT), you can configure the IP address, port, and quality of service (QoS) of the service.
The following sample code shows the configurations:
// config.json
{
"deviceServer": {
"driver": {
"MQTTBrokerIP": "0.0.0.0",
"MQTTBrokerPort": "1883"
}
},
// Other configurations.
}
When the service is running, the application can get the driver configurations by using the func DriverConfigs() map[string]string
method provided by the SDK.
You must use device-service-template
that is provided with the SDK to develop a required driver service. The following figure shows the project directories.
The driver service code can be developed in the internal/driver
directory. At the end of the development, set Dockerfile
and Makefile
based on actual conditions. Then, run make build
to package the driver service into a Docker image.
In the main
function, call the function func Bootstrap(serviceName string, serviceVersion string, driver interface{})
to initialize the SDK. The driver
field includes the ProtocolDriver
interface to be implemented in the SDK.
// main.go
package main
import (
"device-service-template/internal/driver"
"github.com/tuya/tuya-edge-driver-sdk-go"
"github.com/tuya/tuya-edge-driver-sdk-go/pkg/startup"
)
const (
serviceName string = "device-service-template"
)
func main() {
sd := driver.SimpleDriver{}
startup.Bootstrap(serviceName, device.Version, &sd)
}
You must implement the ProtocolDriver
interface to run multiple tasks. For example, the interfaces can be used to initialize the driver service, send commands to read from and write to devices, and add, modify, or delete device notifications. The following code block shows the definition of the interface:
type ProtocolDriver interface {
Initialize(lc logger.LoggingClient, asyncCh chan<- *AsyncValues, deviceCh chan<- []DiscoveredDevice) error
HandleReadCommands(deviceName string, protocols map[string]models.ProtocolProperties, reqs []CommandRequest) ([]*CommandValue, error)
HandleWriteCommands(deviceName string, protocols map[string]models.ProtocolProperties, reqs []CommandRequest, params []*CommandValue) error
Stop(force bool) error
AddDevice(deviceName string, protocols map[string]models.ProtocolProperties, adminState models.AdminState) error
UpdateDevice(deviceName string, protocols map[string]models.ProtocolProperties, adminState models.AdminState) error
RemoveDevice(deviceName string, protocols map[string]models.ProtocolProperties) error
}
The following functions are included:
Initialize
: initializes the driver. For example, the MQTT broker or HTTP server for connections to devices is initialized.
Function:
func (d *SimpleDriver) Initialize(lc logger.LoggingClient, asyncCh chan<- *AsyncValues, deviceCh chan<- []DiscoveredDevice) error`
Sample code for Go:
func (d *SimpleDriver) Initialize(lc logger.LoggingClient, asyncCh chan<- *dsModels.AsyncValues, deviceCh chan<- []dsModels.DiscoveredDevice) error {
d.lc = lc
d.asyncCh = asyncCh
// code here
// Initializes the service code.
return nil
}
HandleReadCommands
: reads device data.
Function:
func (d *SimpleDriver) HandleReadCommands(deviceName string, protocols map[string]models.ProtocolProperties, reqs []CommandRequest) ([]*CommandValue, error)
Sample code for Go:
// This function is used to send read commands to the service code. You must call this function to read device data.
func (d *SimpleDriver) HandleReadCommands(deviceName string, protocols map[string]models.ProtocolProperties, reqs []dsModels.CommandRequest) (res []*dsModels.CommandValue, err error) {
rd := d.retrieveRandomDevice(deviceName)
res = make([]*dsModels.CommandValue, len(reqs))
now := time.Now().UnixNano()
for i, req := range reqs {
t := req.Type
v, err := rd.value(t)
if err != nil {
return nil, err
}
var cv *dsModels.CommandValue
switch t {
case contracts.ValueTypeInt8:
cv, _ = dsModels.NewInt8Value(req.DeviceResourceName, now, int8(v))
case contracts.ValueTypeInt16:
cv, _ = dsModels.NewInt16Value(req.DeviceResourceName, now, int16(v))
case contracts.ValueTypeInt32:
cv, _ = dsModels.NewInt32Value(req.DeviceResourceName, now, int32(v))
}
res[i] = cv
}
return res, nil
}
Note:
- The value of the
protocols
request parameter can vary based on the protocol that is selected when a sub-device is added. Example:
In this topic, a standard Modbus device is added. The Modbus driver service initiates connections to the Modbus device. To add the device, you must provide the required parameters of the device. For other types of devices, whether to provide the device parameters depends on specific protocols.- After a control command is sent to the driver service, device parameters are stored to
protocols
when the SDK calls the current function. The driver uses these parameters to connect to the device and send the control command.
reqs
: the request to send a device control command.commandRequest.DeviceResourceName
: the name of the device resource that is specified in the control request. This is also the DP that is defined in a things data model.commandRequest.Type
: the type of device resource to be controlled.commandRequest.Attributes
: specific attributes of the device resource. For example, the following attributes can be specified for a Modbus device:
To read the DP 15 for the Modbus device, the read DP code is set to03
, the starting address is set to0
, and the data length to be read is 1 byte. For more information, see the standard Modbus protocol.- The
contracts
package includes the data types that are supported by the SDK. You can call the functions in themodels
package of the SDK to convert data types.
HandleWriteCommands
: writes to the device.
func (d *SimpleDriver) HandleWriteCommands(deviceName string, protocols map[string]models.ProtocolProperties, reqs []CommandRequest, params []*CommandValue) error
params
: the parameters of a write command to specify the data to be written.
params
: Before the data is written to the device, the data type must be converted. You can call the functions in the models
package of the SDK to convert data types.
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback