From 6cf65c55f61712b84cc0283a19c58eb27b62e2fc Mon Sep 17 00:00:00 2001 From: Melody Date: Wed, 1 Nov 2023 23:41:39 +0800 Subject: [PATCH] refactor: Device Service refactor (#1263) * refactor: Device Service refactor - Phase 1 Signed-off-by: melody --- docs_src/api/devices/Ch-APIDeviceSDK.md | 2 +- docs_src/general/ServiceConfiguration.md | 2 +- .../Ch-GettingStartedCDevelopers.md | 2 +- .../Ch-GettingStartedGoDevelopers.md | 2 +- .../getting-started/Ch-GettingStartedSDK.md | 27 -- docs_src/getting-started/index.md | 4 +- docs_src/getting-started/tools/Ch-GUI.md | 2 +- docs_src/microservices/device/ApiReference.md | 9 + .../microservices/device/Ch-DeviceServices.md | 286 ---------------- .../microservices/device/Configuration.md | 168 ++++++++++ .../microservices/device/DeviceService.md | 53 +++ .../microservices/device/GettingStarted.md | 28 ++ docs_src/microservices/device/V3Migration.md | 6 +- .../device/details/CommandLine.md | 15 + .../device/details/DeviceDiscovery.md | 29 ++ .../device/details/EnvironmentVariables.md | 11 + .../device/details/SeedingSecrets.md | 7 + .../device/details/ServiceMetrics.md | 15 + .../sdk/{Ch-DeviceSDK.md => Purpose.md} | 26 +- .../microservices/device/sdk/SourceCode.md | 11 + .../CDeviceSDK/CDeviceSDKAPI.md} | 10 +- .../CDeviceSDK/Dependencies/CUtilities.md} | 6 +- .../sdk/api/GoDeviceSDK/GoDeviceSDKAPI.md | 310 ++++++++++++++++++ .../device/sdk/details/CustomConfiguration.md | 48 +++ .../device/sdk/details/CustomRestApis.md | 24 ++ .../sdk/details/CustomServiceMetrics.md | 71 ++++ .../device/sdk/details/Secrets.md | 44 +++ .../EdgeX_GettingStartedGoModInit.png | Bin .../EdgeX_GettingStartedLocateDriver.png | Bin .../EdgeX_GettingStartedSDKBuild.png | Bin .../EdgeX_GettingStartedSDKClone.png | Bin .../EdgeX_GettingStartedSDKCloneC.png | Bin .../EdgeX_GettingStartedSDKCompileC.png | Bin .../EdgeX_GettingStartedSDKCopyFiles.png | Bin .../EdgeX_GettingStartedSDKCopyFilesC.png | Bin .../EdgeX_GettingStartedSDKGoAddImports.png | Bin .../EdgeX_GettingStartedSDKGoGenNumber.png | Bin .../EdgeX_GettingStartedSDKGoMod.png | Bin .../EdgeX_GettingStartedSDKReplaceImports.png | Bin ...eX_SampleDeviceProfile_DeviceResources.png | Bin ...X_SampleDeviceProfile_DeviceResourcesC.png | Bin .../GettingStartedSDK-C.md} | 13 +- .../GettingStartedSDK-Go.md} | 86 +---- .../configuration.yaml | 0 .../random-generator-devices.json | 0 .../random-generator-devices.yaml | 0 .../random-generator.yaml | 0 .../supplementary-info/discovery.md | 2 +- .../Ch-WalkthroughDeviceService.md | 2 +- .../walk-through/Ch-WalkthroughProvision.md | 2 +- .../walk-through/Ch-WalkthroughUseCase.md | 2 +- mkdocs.yml | 38 ++- 52 files changed, 927 insertions(+), 436 deletions(-) delete mode 100644 docs_src/getting-started/Ch-GettingStartedSDK.md create mode 100644 docs_src/microservices/device/ApiReference.md delete mode 100644 docs_src/microservices/device/Ch-DeviceServices.md create mode 100644 docs_src/microservices/device/Configuration.md create mode 100644 docs_src/microservices/device/DeviceService.md create mode 100644 docs_src/microservices/device/GettingStarted.md create mode 100644 docs_src/microservices/device/details/CommandLine.md create mode 100644 docs_src/microservices/device/details/DeviceDiscovery.md create mode 100644 docs_src/microservices/device/details/EnvironmentVariables.md create mode 100644 docs_src/microservices/device/details/SeedingSecrets.md create mode 100644 docs_src/microservices/device/details/ServiceMetrics.md rename docs_src/microservices/device/sdk/{Ch-DeviceSDK.md => Purpose.md} (65%) create mode 100644 docs_src/microservices/device/sdk/SourceCode.md rename docs_src/microservices/device/sdk/{Ch-Ref-SDK-C.md => api/CDeviceSDK/CDeviceSDKAPI.md} (98%) rename docs_src/microservices/device/sdk/{Ch-Using-iot-data-t.md => api/CDeviceSDK/Dependencies/CUtilities.md} (98%) create mode 100644 docs_src/microservices/device/sdk/api/GoDeviceSDK/GoDeviceSDKAPI.md create mode 100644 docs_src/microservices/device/sdk/details/CustomConfiguration.md create mode 100644 docs_src/microservices/device/sdk/details/CustomRestApis.md create mode 100644 docs_src/microservices/device/sdk/details/CustomServiceMetrics.md create mode 100644 docs_src/microservices/device/sdk/details/Secrets.md rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_GettingStartedGoModInit.png (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_GettingStartedLocateDriver.png (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_GettingStartedSDKBuild.png (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_GettingStartedSDKClone.png (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_GettingStartedSDKCloneC.png (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_GettingStartedSDKCompileC.png (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_GettingStartedSDKCopyFiles.png (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_GettingStartedSDKCopyFilesC.png (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_GettingStartedSDKGoAddImports.png (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_GettingStartedSDKGoGenNumber.png (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_GettingStartedSDKGoMod.png (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_GettingStartedSDKReplaceImports.png (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_SampleDeviceProfile_DeviceResources.png (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/EdgeX_SampleDeviceProfile_DeviceResourcesC.png (100%) rename docs_src/{getting-started/Ch-GettingStartedSDK-C.md => microservices/device/sdk/devicesdk-getting-started/GettingStartedSDK-C.md} (95%) rename docs_src/{getting-started/Ch-GettingStartedSDK-Go.md => microservices/device/sdk/devicesdk-getting-started/GettingStartedSDK-Go.md} (77%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/configuration.yaml (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/random-generator-devices.json (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/random-generator-devices.yaml (100%) rename docs_src/{getting-started => microservices/device/sdk/devicesdk-getting-started}/random-generator.yaml (100%) diff --git a/docs_src/api/devices/Ch-APIDeviceSDK.md b/docs_src/api/devices/Ch-APIDeviceSDK.md index dce197d50..ef45b4ce1 100644 --- a/docs_src/api/devices/Ch-APIDeviceSDK.md +++ b/docs_src/api/devices/Ch-APIDeviceSDK.md @@ -1,6 +1,6 @@ # Device Services -The EdgeX Foundry Device Service Software Development Kit (SDK) takes the Developer through the step-by-step process to create an EdgeX Foundry Device Service microservice. See [Device Service SDK](../../microservices/device/sdk/Ch-DeviceSDK.md) for more details on this SDK. +The EdgeX Foundry Device Service Software Development Kit (SDK) takes the Developer through the step-by-step process to create an EdgeX Foundry Device Service microservice. See [Device Service SDK](../../microservices/device/sdk/Purpose.md) for more details on this SDK. The Device Service SDK provides a RESTful API that all Device Services inherit from the SDK. diff --git a/docs_src/general/ServiceConfiguration.md b/docs_src/general/ServiceConfiguration.md index a1929220d..027d1c8a7 100644 --- a/docs_src/general/ServiceConfiguration.md +++ b/docs_src/general/ServiceConfiguration.md @@ -29,7 +29,7 @@ Please refer to the general [Common Configuration documentation](../microservice === "Device" |Service Name| Configuration Reference| |---|---| - |device-service |[General Device Service Configuration](../microservices/device/Ch-DeviceServices.md#configuration-properties)| + |device-service |[General Device Service Configuration](../microservices/device/Configuration.md)| |device-virtual |[Virtual Device Service Configuration](../microservices/device/services/device-virtual/Ch-VirtualDevice.md#configuration-properties)| === "Security" |Service Name| Configuration Reference| diff --git a/docs_src/getting-started/Ch-GettingStartedCDevelopers.md b/docs_src/getting-started/Ch-GettingStartedCDevelopers.md index 8730fd357..c9885479f 100644 --- a/docs_src/getting-started/Ch-GettingStartedCDevelopers.md +++ b/docs_src/getting-started/Ch-GettingStartedCDevelopers.md @@ -96,4 +96,4 @@ apk add iotech-iot-1.5-dev Note: If not using Alpine 3.16, replace v3.16 in the above commands with the correct version. ## Next Steps -To explore how to create and build EdgeX device services in C, head to the [Device Services, C SDK guide](Ch-GettingStartedSDK-C.md). +To explore how to create and build EdgeX device services in C, head to the [Device Services, C SDK guide](../microservices/device/sdk/devicesdk-getting-started/GettingStartedSDK-C.md). diff --git a/docs_src/getting-started/Ch-GettingStartedGoDevelopers.md b/docs_src/getting-started/Ch-GettingStartedGoDevelopers.md index 0144b6cc3..0391f1665 100644 --- a/docs_src/getting-started/Ch-GettingStartedGoDevelopers.md +++ b/docs_src/getting-started/Ch-GettingStartedGoDevelopers.md @@ -181,7 +181,7 @@ See [EdgeX Default Service Ports](../../general/ServicePorts) for a list of the Application services and some device services are also built in Go. To explore how to create and build EdgeX application and devices services in Go, head to SDK documentation covering these EdgeX elements. - [Application Services and the Application Functions SDK](../microservices/application/sdk/GettingStarted.md) -- [Device Services in Go](./Ch-GettingStartedSDK-Go.md) +- [Device Services in Go](../microservices/device/sdk/devicesdk-getting-started/GettingStartedSDK-Go.md) ## EdgeX Foundry in GoLand diff --git a/docs_src/getting-started/Ch-GettingStartedSDK.md b/docs_src/getting-started/Ch-GettingStartedSDK.md deleted file mode 100644 index 50ca2093b..000000000 --- a/docs_src/getting-started/Ch-GettingStartedSDK.md +++ /dev/null @@ -1,27 +0,0 @@ -# Device Service SDK - -The EdgeX device service [software development kits](../general/Definitions.md#Software-Development-Kit) (SDKs) help developers create new [device](..general/../../general/Definitions.md#Device) connectors for EdgeX. An SDK provides the common scaffolding that each device service needs. This allows developers to create new device/sensor connectors more quickly. - -![image](EdgeX_DeviceServiceSDK.png) - -The EdgeX community already provides many device services. However, there is no way the community can provide for every protocol and every sensor. -Even if the EdgeX community provided a device service for every protocol, your use case, sensor, or security infrastructure might require customization. Thus, the device service SDKs provide the means to extend or customize EdgeX’s device connectivity. - -EdgeX provides two SDKs to help developers create new device services. Most of EdgeX is written in Go and C. Thus, there's a device service SDK written in both Go and C to support the more popular languages used in EdgeX today. In the future, the community may offer alternate language SDKs. - -The SDKs are libraries that get incorporated into a new micro services. They make writing a new device service much easier. By importing the SDK library into your new device service project, developers are left to focus on the code that is specific to the communications with the device via the protocol of the device. - -The code in the SDK handles the other details, such as: -- initialization of the device service -- getting the service configured -- sending sensor data to core data -- managing communications with core metadata -- and much more. - -The code in the SDK also helps to ensure your device service adheres to rules and standards of EdgeX. For example, it makes sure the service registers with the EdgeX registry service when it starts. - -[Use the GoLang SDK](Ch-GettingStartedSDK-Go.md) - -[Use the C SDK](Ch-GettingStartedSDK-C.md) - - diff --git a/docs_src/getting-started/index.md b/docs_src/getting-started/index.md index a514566c1..9b26c496c 100644 --- a/docs_src/getting-started/index.md +++ b/docs_src/getting-started/index.md @@ -44,10 +44,10 @@ may also want to obtain the Device Service Software Development Kit (DS SDK) and create new device services. The DS SDK creates all the scaffolding code for a new EdgeX Foundry device service; allowing you to focus on the details of interfacing with the device in its native -protocol. See [Getting Started with Device SDK](./Ch-GettingStartedSDK.md) +protocol. See [Getting Started with Device SDK](../microservices/device/sdk/Purpose.md) for help on using the DS SDK to create a new device service. Learn more about Device Services and the Device Service SDK at -[Device Services](../microservices/device/Ch-DeviceServices.md). +[Device Services](../microservices/device/DeviceService.md). ## Application Service Developer diff --git a/docs_src/getting-started/tools/Ch-GUI.md b/docs_src/getting-started/tools/Ch-GUI.md index adf27330a..cf7868d32 100644 --- a/docs_src/getting-started/tools/Ch-GUI.md +++ b/docs_src/getting-started/tools/Ch-GUI.md @@ -59,7 +59,7 @@ The GUI allows you to ### Dashboard The Dashboard page (the main page of the GUI) presents you with a set of clickable "tiles" that provide a quick view of the status of your EdgeX instance. That is, it provides some quick data points about the EdgeX instance and what the GUI is tracking. Specifically, the tiles in the Dashboard show you: -- the number of [device services](../../microservices/device/Ch-DeviceServices.md) that it is aware of and their status (locked vs unlocked) +- the number of [device services](../../microservices/device/DeviceService.md) that it is aware of and their status (locked vs unlocked) - the number of devices being managed by EdgeX (through the associated device services) - the number of [device profiles](../../microservices/core/metadata/details/DeviceProfile.md) registered with core metadata - the number of [schedules](../../microservices/support/scheduler/Purpose.md) (or intervals) EdgeX is managing diff --git a/docs_src/microservices/device/ApiReference.md b/docs_src/microservices/device/ApiReference.md new file mode 100644 index 000000000..03422b6c3 --- /dev/null +++ b/docs_src/microservices/device/ApiReference.md @@ -0,0 +1,9 @@ +--- +title: Device Service - API Reference +--- + +# Device Service - API Reference + +The following REST APIs are provided by the Device Services SDK and are inherited by all Device Services. + + diff --git a/docs_src/microservices/device/Ch-DeviceServices.md b/docs_src/microservices/device/Ch-DeviceServices.md deleted file mode 100644 index 37adf5075..000000000 --- a/docs_src/microservices/device/Ch-DeviceServices.md +++ /dev/null @@ -1,286 +0,0 @@ -# Device Services Overview - -![image](EdgeX_DeviceServices.png) - -## Introduction - -The Device Services Layer interacts with Device Services. - -Device services are the edge connectors interacting with the -[devices](../../general/Definitions.md#device) that include, but are not limited to: appliances -in your home, alarm systems, HVAC equipment, lighting, machines in any -industry, irrigation systems, drones, traffic signals, automated -transportation, and so forth. - -EdgeX device services translate information coming from devices via hundreds of protocols and thousands of formats and bring them into EdgeX. In other terms, device services ingest sensor data provided by “things”. When it ingests the sensor data, the device service converts the data produced and communicated by the “thing” into a common EdgeX Foundry data structure, and sends that converted data into the core services layer, and to other micro services in other layers of EdgeX Foundry. - -Device services also receive and handle any request for actuation back to the device. Device services take a general command from EdgeX to perform some sort of action and it translates that into a protocol specific request and forwards the request to the desired device. - -Device services serve as the main means EdgeX interacts with sensors/devices. So, in addition to getting sensor data and actuating devices, device services also: - -- Get status updates from devices/sensors -- Transform data before sending sensor data to EdgeX -- Change configuration -- Discover devices - -Device services may service one or a number of devices at one time. - -A device that a device service manages, could be something other than a simple, single, physical device. The device could be an edge/IoT [gateway](../../general/Definitions.md#gateway) (and all of that gateway's devices), a device manager, a sensor hub, a web service available over HTTP, or a software sensor that acts as a device, or collection of devices, to EdgeX Foundry. - -![image](EdgeX_Device.png) - -The device service communicates with the devices through protocols native to each device object. EdgeX comes with a number of device services speaking many common IoT protocols such as Modbus, BACnet, BLE, etc. EdgeX also provides the means to create new devices services through [device service software development kits (SDKs)](./sdk/Ch-DeviceSDK.md) when you encounter a new protocol and need EdgeX to communicate with a new device. - -## Device Service Abstraction - -A device service is really just a software abstraction around a device and any associated firmware, software and protocol stack. It allows the rest of EdgeX (and users of EdgeX) to talk to a device via the abstraction API so that all devices look the same from the perspective of how you communicate with them. Under the covers, the implementation of the device service has some common elements, but can also vary greatly depending on the underlying device, protocol, and associate software. - -![image](EdgeX_DeviceServiceAbstraction.png) - -A device service provides the abstraction between the rest of EdgeX and the physical device. In other terms, the device service “wraps” the protocol communication code, device driver/firmware and actual device. - -Each device service in EdgeX is an independent micro service. Devices services are typically created using a [device service SDK](./sdk/Ch-DeviceSDK.md). The SDK is really just a library that provides common scaffolding code and convenience methods that are needed by all device services. While not required, the EdgeX community use the SDKs as the basis for the all device services the community provides. The SDKs make it easier to create device service by allowing a developer to focus on device specific communications, features, etc. versus having to code a lot of EdgeX service boilerplate code. Using the SDKs also helps to ensure the device services adhere to rules required of the device services. - -Unless you need to create a new device service or modify an existing device service, you may not ever have to go under the covers, so to speak, to understand how a device service works. However, having some general understanding of what a device service does and how it does it can be helpful in customization, setting configuration and diagnosing problems. - -## Device Service Functionality - -All device services must perform the following tasks: - -- Register with core metadata – thereby letting all of EdgeX know that it is running and stands ready to manage devices. In the case of an existing device service, the device service will update its metadata registration and get any new information. -- Get its configuration settings from the EdgeX’s configuration service (or local configuration file if the configuration service is not being used). -- Register itself an EdgeX running micro service with the EdgeX registry service (when running) – thereby allowing other EdgeX services to communicate with it. -- On-board and manage physical devices it knows how to communicate with. This process is called provisioning of the device(s). In some cases, the device service may have the means to automatically detect and provision the devices. For example, a BLE device service may automatically scan a BLE address space, detect a new BLE device in its range, and then provision that device to EdgeX and the associated BLE device service. -- Update and inform EdgeX on the operating state of the device (does it appear the device is still running and able to communicate). -- Monitor for configuration changes and apply new configuration where applicable. Note, in some cases configuration changes cannot be dynamically applied (example: change the operating port of the device service). -- Get sensor data (i.e. ingest sensor data) and pass that data to the core data micro service via REST. -- Receive and react to REST based actuation commands. - -As you can imagine, many of these tasks (like registering with core metadata) are generic and the same for all device services and thereby provided by the SDK. Other tasks (like getting sensor data from the underlying device) are quite specific to the underlying device. In these cases, the device service SDK provides empty functions for performing the work, but the developer would need to fill in the function code as it relates to the specific device, the communication protocol, device driver, etc. - -### Device Service Functional Requirements - -[Requirements for the device service](../../design/legacy-requirements/device-service.md) are provided in this documentation. These -requirements are being used to define what functionality needs to be -offered via any Device Service SDK to produce the device service -scaffolding code. They may also help the reader further understand the duties -and role of a device service. - -## Device Profile - -EdgeX comes with a number of existing device services for communicating with devices that speak many IoT protocols – such as Modbus, BACnet, BLE, etc. While these devices services know how to speak to devices that communicate by the associated protocol, the device service doesn’t know the specifics of all devices that speak that protocol. For example, there are thousands of Modbus devices in the world. It is a common industrial protocol used in a variety of devices. Some Modbus devices measure temperature and humidity and provide thermostatic control over building HVAC systems, while other Modbus devices are used in automation control of flare gas meters in the oil and gas industry. This diversity of devices means that the Modbus device service could never know how to communicate with each Modbus device directly. The device service just knows the Modbus protocol generically and must be informed of how to communicate with each individual device based on what that device knows and communicates. Using an analogy, you may speak a language or two. Just because you speak English, doesn’t mean you know everything about all English-speaking people. For example, just because someone spoke English, you would not know if they could solve a calculus problem for you or if they can sing your favorite song. - -Device profiles describe a specific device to a device service. Each device managed by a device service has an association device profile, which defines that device in terms of the data it reports and operations that it supports. General characteristics about the type of device, the data the device provides, and how to command the device is all provided in a device profile. A device profile is described in YAML which is a human-readable data serialization language (similar to a markup language like XML). See the [page on device profiles](../core/metadata/details/DeviceProfile.md) to learn more about how they provide the detail EdgeX device services need to communicate with a device. - -!!! Info - Device profiles, while normally provided to EdgeX in a YAML file, can also be specified to EdgeX in JSON. See the metadata API for [upload via JSON](../../api/core/Ch-APICoreMetadata.md#swagger) versus [upload YAML file](../../api/core/Ch-APICoreMetadata.md#swagger). - -## Device Discovery and Provision Watchers - -Device Services may contain logic to automatically provision new devices. This can be done **statically** or **dynamically**. - -### Static Provisioning - -In static device configuration (also known as static provisioning) the device service connects to and establishes a new device that it manages in EdgeX (specifically metadata) from configuration the device service is provided. For example, a device service may be provided with the specific IP address and additional device details for a device (or devices) that it is to onboard at startup. In static provisioning, it is assumed that the device will be there and that it will be available at the address or place specified through configuration. The devices and the connection information for those devices is known at the point that the device service starts. - -### Dynamic Provisioning - -In dynamic discovery (also known as automatic provisioning), a device service is given some general information about where to look and general parameters for a device (or devices). For example, the device service may be given a range of BLE address space and told to look for devices of a certain nature in this range. However, the device service does not know that the device is physically there – and the device may not be there at start up. It must continually scan during its operations (typically on some sort of schedule) for new devices within the guides of the location and device parameters provided by configuration. - -Not all device services support dynamic discovery. If it does support dynamic discovery, the configuration about what and where to look (in other words, where to scan) for new devices is specified by a provision watcher. A provision watcher is created via a call to the [core metadata provision watcher API](../../api/core/Ch-APICoreMetadata.md#swagger) (and is stored in the metadata database). - -A Provision Watcher is a filter which is applied to any new devices found when a device service scans for devices. It contains a set of ProtocolProperty names and values, these values may be regular expressions. If a new device is to be added, each of these must match the corresponding properties of the new device. Furthermore, a provision watcher may also contain “blocking” identifiers, if any of these match the properties of the new device (note that matching here is *not* regex-based), the device will not be automatically provisioned. This allows the scope of a device scan to be narrowed or allow specific devices to be avoided. - -More than one Provision Watcher may be provided for a device service, and discovered devices are added if they match with any one of them. In addition to the filtering criteria, a Provision Watcher includes specification of various properties to be associated with the new device which matches it: these are the Profile name, the initial AdminState, and optionally any AutoEvents to be applied. - -## Admin State - -The **adminState** is either `LOCKED` or `UNLOCKED` for each device. This is an administrative condition applied to the device. This state is periodically set by an administrator of the system – perhaps for system maintenance or upgrade of the sensor. When `LOCKED`, requests to the device via the device service are stopped and an indication that the device is locked (HTTP 423 status code) is returned to the caller. - -## Sensor Reading Schedule - -Data collected from devices by a device service is marshalled into EdgeX event and reading objects (delivered as JSON objects in service REST calls). This is one of the primary responsibilities of a device service. Typically, a configurable schedule - called an **auto event schedule** - determines when a device service sends data to core data via core data’s REST API (future EdgeX implementations may afford alternate means to send the data to core data or to send sensor data to other services). - -## Test and Demonstration Device Services - -Among the many available device services provided by EdgeX, there are two device services that are typically used for demonstration, education and testing purposes only. The random device service ([device-random-go](https://github.com/edgexfoundry/device-random)) is a very simple device service used to provide device service authors a bare bones example inclusive of a device profile. It can also be used to create random integer data (either 8, 16, or 32 bit signed or unsigned) to simulate integer readings when developing or testing other EdgeX micro services. It was created from the Go-based device service SDK. - -The virtual device service ([device-virtual-go](https://github.com/edgexfoundry/device-virtual-go)) is also used for demonstration, education and testing. It is a more complex simulator in that it allows any type of data to be generated on a scheduled basis and used an embedded SQL database (ql) to provide simulated data. Manipulating the data in the embedded database allows the service to mimic almost any type of sensing device. More information on the [virtual device service](services/device-virtual/Ch-VirtualDevice.md) is available in this documentation. - -## Running multiple instances - -Device services support one additional command-line argument, `--instance` or `-i`. This allows for running multiple instances of a device service in an EdgeX deployment, by giving them different names. - -For example, running `device-modbus -i 1` results in a service named `device-modbus_1`, ie the parameter given to the `instance` argument is added as a suffix to the device service name. The same effect may be obtained by setting the `EDGEX_INSTANCE_NAME` environment variable. - -## Publish to MessageBus - -Device services now have the capability to publish Events directly to the EdgeX MessageBus, rather than POST the Events to Core Data via REST. This capability is controlled by the `Device.UseMessageBus` configuration property (see below), which is set to `true` by default. Core Data is configured by default to subscribe to the EdgeX MessageBus to receive and persist the Events. Application services, as in EdgeX 1.x, subscribe to the EdgeX MessageBus to receive and process the Events. - -!!! edgey "Edgex 3.0" - Upon successful PUT command, Device services will also publish an Event with the updated Resource value(s) to the EdgeX MessageBus as long as the Resource(s) are not write-only. - -## Configuration Properties - -Please refer to the general [Common Configuration documentation](../configuration/CommonConfiguration.md) for configuration properties common to all services. - -!!! edgey - "EdgeX 3.0" - **UpdateLastConnected** is removed in EdgeX 3.0. - -!!! edgey "Edgex 3.0" - For EdgeX 3.0 the `MessageQueue` configuration has been move to `MessageBus` in [Common Configuration](../../../configuration/CommonConfiguration/#configuration-properties) - -!!! note - The `*` on the configuration section names below denoted that these sections are pulled from the device service common configuration thus are not in the individual device service's private configuration file. - -=== "Writable" - |Property|Default Value|Description| - |---|---|---| - ||Writable properties can be set and will dynamically take effect without service restart| - |LogLevel|INFO|log entry [severity level](https://en.wikipedia.org/wiki/Syslog#Severity_level). Log entries not of the default level or higher are ignored. | -=== "Writable.Reading*" - |Property|Default Value|Description| - |---|---|---| - |ReadingUnits|true|Indicate the units of measure for the Value in the Reading, set to `false` to not include units in the Reading. | -=== "Writable.Telemetry*" - |Property|
Default Value
|Description| - |---|---|---| - |||See `Writable.Telemetry` at [Common Configuration](../../configuration/CommonConfiguration/#configuration-properties) for the Telemetry configuration common to all services | - |Metrics| |Service metrics that the device service collects. Boolean value indicates if reporting of the metric is enabled. Common and custom metrics are also included.| - ||`EventsSent` = false |Enable/disable reporting of the built-in **EventsSent** metric| - ||`ReadingsSent` = false |Enable/disable reporting of the built-in **ReadingsSent** metric| - ||`LastConnected` = false |Enable/disable reporting of the built-in **LastConnected** metric| - ||`` = false |Enable/disable reporting of custom device service's custom metric. See [Custom Device Service Metrics](../../getting-started/Ch-GettingStartedSDK-Go/#built-in) for more details.| - |Tags|``|List of arbitrary service level tags to included with every metric that is reported. | -=== "Clients.core-metadata*" - |Property|Default Value|Description| - |---|---|---| - |Protocol|http| The protocol to use when building a URI to the service endpoint| - |Host|localhost| The host name or IP address where the service is hosted | - |Port|59881| The port exposed by the target service| -=== "Device*" - |Property|Default Value|Description| - |---|---|---| - |||Properties that determine how the device service communicates with a device| - |DataTransform|true|Controls whether transformations are applied to numeric readings| - |MaxCmdOps|128|Maximum number of resources in a device command (hence, readings in an event)| - |MaxCmdResultLen|256|Maximum JSON string length for command results| - |ProfilesDir|'./res/profiles'|If set, directory or index URI containing profile definition files to upload to core-metadata. See [URI for Device Service Files](#uris-for-device-service-files) for more information on URI index files. Also may be in device service private config, so it can be overridden with environment variable| - |DevicesDir|'./res/devices'|If set, directory or index URI containing device definition files to upload to core-metadata. See [URI for Device Service Files](#uris-for-device-service-files) for more information on URI index files. Also may be in device service private config, so it can be overridden with environment variable| - |ProvisionWatchersDir|''|If set, directory or index URI containing provision watcher definition files to upload to core-metadata (service specific when needed). See [URI for Device Service Files](#uris-for-device-service-files) for more information on URI index files.| - |EnableAsyncReadings| true| Enables/Disables the Device Service ability to handle async readings | - |AsyncBufferSize| 16| Size of the buffer for async readings| - |Discovery/Enabled|false|Controls whether device discovery is enabled| - |Discovery/Interval|30s|Interval between automatic discovery runs. Zero means do not run discovery automatically| -=== "MaxEventSize*" - |Property|Default Value|Description| - |---|---|---| - |MaxEventSize|0|maximum event size in kilobytes sent to Core Data or MessageBus. 0 represents default to system max.| - -### URIs for Device Service Files - -!!! edgey "EdgeX 3.1" - Support for URIs for Devices, Profiles, and Provision Watchers is new in EdgeX 3.1. - -When loading device definitions, device profiles, and provision watchers from a URI, the directory field (ie `DevicesDir`, `ProfilesDir`, `ProvisionWatchersDir`) loads an index file instead of a folder name. -The contents of the index file will specify the individual files to load by URI by appending the filenames to the URI as shown in the example below. -Any authentication specified in the original URI will be used in subsequent URIs. See the [URI for Files](../general/index.md#uri-for-files) section for more details. - -!!! example "Example Device Dir loaded from URI in service configuration" -```yaml -... -ProfilesDir = "./res/profiles" -DevicesDir = "http://example.com/devices/index.json" -ProvisionWatchersDir = "./res/provisionwatchers" -... -``` - -#### Device Definition URI Example -For device definitions, the index file contains the list of references to device files that contain one or more devices. - -!!! example "Example Device Index File at `http://example.com/devices/index.json` and resulting URIs" - ```json - [ - "device1.yaml", "device2.yaml" - ] - which results in the following URIs: - http://example.com/devices/device1.yaml - http://example.com/devices/device2.yaml - ``` - -#### Device Profile and Provision Watchers URI Example -For device profiles and provision watchers, the index file contains a dictionary of key-value pairs that map the name of the profile or provision watcher to its file. -The name is mapped so that the resources are only loaded from a URI if a device profile or provision watcher by that name has not been loaded yet. - -!!! example "Example Device Profile Index File at `http://example.com/profiles/index.json` and resulting URIs" - ```json - { - "Simple-Device": "Simple-Driver.yaml", - "Simple-Device2": "Simple-Driver2.yml" - } - which results in the following URIs: - http://example.com/profiles/Simple-Driver.yaml - http://example.com/profiles/Simple-Driver2.yml - ``` - -### Custom Configuration - -Device services can have custom configuration in one of two ways. See the table below for details. - -=== "Driver" - `Driver` - The Driver section used for simple custom settings and is accessed via the SDK's DriverConfigs() API. The DriverConfigs API returns a `map[string] string` containing the contents on the `Driver` section of the `configuration.yaml` file. - - ```yaml - Driver: - MySetting: "My Value" - ``` -=== "Custom Structured Configuration" - For Go Device Services see [Go Custom Structured Configuration](../../../getting-started/Ch-GettingStartedSDK-Go/#custom-structured-configuration) for more details. - - - For C Device Service see [C Custom Structured Configuration](../../../getting-started/Ch-GettingStartedSDK-C/#custom-structured-configuration) for more details. - -## Secrets - -#### Configuration - -!!! edgey "Edgex 3.0" - For EdgeX 3.0 the **SecretStore** configuration has been removed from each service's configuration files. It has default values which can be overridden with environment variables. See the [SecretStore Overrides](../CommonEnvironmentVariables/#secretstore-overrides) section for more details. - -All instances of Device Services running in secure mode require a `SecretStore` to be created for the service by the Security Services. See [Configuring Add-on Service](../../../security/Ch-Configuring-Add-On-Services) for details on configuring a `SecretStore` to be created for the Device Service. With the use of `Redis Pub/Sub` as the default EdgeX MessageBus all Device Services need the `redisdb` known secret added to their `SecretStore` so they can connect to the Secure EdgeX MessageBus. See the [Secure MessageBus](../../../security/Ch-Secure-MessageBus) documentation for more details. - -Each Device Service also has detailed configuration to enable connection to it's exclusive `SecretStore` - -#### Storing Secrets - -##### Secure Mode - -When running an Device Service in secure mode, secrets can be stored in the SecretStore by making an HTTP `POST` call to the `/api/{{api_version}}/secret` API route on the Device Service. The secret data POSTed is stored to the service's secure`SecretStore` . Once a secret is stored, only the service that added the secret will be able to retrieve it. See the [Secret API Reference](../../api/devices/Ch-APIDeviceSDK.md#swagger) for more details and example. - -##### Insecure Mode - -When running in insecure mode, the secrets are stored and retrieved from the *Writable.InsecureSecrets* section of the service's configuration.yaml file. Insecure secrets and their paths can be configured as below. - -!!! example "Example - InsecureSecrets Configuration" - ```yaml - Writable: - InsecureSecrets: - DB: - SecretName: "redisdb" - SecretData: - username: "" - password: "" - MQTT: - SecretName: "credentials" - SecretData: - username: "mqtt-user" - password: "mqtt-password" - ``` - -#### Retrieving Secrets - -Device Services retrieve secrets from their `SecretStore` using the SDK API. See [Retrieving Secrets](../../../getting-started/Ch-GettingStartedSDK-Go/#retrieving-secrets) for more details using the Go SDK. - -## API Reference - -[Device Service - SDK- API Reference](../../api/devices/Ch-APIDeviceSDK.md#swagger) diff --git a/docs_src/microservices/device/Configuration.md b/docs_src/microservices/device/Configuration.md new file mode 100644 index 000000000..7fcfea2f4 --- /dev/null +++ b/docs_src/microservices/device/Configuration.md @@ -0,0 +1,168 @@ +--- +title: Device Service - Configuration +--- + +# Device Service - Configuration + +Please refer to the general [Common Configuration documentation](../configuration/CommonConfiguration.md) for configuration properties common to all services. + +!!! edgey - "EdgeX 3.0" + **UpdateLastConnected** is removed in EdgeX 3.0. + +!!! edgey "Edgex 3.0" + For EdgeX 3.0 the `MessageQueue` configuration has been move to `MessageBus` in [Common Configuration](../../../configuration/CommonConfiguration/#configuration-properties) + + +!!! edgey "EdgeX 3.1" + New in EdgeX 3.1 is URI for files which allows the private configuration file to be pulled from a remote location via a URI rather than from the local file system. See [Config File Command-line](../configuration/CommonCommandLineOptions.md#config-file) section for more details. + +!!! note + The `*` on the configuration section names below denoted that these sections are pulled from the device service common configuration thus are not in the individual device service's private configuration file. + +=== "Writable" +|Property|Default Value|Description| +|---|---|---| +||Writable properties can be set and will dynamically take effect without service restart| +|LogLevel|INFO|log entry [severity level](https://en.wikipedia.org/wiki/Syslog#Severity_level). Log entries not of the default level or higher are ignored. | +=== "Writable.Reading*" +|Property|Default Value|Description| +|---|---|---| +|ReadingUnits|true|Indicate the units of measure for the Value in the Reading, set to `false` to not include units in the Reading. | +=== "Writable.Telemetry*" +|Property|
Default Value
|Description| +|---|---|---| +|||See `Writable.Telemetry` at [Common Configuration](../../configuration/CommonConfiguration/#configuration-properties) for the Telemetry configuration common to all services | +|Metrics| |Service metrics that the device service collects. Boolean value indicates if reporting of the metric is enabled. Common and custom metrics are also included.| +||`EventsSent` = false |Enable/disable reporting of the built-in **EventsSent** metric| +||`ReadingsSent` = false |Enable/disable reporting of the built-in **ReadingsSent** metric| +||`LastConnected` = false |Enable/disable reporting of the built-in **LastConnected** metric| +||`` = false |Enable/disable reporting of custom device service's custom metric. See [Custom Device Service Metrics](../../getting-started/Ch-GettingStartedSDK-Go/#built-in) for more details.| +|Tags|``|List of arbitrary service level tags to included with every metric that is reported. | +=== "Clients.core-metadata*" +|Property|Default Value|Description| +|---|---|---| +|Protocol|http| The protocol to use when building a URI to the service endpoint| +|Host|localhost| The host name or IP address where the service is hosted | +|Port|59881| The port exposed by the target service| +=== "Device*" +|Property|Default Value|Description| +|---|---|---| +|||Properties that determine how the device service communicates with a device| +|DataTransform|true|Controls whether transformations are applied to numeric readings| +|MaxCmdOps|128|Maximum number of resources in a device command (hence, readings in an event)| +|MaxCmdResultLen|256|Maximum JSON string length for command results| +|ProfilesDir|'./res/profiles'|If set, directory or index URI containing profile definition files to upload to core-metadata. See [URI for Device Service Files](#uris-for-device-service-files) for more information on URI index files. Also may be in device service private config, so it can be overridden with environment variable| +|DevicesDir|'./res/devices'|If set, directory or index URI containing device definition files to upload to core-metadata. See [URI for Device Service Files](#uris-for-device-service-files) for more information on URI index files. Also may be in device service private config, so it can be overridden with environment variable| +|ProvisionWatchersDir|''|If set, directory or index URI containing provision watcher definition files to upload to core-metadata (service specific when needed). See [URI for Device Service Files](#uris-for-device-service-files) for more information on URI index files.| +|EnableAsyncReadings| true| Enables/Disables the Device Service ability to handle async readings | +|AsyncBufferSize| 16| Size of the buffer for async readings| +|Discovery/Enabled|false|Controls whether device discovery is enabled| +|Discovery/Interval|30s|Interval between automatic discovery runs. Zero means do not run discovery automatically| +=== "MaxEventSize*" +|Property|Default Value|Description| +|---|---|---| +|MaxEventSize|0|maximum event size in kilobytes sent to Core Data or MessageBus. 0 represents default to system max.| + +## URIs for Device Service Files + +!!! edgey "EdgeX 3.1" + Support for URIs for Devices, Profiles, and Provision Watchers is new in EdgeX 3.1. + +When loading device definitions, device profiles, and provision watchers from a URI, the directory field (ie `DevicesDir`, `ProfilesDir`, `ProvisionWatchersDir`) loads an index file instead of a folder name. +The contents of the index file will specify the individual files to load by URI by appending the filenames to the URI as shown in the example below. +Any authentication specified in the original URI will be used in subsequent URIs. See the [URI for Files](../general/index.md#uri-for-files) section for more details. + +!!! example "Example Device Dir loaded from URI in service configuration" +```yaml +... +ProfilesDir = "./res/profiles" +DevicesDir = "http://example.com/devices/index.json" +ProvisionWatchersDir = "./res/provisionwatchers" +... +``` + +#### Device Definition URI Example +For device definitions, the index file contains the list of references to device files that contain one or more devices. + +!!! example "Example Device Index File at `http://example.com/devices/index.json` and resulting URIs" + ```json + [ + "device1.yaml", "device2.yaml" + ] + which results in the following URIs: + http://example.com/devices/device1.yaml + http://example.com/devices/device2.yaml + ``` + +#### Device Profile and Provision Watchers URI Example +For device profiles and provision watchers, the index file contains a dictionary of key-value pairs that map the name of the profile or provision watcher to its file. +The name is mapped so that the resources are only loaded from a URI if a device profile or provision watcher by that name has not been loaded yet. + +!!! example "Example Device Profile Index File at `http://example.com/profiles/index.json` and resulting URIs" + ```json + { + "Simple-Device": "Simple-Driver.yaml", + "Simple-Device2": "Simple-Driver2.yml" + } + which results in the following URIs: + http://example.com/profiles/Simple-Driver.yaml + http://example.com/profiles/Simple-Driver2.yml + ``` + +## Custom Configuration + +Device services can have custom configuration in one of two ways. See the table below for details. + +=== "Driver" + `Driver` - The Driver section used for simple custom settings and is accessed via the SDK's DriverConfigs() API. The DriverConfigs API returns a `map[string] string` containing the contents on the `Driver` section of the `configuration.yaml` file. + + ```yaml + Driver: + MySetting: "My Value" + ``` +=== "Custom Structured Configuration" + For Go Device Services see [Go Custom Structured Configuration](../../../getting-started/Ch-GettingStartedSDK-Go/#custom-structured-configuration) for more details. + + + For C Device Service see [C Custom Structured Configuration](../../../getting-started/Ch-GettingStartedSDK-C/#custom-structured-configuration) for more details. + +## Secrets + +#### Configuration + +!!! edgey "Edgex 3.0" + For EdgeX 3.0 the **SecretStore** configuration has been removed from each service's configuration files. It has default values which can be overridden with environment variables. See the [SecretStore Overrides](../CommonEnvironmentVariables/#secretstore-overrides) section for more details. + +All instances of Device Services running in secure mode require a `SecretStore` to be created for the service by the Security Services. See [Configuring Add-on Service](../../../security/Ch-Configuring-Add-On-Services) for details on configuring a `SecretStore` to be created for the Device Service. With the use of `Redis Pub/Sub` as the default EdgeX MessageBus all Device Services need the `redisdb` known secret added to their `SecretStore` so they can connect to the Secure EdgeX MessageBus. See the [Secure MessageBus](../../../security/Ch-Secure-MessageBus) documentation for more details. + +Each Device Service also has detailed configuration to enable connection to it's exclusive `SecretStore` + +#### Storing Secrets + +##### Secure Mode + +When running an Device Service in secure mode, secrets can be stored in the SecretStore by making an HTTP `POST` call to the `/api/{{api_version}}/secret` API route on the Device Service. The secret data POSTed is stored to the service's secure`SecretStore` . Once a secret is stored, only the service that added the secret will be able to retrieve it. See the [Secret API Reference](../../api/devices/Ch-APIDeviceSDK.md#swagger) for more details and example. + +##### Insecure Mode + +When running in insecure mode, the secrets are stored and retrieved from the *Writable.InsecureSecrets* section of the service's configuration.yaml file. Insecure secrets and their paths can be configured as below. + +!!! example "Example - InsecureSecrets Configuration" + ```yaml + Writable: + InsecureSecrets: + DB: + SecretName: "redisdb" + SecretData: + username: "" + password: "" + MQTT: + SecretName: "credentials" + SecretData: + username: "mqtt-user" + password: "mqtt-password" + ``` + +#### Retrieving Secrets + +Device Services retrieve secrets from their `SecretStore` using the SDK API. See [Retrieving Secrets](../../../getting-started/Ch-GettingStartedSDK-Go/#retrieving-secrets) for more details using the Go SDK. diff --git a/docs_src/microservices/device/DeviceService.md b/docs_src/microservices/device/DeviceService.md new file mode 100644 index 000000000..1720d601e --- /dev/null +++ b/docs_src/microservices/device/DeviceService.md @@ -0,0 +1,53 @@ +--- +title: Device Service - Overview +--- + +# Device Service - Overview + +![image](EdgeX_DeviceServices.png) + +The Device Services Layer interacts with Device Services. + +Device services are the edge connectors interacting with the +[devices](../../general/Definitions.md#device) that include, but are not limited to: appliances +in your home, alarm systems, HVAC equipment, lighting, machines in any +industry, irrigation systems, drones, traffic signals, automated +transportation, and so forth. + +EdgeX device services translate information coming from devices via hundreds of protocols and thousands of formats and bring them into EdgeX. In other terms, device services ingest sensor data provided by “things”. When it ingests the sensor data, the device service converts the data produced and communicated by the “thing” into a common EdgeX Foundry data structure, and sends that converted data into the core services layer, and to other micro services in other layers of EdgeX Foundry. + +Device services also receive and handle any request for actuation back to the device. Device services take a general command from EdgeX to perform some sort of action and it translates that into a protocol specific request and forwards the request to the desired device. + +Device services serve as the main means EdgeX interacts with sensors/devices. So, in addition to getting sensor data and actuating devices, device services also: + +- Get status updates from devices/sensors +- Transform data before sending sensor data to EdgeX +- Change configuration +- Discover devices + +Device services may service one or a number of devices at one time. + +A device that a device service manages, could be something other than a simple, single, physical device. The device could be an edge/IoT [gateway](../../general/Definitions.md#gateway) (and all of that gateway's devices), a device manager, a sensor hub, a web service available over HTTP, or a software sensor that acts as a device, or collection of devices, to EdgeX Foundry. + +![image](EdgeX_Device.png) + +The device service communicates with the devices through protocols native to each device object. EdgeX comes with a number of device services speaking many common IoT protocols such as Modbus, BACnet, BLE, etc. EdgeX also provides the means to create new devices services through [device service software development kits (SDKs)](./sdk/Purpose.md) when you encounter a new protocol and need EdgeX to communicate with a new device. + +## Device Service Abstraction + +A device service is really just a software abstraction around a device and any associated firmware, software and protocol stack. It allows the rest of EdgeX (and users of EdgeX) to talk to a device via the abstraction API so that all devices look the same from the perspective of how you communicate with them. Under the covers, the implementation of the device service has some common elements, but can also vary greatly depending on the underlying device, protocol, and associate software. + +![image](EdgeX_DeviceServiceAbstraction.png) + +A device service provides the abstraction between the rest of EdgeX and the physical device. In other terms, the device service “wraps” the protocol communication code, device driver/firmware and actual device. + +Each device service in EdgeX is an independent micro service. Devices services are typically created using a [device service SDK](./sdk/Purpose.md). The SDK is really just a library that provides common scaffolding code and convenience methods that are needed by all device services. While not required, the EdgeX community use the SDKs as the basis for the all device services the community provides. The SDKs make it easier to create device service by allowing a developer to focus on device specific communications, features, etc. versus having to code a lot of EdgeX service boilerplate code. Using the SDKs also helps to ensure the device services adhere to rules required of the device services. + +Unless you need to create a new device service or modify an existing device service, you may not ever have to go under the covers, so to speak, to understand how a device service works. However, having some general understanding of what a device service does and how it does it can be helpful in customization, setting configuration and diagnosing problems. + +## Publish to MessageBus + +Device services now have the capability to publish Events directly to the EdgeX MessageBus, rather than POST the Events to Core Data via REST. This capability is controlled by the `Device.UseMessageBus` configuration property (see below), which is set to `true` by default. Core Data is configured by default to subscribe to the EdgeX MessageBus to receive and persist the Events. Application services, as in EdgeX 1.x, subscribe to the EdgeX MessageBus to receive and process the Events. + +!!! edgey "Edgex 3.0" + Upon successful PUT command, Device services will also publish an Event with the updated Resource value(s) to the EdgeX MessageBus as long as the Resource(s) are not write-only. \ No newline at end of file diff --git a/docs_src/microservices/device/GettingStarted.md b/docs_src/microservices/device/GettingStarted.md new file mode 100644 index 000000000..399f39e69 --- /dev/null +++ b/docs_src/microservices/device/GettingStarted.md @@ -0,0 +1,28 @@ +--- +title: Device Service - Getting Started +--- + +# Device Service - Getting Started + +## Device Service - Functionality + +All device services must perform the following tasks: + +- Register with core metadata – thereby letting all of EdgeX know that it is running and stands ready to manage devices. In the case of an existing device service, the device service will update its metadata registration and get any new information. +- Get its configuration settings from the EdgeX’s configuration service (or local configuration file if the configuration service is not being used). +- Register itself an EdgeX running micro service with the EdgeX registry service (when running) – thereby allowing other EdgeX services to communicate with it. +- On-board and manage physical devices it knows how to communicate with. This process is called provisioning of the device(s). In some cases, the device service may have the means to automatically detect and provision the devices. For example, an Onvif device service may execute automation of camera discovery in its range, and then provision that device to EdgeX and the associated Onvif device service. +- Update and inform EdgeX on the operating state of the devices it is managing (i.e. are the devices is still running and able to communicate). +- Monitor for configuration changes and apply new configuration where applicable. Note, in some cases configuration changes cannot be dynamically applied (example: change the operating port of the device service). +- Get sensor data (i.e. ingest sensor data) and pass that data to the rest of EdgeX (Core Data, App service, etc.) via the MessageBus. +- Receive and react to REST or MessageBus based actuation commands. + +As you can imagine, many of these tasks (like registering with core metadata) are generic and the same for all device services and thereby provided by the SDK. Other tasks (like getting sensor data from the underlying device) are quite specific to the underlying device protocol. In these cases, the device service SDK provides empty functions for performing the work, but the developer would need to fill in the function code as it relates to the specific device protocol. + +### Device Service Functional Requirements + +[Requirements for the device service](../../design/legacy-requirements/device-service.md) are provided in this documentation. These +requirements are being used to define what functionality needs to be +offered via any Device Service SDK to produce the device service +scaffolding code. They may also help the reader further understand the duties +and role of a device service. \ No newline at end of file diff --git a/docs_src/microservices/device/V3Migration.md b/docs_src/microservices/device/V3Migration.md index a22b12bc1..765b94322 100644 --- a/docs_src/microservices/device/V3Migration.md +++ b/docs_src/microservices/device/V3Migration.md @@ -1,4 +1,8 @@ -# V3 Device Service Migration Guide +--- +title: Device Service - V3 Migration Guide +--- + +# Device Service - V3 Migration Guide ## All Device Services diff --git a/docs_src/microservices/device/details/CommandLine.md b/docs_src/microservices/device/details/CommandLine.md new file mode 100644 index 000000000..7ec5bd85f --- /dev/null +++ b/docs_src/microservices/device/details/CommandLine.md @@ -0,0 +1,15 @@ +--- +title: Device Service - Running multiple instances +--- + +# Device Service - Command-line Options + +See the [Common Command Line Options](../../configuration/CommonCommandLineOptions.md) for the set of command line options common to all EdgeX services. The following command line options are specific to Device Service. + +### Running multiple instances + +`--instance` or `-i` + +Device services support one additional command-line argument, `--instance` or `-i`. + +This allows for running multiple instances of a device service in an EdgeX deployment, by giving them different names. For example, running `device-modbus -i 1` results in a service named `device-modbus_1`, ie the parameter given to the `instance` argument is added as a suffix to the device service name. The same effect may be obtained by setting the [EDGEX_INSTANCE_NAME](./EnvironmentVariables.md) environment variable. diff --git a/docs_src/microservices/device/details/DeviceDiscovery.md b/docs_src/microservices/device/details/DeviceDiscovery.md new file mode 100644 index 000000000..c1a0567d6 --- /dev/null +++ b/docs_src/microservices/device/details/DeviceDiscovery.md @@ -0,0 +1,29 @@ +--- +title: Device Service - Device Discovery and Provision Watchers +--- + +# Device Service - Device Discovery and Provision Watchers + +Device Services may contain logic to automatically provision new devices. This can be done **statically** or **dynamically**. + +### Static Provisioning + +In static provisioning, the device service is provided with a Device file which contains the definition(s) of the device(s) to statically provision. The device service connects to and establishes a new device that it manages in EdgeX (specifically metadata) from device definition configuration the device service is provided. For example, a device service may be provided with the specific IP address and additional device details for a device (or devices) that it is to onboard at startup. In static provisioning, it is assumed that the device will be there and that it will be available at the address or place specified through the device definition configuration. The devices and the connection information for those devices is known at the point that the device service starts. + +### Dynamic Provisioning + +In dynamic provisioning (also known as device discovery), a device service is given some general information about where to look and general parameters for a device (or devices). For example, the device service may be given a range of network address space and told to look for devices of a certain nature in this range. However, the device service does not know that the device is physically there – and the device may not be there at start-up. It must continually scan during its operations (typically on some sort of schedule) for new devices within the guides of the location and device parameters provided by configuration. + +Not all device services support dynamic discovery. If it does support dynamic discovery, the configuration about what and where to look (in other words, where to scan) for new devices is specified by a provision watcher. A provision watcher is created via a call to the [core metadata provision watcher API](../../core/metadata/ApiReference.md) (and is stored in the metadata database). + +A Provision Watcher is a filter which is applied to any new devices found when a device service scans for devices. It contains a set of ProtocolProperty names and values, these values may be regular expressions. If a new device is to be added, each of these must match the corresponding properties of the new device. Furthermore, a provision watcher may also contain “blocking” identifiers, if any of these match the properties of the new device (note that matching here is *not* regex-based), the device will not be automatically provisioned. This allows the scope of a device scan to be narrowed or allow specific devices to be avoided. + +More than one Provision Watcher may be provided for a device service, and discovered devices are added if they match with any one of them. In addition to the filtering criteria, a Provision Watcher includes specification of various properties to be associated with the new device which matches it: these are the Profile name, the initial AdminState, and optionally any AutoEvents to be applied. + +## Admin State + +The **adminState** is either `LOCKED` or `UNLOCKED` for each device. This is an administrative condition applied to the device. This state is periodically set by an administrator of the system – perhaps for system maintenance or upgrade of the sensor. When `LOCKED`, requests to the device via the device service are stopped and an indication that the device is locked (HTTP 423 status code) is returned to the caller. + +## Sensor Reading Schedule + +Data collected from devices by a device service is marshalled into EdgeX event and reading objects which are published to the EdgeX MessageBus. This is one of the primary responsibilities of a device service. Typically, a configurable schedule - called an **auto event schedule** - determines when a device service collects the data from the device. diff --git a/docs_src/microservices/device/details/EnvironmentVariables.md b/docs_src/microservices/device/details/EnvironmentVariables.md new file mode 100644 index 000000000..13e8cf178 --- /dev/null +++ b/docs_src/microservices/device/details/EnvironmentVariables.md @@ -0,0 +1,11 @@ +--- +title: Device Service - Environment Variables +--- + +# Device Service - Environment Variables + +See the [Common Environment Variables](../../configuration/CommonEnvironmentVariables.md) section for the list of environment variables common to all EdgeX Services. The remaining in this section are specific to Device Service. + +### EDGEX_INSTANCE_NAME + +This environment variable overrides the [`-i/--instance` command-line option](CommandLine.md#running-multiple-instances) and the default set by the device service. diff --git a/docs_src/microservices/device/details/SeedingSecrets.md b/docs_src/microservices/device/details/SeedingSecrets.md new file mode 100644 index 000000000..c78399660 --- /dev/null +++ b/docs_src/microservices/device/details/SeedingSecrets.md @@ -0,0 +1,7 @@ +--- +title: Device Service - Seeding Secrets +--- + +# Device Service - Seeding Secrets + +Often device service required their own specific secrets for authentication, encryption, etc. These secrets can be seeded into the service's SecretStore at start-up via a secret seed file. See [Seeding Service Secrets](../../../security/SeedingServiceSecrets.md) security page for more detail. diff --git a/docs_src/microservices/device/details/ServiceMetrics.md b/docs_src/microservices/device/details/ServiceMetrics.md new file mode 100644 index 000000000..c6a0b2603 --- /dev/null +++ b/docs_src/microservices/device/details/ServiceMetrics.md @@ -0,0 +1,15 @@ +--- +title: Device Service - Service Metrics +--- + +# Device Service - Service Metrics + +All device services have the following built-in metrics: + +| Metric Name | Type | Description | +| ----------------------------- | --------- | ------------------------------------------------------------ | +| EventsSent | bool | Enable/disable reporting of the built-in **EventsSent** metric | +| ReadingsSent | bool | Enable/disable reporting of the built-in **ReadingsSent** metric | +| LastConnected | bool | Enable/disable reporting of the built-in **LastConnected** metric| + +See [Custom Service Metrics](../sdk/details/CustomServiceMetrics.md) page for details on creating additional service metrics in a custom device service. diff --git a/docs_src/microservices/device/sdk/Ch-DeviceSDK.md b/docs_src/microservices/device/sdk/Purpose.md similarity index 65% rename from docs_src/microservices/device/sdk/Ch-DeviceSDK.md rename to docs_src/microservices/device/sdk/Purpose.md index e35f6ccc6..92f789deb 100644 --- a/docs_src/microservices/device/sdk/Ch-DeviceSDK.md +++ b/docs_src/microservices/device/sdk/Purpose.md @@ -1,20 +1,19 @@ -# Device Services SDK +--- +title: Device Service SDK - Purpose +--- -![image](EdgeX_SDKs.png) +# Device Service SDK - Purpose + +The EdgeX device service [software development kits](../../../general/Definitions.md#software-development-kit) (SDKs) help developers create new [device](../../../general/Definitions.md#Device) connectors for EdgeX. An SDK provides the common scaffolding that each device service needs. This allows developers to create new device/sensor connectors more quickly. -## Introduction to the SDKs +![image](EdgeX_SDKs.png) EdgeX provides two software development kits (SDKs) to help developers create new device services. While the EdgeX community and the larger EdgeX ecosystem provide a number of open source and commercially available device services for use with EdgeX, there is no way that every protocol and every sensor can be accommodated and connected to EdgeX with a pre-existing device service. Even if all the device service connectivity were provided, your use case, sensor or security infrastructure may require customization. Therefore, the device service SDKs provide the means to extend or customize EdgeX’s device connectivity. EdgeX is mostly written in Go and C. There is a device service SDK written in both Go and C to support the more popular languages used in EdgeX today. In the future, alternate language SDKs may be provided by the community or made available by the larger ecosystem. -The SDKs are really libraries to be incorporated into a new micro service. They make writing a new device service much easier. By importing the SDK library of choice into your new device service project, you can focus on the details associated with getting and manipulating sensor data from your device via the specific protocol of your device. Other details, such as initialization of the device service, getting the service configured, sending sensor data to core data, managing communications with core metadata, and much more are handled by the code in the SDK library. The code in the SDK also helps to ensure your device service adheres to rules and standards of EdgeX – such as making sure the service registers with the EdgeX registry service when it starts up. +The SDKs are really libraries to be incorporated into a new micro service. They make writing a new device service much easier. By importing the SDK library of choice into your new device service project, you can focus on the details associated with getting and manipulating sensor data from your device via the specific protocol of your device. Other details, such as initialization of the device service, getting the service configured, sending sensor data to the EdgeX MessageBus, managing communications with core metadata, and much more are handled by the code in the SDK library. The code in the SDK also helps to ensure your device service adheres to rules and standards of EdgeX – such as making sure the service registers with the EdgeX registry service when it starts up. -The EdgeX Foundry Device Service Software Development Kit (SDK) takes -the developer through the step-by-step process to create an EdgeX -Foundry device service micro service. Then setup the SDK and execute the -code to generate the device service scaffolding to get you started using -EdgeX. The Device Service SDK supports: @@ -26,12 +25,3 @@ The Device Service SDK supports: - Support for multiple classes of Devices with Profiles - Support for sets of actions triggered by a command - Cached responses to queries - -## Writing a Device Service - -- [Writing a new Device Service in Go](../../../getting-started/Ch-GettingStartedSDK-Go.md) -- [Writing a new Device Service in C](../../../getting-started/Ch-GettingStartedSDK-C.md) - -## Reference - -- [C SDK Reference Guide](Ch-Ref-SDK-C.md) diff --git a/docs_src/microservices/device/sdk/SourceCode.md b/docs_src/microservices/device/sdk/SourceCode.md new file mode 100644 index 000000000..70aa15ce7 --- /dev/null +++ b/docs_src/microservices/device/sdk/SourceCode.md @@ -0,0 +1,11 @@ +--- +title: Device Service SDK - Source Code +--- + +# Go Device Service SDK - Source Code + +The source code for the Go Device Services SDK can be found at [https://github.com/edgexfoundry/device-sdk-c/tree/{{edgexversion}}](https://github.com/edgexfoundry/device-sdk-go/tree/{{edgexversion}}). + +# C Device Service SDK - Source Code + +The source code for the C Device Services SDK can be found at [https://github.com/edgexfoundry/device-sdk-c/tree/{{edgexversion}}](https://github.com/edgexfoundry/device-sdk-c/tree/{{edgexversion}}). diff --git a/docs_src/microservices/device/sdk/Ch-Ref-SDK-C.md b/docs_src/microservices/device/sdk/api/CDeviceSDK/CDeviceSDKAPI.md similarity index 98% rename from docs_src/microservices/device/sdk/Ch-Ref-SDK-C.md rename to docs_src/microservices/device/sdk/api/CDeviceSDK/CDeviceSDKAPI.md index f841aeaef..547c2ccde 100644 --- a/docs_src/microservices/device/sdk/Ch-Ref-SDK-C.md +++ b/docs_src/microservices/device/sdk/api/CDeviceSDK/CDeviceSDKAPI.md @@ -1,10 +1,14 @@ -# Device Services C SDK Reference +--- +title: Device Service SDK - Getting Started C Device Services SDK +--- + +# Device Service SDK - Getting Started C Device Services SDK ## Introduction This page provides detail on the API provided by the C SDK. A device service implementation will define a number of callback functions, and a `main` function which registers these functions with the SDK and uses the SDK lifecycle methods to start the service and shut it down. The implementation may also use some of the helper functions which the SDK provides. -In various places information is passed between the SDK and the DS implementation using the `iot_data_t` type. This is a holder for data of different types, and its use is described in its own page : [Use of iot_data_t](Ch-Using-iot-data-t.md) +In various places information is passed between the SDK and the DS implementation using the `iot_data_t` type. This is a holder for data of different types, and its use is described in its own page : [Use of iot_data_t](./Dependencies/CUtilities.md) ## Types @@ -103,6 +107,8 @@ next | devsdk_devices* | The next device in the list, or NULL if this is the las ## Callbacks +Callback functions that a device service needs to execute which depends on its protocol. + Note that each of the callback functions has as its first parameter a `void*` pointer. This pointer is specified by the implementation when the device service is created, and is passed to all callbacks. It may therefore be used to hold whatever state is required by the implementation. ### Required callback functions diff --git a/docs_src/microservices/device/sdk/Ch-Using-iot-data-t.md b/docs_src/microservices/device/sdk/api/CDeviceSDK/Dependencies/CUtilities.md similarity index 98% rename from docs_src/microservices/device/sdk/Ch-Using-iot-data-t.md rename to docs_src/microservices/device/sdk/api/CDeviceSDK/Dependencies/CUtilities.md index 73a2fb436..a1900e5c0 100644 --- a/docs_src/microservices/device/sdk/Ch-Using-iot-data-t.md +++ b/docs_src/microservices/device/sdk/api/CDeviceSDK/Dependencies/CUtilities.md @@ -1,4 +1,8 @@ -# Using iot_data_t +--- +title: Device Service SDK - C Utilities +--- + +# Device Service SDK - C Utilities ## Introduction diff --git a/docs_src/microservices/device/sdk/api/GoDeviceSDK/GoDeviceSDKAPI.md b/docs_src/microservices/device/sdk/api/GoDeviceSDK/GoDeviceSDKAPI.md new file mode 100644 index 000000000..2ef5923ec --- /dev/null +++ b/docs_src/microservices/device/sdk/api/GoDeviceSDK/GoDeviceSDKAPI.md @@ -0,0 +1,310 @@ +--- +title: Device Service SDK - Getting Started Go Device Services SDK +--- + +# Device Service SDK - Getting Started Go Device Services SDK + +The `DeviceServiceSDK` API provides the following APIs for the device service developer to use. + +```go +type DeviceServiceSDK interface { + AddDevice(device models.Device) (string, error) + Devices() []models.Device + GetDeviceByName(name string) (models.Device, error) + UpdateDevice(device models.Device) error + RemoveDeviceByName(name string) error + AddDeviceProfile(profile models.DeviceProfile) (string, error) + DeviceProfiles() []models.DeviceProfile + GetProfileByName(name string) (models.DeviceProfile, error) + UpdateDeviceProfile(profile models.DeviceProfile) error + RemoveDeviceProfileByName(name string) error + AddProvisionWatcher(watcher models.ProvisionWatcher) (string, error) + ProvisionWatchers() []models.ProvisionWatcher + GetProvisionWatcherByName(name string) (models.ProvisionWatcher, error) + UpdateProvisionWatcher(watcher models.ProvisionWatcher) error + RemoveProvisionWatcher(name string) error + DeviceResource(deviceName string, deviceResource string) (models.DeviceResource, bool) + DeviceCommand(deviceName string, commandName string) (models.DeviceCommand, bool) + AddDeviceAutoEvent(deviceName string, event models.AutoEvent) error + RemoveDeviceAutoEvent(deviceName string, event models.AutoEvent) error + UpdateDeviceOperatingState(name string, state models.OperatingState) error + DeviceExistsForName(name string) bool + PatchDevice(updateDevice dtos.UpdateDevice) error + Run() error + Name() string + Version() string + AsyncReadingsEnabled() bool + AsyncValuesChannel() chan *sdkModels.AsyncValues + DiscoveredDeviceChannel() chan []sdkModels.DiscoveredDevice + DeviceDiscoveryEnabled() bool + DriverConfigs() map[string]string + AddRoute(route string, handler func(http.ResponseWriter, *http.Request), methods ...string) error + AddCustomRoute(route string, authenticated Authenticated, handler func(echo.Context) error, methods ...string) error + LoadCustomConfig(customConfig UpdatableConfig, sectionName string) error + ListenForCustomConfigChanges(configToWatch interface{}, sectionName string, changedCallback func(interface{})) error + LoggingClient() logger.LoggingClient + SecretProvider() interfaces.SecretProvider + MetricsManager() interfaces.MetricsManager +} +``` + +## APIs + +### Auto Event + +#### AddDeviceAutoEvent + +`AddDeviceAutoEvent(deviceName string, event models.AutoEvent) error` + +This API adds a new AutoEvent to the Device with given name. An error is returned if not able to add AutoEvent + +#### RemoveDeviceAutoEvent + +`RemoveDeviceAutoEvent(deviceName string, event models.AutoEvent) error` + +This API removes an AutoEvent from the Device with given name. An error is returned if not able to remove AutoEvent + +### Device + +#### AddDevice + +`AddDevice(device models.Device) (string, error)` + +This API adds a new Device to Core Metadata and device service's cache. Returns new Device id or an error. + +#### UpdateDevice + +`UpdateDevice(device models.Device) error` + +This API updates the Device in Core Metadata and device service's cache. An error is returned if the Device can not be updated. + +#### UpdateDeviceOperatingState + +`UpdateDeviceOperatingState(deviceName string, state models.OperatingState) error` + +This API updates the Device's operating state for the given name in Core Metadata and device service's cache. An error is return if the operating state can not be updated. + +#### RemoveDeviceByName + +`RemoveDeviceByName(name string) error` + +This API removes the specified Device by name from Core Metadata and device service cache. An error is return if the Device can not be removed. + +#### Devices + +`Devices() []models.Device` + +This API returns all managed Devices from the device service's cache + +#### GetDeviceByName + +`GetDeviceByName(name string) (models.Device, error)` + +This API returns the Device by its name if it exists in the device service's cache, or returns an error. + +#### PatchDevice + +`PatchDevice(updateDevice dtos.UpdateDevice) error` + +This API patches the specified device properties in Core Metadata. Device name is required +to be provided in the UpdateDevice. + +!!! Note + All properties of UpdateDevice are pointers and anything that is `nil` will not modify the device. In the case of Arrays and Maps, the whole new value + must be sent, as it is applied as an overwrite operation. + +!!! example - "Example - PatchDevice()" + ```go + service := interfaces.Service() + locked := models.Locked + return service.PatchDevice(dtos.UpdateDevice{ + Name: &name, + AdminState: &locked, + }) + ``` + +#### DeviceExistsForName + +`DeviceExistsForName(name string) bool` + +This API returns true if a device exists in cache with the specified name, otherwise it returns false. + +### Device Profile + +#### AddDeviceProfile + +`AddDeviceProfile(profile models.DeviceProfile) (string, error)` + +This API adds a new DeviceProfile to Core Metadata and device service's cache. Returns new DeviceProfile id or error + +#### UpdateDeviceProfile + +`UpdateDeviceProfile(profile models.DeviceProfile) error` + +This API updates the DeviceProfile in Core Metadata and device service's cache. An error is returned if the DeviceProfile can not be updated. + +#### RemoveDeviceProfileByName + +`RemoveDeviceProfileByName(name string) error` + +This API removes the specified DeviceProfile by name from Core Metadata and device service's cache. An error is return if the DeviceProfile can not be removed. + +#### DeviceProfiles + +`DeviceProfiles() []models.DeviceProfile` + +This API returns all managed DeviceProfiles from device service's cache. + +#### GetProfileByName + +`GetProfileByName(name string) (models.DeviceProfile, error)` + +This API returns the DeviceProfile by its name if it exists in the cache, or returns an error. + +### Provision Watcher + +#### AddProvisionWatcher + +`AddProvisionWatcher(watcher models.ProvisionWatcher) (string, error)` + +This API adds a new Watcher to Core Metadata and device service's cache. Returns new ProvisionWatcherid or error. + +#### UpdateProvisionWatcher + +`UpdateProvisionWatcher(watcher models.ProvisionWatcher) error` + +This API updates the ProvisionWatcherin in Core Metadata and device service's cache. An error is returned if the ProvisionWatcher can not be updated. + +#### RemoveProvisionWatcher + +`RemoveProvisionWatcher(name string) error` + +This API removes the specified ProvisionWatcherby name from Core Metadata and device service's cache. An error is return if the ProvisionWatcher can not be removed. + +#### ProvisionWatchers + +`ProvisionWatchers() []models.ProvisionWatcher` + +This API returns all managed ProvisionWatchers from device service's cache. + +#### GetProvisionWatcherByName + +`GetProvisionWatcherByName(name string) (models.ProvisionWatcher, error)` + +This API returns the ProvisionWatcher by its name if it exists in the device service's , or returns an error. + +### Resource & Command + +#### DeviceResource + +`DeviceResource(deviceName string, deviceResource string) (models.DeviceResource, bool)` + +This API retrieves the specific DeviceResource instance from device service's cache for the specified Device name and Resource name. Returns the DeviceResource and true if found in device service's cache or false if not found. + +#### DeviceCommand + +`DeviceCommand(deviceName string, commandName string) (models.DeviceCommand, bool)` + +This API retrieves the specific DeviceCommand instance from device service's cache for the specified Device name and Command name. Returns the DeviceCommand and true if found in device service's cache or false if not found. + +### Custom Configuration + +#### LoadCustomConfig + +`LoadCustomConfig(customConfig service.UpdatableConfig, sectionName string) error` + +This API attempts to load service's custom configuration. It uses the same command line flags to process the custom config in the same manner + as the standard configuration. Returns an error is custom configuration can not be loaded. See [Custom Structured Configuration](../../../getting-started/Ch-GettingStartedSDK-Go/#custom-structured-configuration) section for more details. + +#### ListenForCustomConfigChanges + +`ListenForCustomConfigChanges(configToWatch interface{}, sectionName string, changedCallback func(interface{})) error` + +This API attempts to start listening for changes to the specified custom configuration section. LoadCustomConfig API must be called before this API. See [Custom Structured Configuration](../../../getting-started/Ch-GettingStartedSDK-Go/#custom-structured-configuration) section for more details. + +### Miscellaneous + +#### Name + +`Name() string` + +This API returns the name of the Device Service. + +#### Version + +`Version() string` + +This API returns the version number of the Device Service. + +#### DriverConfigs + +`DriverConfigs() map[string]string` + +This API returns the driver specific configuration + +#### AsyncReadingsEnabled + +`AsyncReadingsEnabled() bool` + +This API returns a bool value to indicate whether the asynchronous reading is enabled via configuration. + +#### DeviceDiscoveryEnabled + +`DeviceDiscoveryEnabled() bool` + +This API returns a bool value to indicate whether the device discovery is enabled via configuration. + +#### AddRoute (Deprecated) + +`AddRoute(route string, handler func(http.ResponseWriter, *http.Request), methods ...string) error` + +This API is deprecated in favor of `AddCustomRoute()` which has an explicit parameter to indicate whether the route should require authentication. + +#### AddCustomRoute + +`AddCustomRoute(route string, authenticated interfaces.Authenticated, handler func(echo.Context) error, methods ...string) error` + +This API allows leveraging the existing internal web server to add routes specific to the Device Service. If the route is marked authenticated, it will require an EdgeX JWT when security is enabled. Returns error is route could not be added. + +!!! Note + The `handler` function uses the signature of `echo.HandlerFunc` which is `func(echo.Context) error`. See [echo API HandlerFunc section](https://pkg.go.dev/github.com/labstack/echo#HandlerFunc) for more details. + +#### LoggingClient + +`LoggingClient() logger.LoggingClient` + +This API returns the `LoggingClient` used to log messages. + + +#### SecretProvider + +`SecretProvider() interfaces.SecretProvider` + +This API returns the SecretProvider used to get/save the service secrets. See [Secret Provider API](../../../../security/Ch-SecretProviderApi/) section for more details. + +#### MetricsManager + +`MetricsManager () interfaces.MetricsManager` + +This API returns the MetricsManager used to register custom service metrics. See [Service Metrics](../../../general/#service-metrics) for more details + +#### AsyncValuesChannel + +`AsyncValuesChannel() chan *sdkModels.AsyncValues` + +This API returns a channel to allow developer send asynchronous reading back to SDK. + +#### DiscoveredDeviceChannel + +`DiscoveredDeviceChannel() chan []sdkModels.DiscoveredDevice` + +This API returns a channel to allow developer send discovered devices back to SDK. + +### Internal + +#### Run + +`Run() error` + +This internal API call starts this Device Service. It should not be called directly by a device service. +Instead, call `startup.Bootstrap(...)`. diff --git a/docs_src/microservices/device/sdk/details/CustomConfiguration.md b/docs_src/microservices/device/sdk/details/CustomConfiguration.md new file mode 100644 index 000000000..46c05a7f6 --- /dev/null +++ b/docs_src/microservices/device/sdk/details/CustomConfiguration.md @@ -0,0 +1,48 @@ +--- +title: Device Service SDK - Custom Configuration +--- + +# Device Service SDK - Custom Configuration + +## C Device Service SDK - Custom Structured Configuration +C Device Services support structured custom configuration as part of the `[Driver]` section in the configuration.yaml file. + +View the `main` function of `template.c`. The `confparams` variable is initialized with default values for three test parameters. These values may be overridden by entries in the configuration file or by environment variables in the usual way. The resulting configuration is passed to the `init` function when the service starts. + +Configuration parameters `X`, `Y/Z` and `Writable/Q` correspond to configuration file entries as follows: +``` +[Writable] + [Writable.Driver] + Q = "foo" + +[Driver] + X = "bar" + [Driver.Y] + Z = "baz" +``` + +Entries in the writable section can be changed dynamically if using the registry; the `reconfigure` callback will be invoked with the new configuration when changes are made. + +In addition to strings, configuration entries may be integer, float or boolean typed. Use the different `iot_data_alloc_` functions when setting up the defaults as appropriate. + +## Go Device Service SDK - Custom Structured Configuration + +Go Device Services can now define their own custom structured configuration section in the `configuration.yaml` file. Any additional sections in the configuration file are ignored by the SDK when it parses the file for the SDK defined sections. + +This feature allows a Device Service to define and watch it's own structured section in the service's configuration file. + +The `SDK` API provides the follow APIs to enable structured custom configuration: + +- `LoadCustomConfig(config UpdatableConfig, sectionName string) error` + + Loads the service's custom configuration from local file or the Configuration Provider (if enabled). The Configuration Provider will also be seeded with the custom configuration the first time the service is started, if service is using the Configuration Provider. The `UpdateFromRaw` interface will be called on the custom configuration when the configuration is loaded from the Configuration Provider. + +- `ListenForCustomConfigChanges(configToWatch interface{}, sectionName string, changedCallback func(interface{})) error` + + Starts a listener on the Configuration Provider for changes to the specified section of the custom configuration. When changes are received from the Configuration Provider the UpdateWritableFromRaw interface will be called on the custom configuration to apply the updates and then signal that the changes occurred via changedCallback. + +See the [Device MQTT Service](https://github.com/edgexfoundry/device-mqtt-go/tree/{{edgexversion}}) for an example of using the new Structured Custom Configuration capability. + +- [See here for defining the structured custom configuration](https://github.com/edgexfoundry/device-mqtt-go/blob/{{edgexversion}}/internal/driver/config.go#L21-L72) +- [See here for custom section on the configuration.yaml file](https://github.com/edgexfoundry/device-mqtt-go/blob/{{edgexversion}}/cmd/res/configuration.yaml#L28-L50) +- [See here for loading, validating and watching the configuration](https://github.com/edgexfoundry/device-mqtt-go/blob/{{edgexversion}}/internal/driver/driver.go#L53-L67) diff --git a/docs_src/microservices/device/sdk/details/CustomRestApis.md b/docs_src/microservices/device/sdk/details/CustomRestApis.md new file mode 100644 index 000000000..ceaa6abce --- /dev/null +++ b/docs_src/microservices/device/sdk/details/CustomRestApis.md @@ -0,0 +1,24 @@ +--- +title: Device Service - Custom REST APIs +--- + +# Device Service - Custom REST APIs + +You can customize your own REST APIs when building a Device Service but a few routes are reserved and cannot be used: + +- /api/{{api_version}}/version +- /api/{{api_version}}/ping +- /api/{{api_version}}/config +- /api/{{api_version}}/trigger +- /api/{{api_version}}/secret + +To add your own route, use the `AddCustomRoute()` API provided on the `DeviceService` interface. + +!!! example "Example - Add Custom REST route" + + ``` go + AddCustomRoute(route string, authentication Authentication, handler func(e echo.Context) error, methods ...string) error + ``` + +Under the hood, this simply adds the provided route, handler, and method to the `echo` router used in the SDK. For more information on `echo` you can check out the GitHub repo [here](https://github.com/labstack/echo). +You can access the `interfaces.DeviceService` API for resources such as the logging client by pulling it from the context as shown above -- this is useful for when your routes might not be defined in your `main.go` where you have access to the ``interfaces.DeviceService`` instance. diff --git a/docs_src/microservices/device/sdk/details/CustomServiceMetrics.md b/docs_src/microservices/device/sdk/details/CustomServiceMetrics.md new file mode 100644 index 000000000..3ce847e99 --- /dev/null +++ b/docs_src/microservices/device/sdk/details/CustomServiceMetrics.md @@ -0,0 +1,71 @@ +--- +title: Device Service - Go Device Services SDK Metrics +--- + +# Device Service - Go Device Services SDK Metrics + +### Built-In + +The following built-in device service metrics are collected by the Device SDK + +1. **EventSent** - Number of Events that have been sent from the Device Service +2. **ReadingsSent** - Number of Reading that have been sent from the Device Service +3. **Common Metrics** - Set of service metrics common to all EdgeX Services. See [Common Service Metrics](../../microservices/general/#common-service-metrics) for list of all these metrics. + +See [Device Service Configuration Properties](../../microservices/device/Ch-DeviceServices/#configuration-properties) for detail on configuring device service metrics + +### Custom + +The Custom Device Service Metrics capability allows for device service developers to define, collect and report their own service metrics beyond the common built-in service metrics supplied by the Device SDK. + +The following are the steps to collect and report service metrics: + +1. Determine the metric type that needs to be collected + - `counter` - Track the integer count of something + - `gauge` - Track the integer value of something + - `gaugeFloat64` - Track the float64 value of something + - `timer` - Track the time it takes to accomplish a task + - `histogram` - Track the integer value variance of something + +2. Create instance of the metric type from `github.com/rcrowley/go-metrics` + - `myCounter = gometrics.NewCounter()` + - `myGauge = gometrics.NewGauge()` + - `myGaugeFloat64 = gometrics.NewGaugeFloat64()` + - `myTimer = gometrics.NewTime()` + - `myHistogram = gometrics.NewHistogram(gometrics.NewUniformSample(