diff --git a/README.md b/README.md index 2a793bf..76aa7c4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,39 @@ -# Device Controller +# Yurt-device-controller -This repository contains the device-controller that leverages EdgeX Foundry to manage edge devices. +This repository contains three CRD/controllers, Device, DeviceService and DeviceProfile: + +- The `DeviceProfile` defines a type of devices using same kind of protocol, which includes some generic information like the manufacturer's name, the device description, and the device model. DeviceProfile also defines what kind of resources (e.g., temperature, humidity) this type of device provided and how to read/write these resources. + +- The `DeviceService` defines the way of how to connect a device to the OpenYurt, like the URL of the device. The `DeviceService` can not exist alone. Every `DeviceService` must associate with a `DeviceProfile`. + +- The `Device` is used to refer to a sensor, actuator, or IoT "thing", it gives the detailed definition of a specific device, like which `DeviceProfile` it belongs to and which `DeviceService` it used to connect to the system. + +For details of the design, please see the [document](https://github.com/openyurtio/openyurt/blob/master/docs/proposals/20210310-edge-device-management.md). + +## Getting Start + +To use the yurt-device-controller, you need to deploy the OpenYurt cluster in advance and meet the following two conditions: + +- Deploy the yurt-app-manager; +- Deploy an Edgex Foundry instance in a NodePool by using yurt-edgex-manager; + +For a complete example, please check out the [tutorial](docs/yurt-device-controller-tutorial.md) + +## Contributing + +Contributions are welcome, whether by creating new issues or pull requests. See our [contributing document](https://github.com/openyurtio/openyurt/blob/master/CONTRIBUTING.md) to get started. + +## Contact + +- Mailing List: openyurt@googlegroups.com +- Slack: [channel](https://join.slack.com/t/openyurt/shared_invite/zt-iw2lvjzm-MxLcBHWm01y1t2fiTD15Gw) +- Dingtalk Group (钉钉讨论群) + +
+ +
+ + +## License + +Yurt-device-controller is under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details. Certain implementations in Yurt-device-controller rely on the existing code from [Kubernetes](https://github.com/kubernetes/kubernetes) and [OpenKruise](https://github.com/openkruise/kruise) the credits go to the original authors. \ No newline at end of file diff --git a/docs/yurt-device-controller-tutorial.md b/docs/yurt-device-controller-tutorial.md new file mode 100644 index 0000000..b57c65f --- /dev/null +++ b/docs/yurt-device-controller-tutorial.md @@ -0,0 +1,481 @@ +# Yurt-device-controller Tutorial + +This document introduces how to install yurt-device-controller and use yurt-device-controller to manage edge devices on edgex foundry. Suppose you have an OpenYurt cluster, and already have one edgex foundry instance in a NodePool. + +## Environment + +1. For details on setting up an OpenYurt cluster, please check out the [tutorial](https://github.com/openyurtio/openyurt#getting-started) ; + +2. For details on deploying Yurt-app-Manager, please check out the [tutorial](https://github.com/openyurtio/yurt-app-manager/blob/master/docs/yurt-app-manager-tutorial.md) ; + +3. For details on deploying the Edgex Foundry instance using yurt-edgex-manager, please check out the [tutorial](https://github.com/openyurtio/yurt-edgex-manager/blob/main/README.md) . + +## Install yurt-device-controller + +Suppose you have an OpenYurt cluster, a nodePool, and deployed an Edgex Foundry Instance on that node pool. + +### Install the related CRDs + +```bash +$ cd yurt-device-controller +$ kubectl apply -f config/setup/crd.yaml +``` + +### Deploy yurt-device-controller by using unitedDeployment + +The following unitedDeployment example deploy a yurt-device-controller in hangzhou nodePool: + +```bash +$ cat < + API Version: device.openyurt.io/v1alpha1 + Kind: Device + Metadata: + Creation Timestamp: 2021-09-22T06:03:04Z + Finalizers: + v1alpha1.device.finalizer + # ...... + # ...... + Spec: + Admin State: UNLOCKED + Description: Example of Device Virtual + Labels: + device-virtual-example + Managed: false + Node Pool: hangzhou + Operating State: ENABLED + Profile: Random-Boolean-Device + Protocols: + Other: + Address: device-virtual-bool-01 + Port: 300 + Service: device-virtual + Status: + Admin State: UNLOCKED + Conditions: + Last Transition Time: 2021-09-23T05:36:29Z + Reason: this device is not managed by openyurt + Severity: Info + Status: False + Type: Ready + Last Transition Time: 2021-09-23T05:36:29Z + Reason: this device is not managed by openyurt + Severity: Info + Status: False + Type: DeviceManaging + Last Transition Time: 2021-09-22T06:03:05Z + Status: True + Type: DeviceSynced + Device Properties: + Bool: + Actual Value: true + Get URL: http://edgex-core-command:48082/api/v1/device/07b0d343-cc07-43ff-afb1-6a2792d48b7f/command/7369b8b1-6772-420b-93d2-b3cedef9c50b + Name: Bool + Bool Array: + Actual Value: [false,false,false,false,false] + Get URL: http://edgex-core-command:48082/api/v1/device/07b0d343-cc07-43ff-afb1-6a2792d48b7f/command/e1756728-8f8d-444d-a9a0-f3168a294923 + Name: BoolArray + Edge Id: 07b0d343-cc07-43ff-afb1-6a2792d48b7f + Operating State: ENABLED + Synced: true + Events: + ``` + + + +2. Set the `managed` field of device to `true` + + The `Device.Spec.Managed` field determines whether the cloud can set the property value of the edge device. The cloud can successfully set device properties only if `managed=true`: + + ```bash + $ kubectl patch devices.device.openyurt.io hangzhou-random-boolean-device -p '{"spec":{"managed":true}}' --type=merge + ``` + + The device status after field `managed` is set to `true`: + + ```yaml + Status: + Admin State: UNLOCKED + Conditions: + Last Transition Time: 2021-09-23T06:09:22Z + Status: True + Type: Ready + Last Transition Time: 2021-09-23T06:09:22Z + Status: True + Type: DeviceManaging + Last Transition Time: 2021-09-22T06:03:05Z + Status: True + Type: DeviceSynced + Device Properties: + Bool: + Actual Value: true + Get URL: http://edgex-core-command:48082/api/v1/device/07b0d343-cc07-43ff-afb1-6a2792d48b7f/command/7369b8b1-6772-420b-93d2-b3cedef9c50b + Name: Bool + Bool Array: + Actual Value: [false,true,false,true,true] + Get URL: http://edgex-core-command:48082/api/v1/device/07b0d343-cc07-43ff-afb1-6a2792d48b7f/command/e1756728-8f8d-444d-a9a0-f3168a294923 + Name: BoolArray + Edge Id: 07b0d343-cc07-43ff-afb1-6a2792d48b7f + Operating State: ENABLED + Synced: true + Events: + ``` + +3. Change the `adminState` of device + + > The administrative state (aka admin state) provides control of the device service by man or other systems. It can be set to LOCKED or UNLOCKED. When a device service is set to locked, it is not suppose to respond to any command requests nor send data from the devices. + + ```bash + $ kubectl patch devices.device.openyurt.io hangzhou-random-boolean-device -p '{"spec":{"adminState":"LOCKED"}}' --type=merge + ``` + + The device status after field `adminState` is set to `LOCKED`: + + ```yaml + Status: + Admin State: LOCKED + Conditions: + Last Transition Time: 2021-09-23T06:09:22Z + Status: True + Type: Ready + Last Transition Time: 2021-09-23T06:09:22Z + Status: True + Type: DeviceManaging + Last Transition Time: 2021-09-22T06:03:05Z + Status: True + Type: DeviceSynced + Device Properties: + Bool: + Actual Value: + Get URL: http://edgex-core-command:48082/api/v1/device/07b0d343-cc07-43ff-afb1-6a2792d48b7f/command/c09f856a-36cf-4d95-a352-e42cf8d451dc + Name: Bool + Bool Array: + Actual Value: + Get URL: http://edgex-core-command:48082/api/v1/device/07b0d343-cc07-43ff-afb1-6a2792d48b7f/command/49618976-19ce-4084-84ea-90428d57c547 + Name: BoolArray + Edge Id: 07b0d343-cc07-43ff-afb1-6a2792d48b7f + Operating State: ENABLED + Synced: true + ``` + + + +4. Change the `operatingState` of device + + > The operating state (aka op state) provides an indication on the part of EdgeX about the internal operating status of the device service. The operating state is not set externally (as by another system or man), it is a signal from within EdgeX (and potentially the device service itself) about the condition of the service. The operating state of the device service may be either enabled or disabled. When the operating state of the device service is disabled, it is either experiencing some difficulty or going through some process (for example an upgrade) which does not allow it to function in its normal capacity. + + ```bash + $ kubectl patch devices.device.openyurt.io hangzhou-random-boolean-device -p '{"spec":{"operatingState":"DISABLED"}}' --type=merge + ``` + + The device status after field `operatingState` is set to `DISABLED`: + + ```yaml + Status: + Admin State: UNLOCKED + Conditions: + Last Transition Time: 2021-09-23T06:09:22Z + Status: True + Type: Ready + Last Transition Time: 2021-09-23T06:09:22Z + Status: True + Type: DeviceManaging + Last Transition Time: 2021-09-22T06:03:05Z + Status: True + Type: DeviceSynced + Edge Id: 07b0d343-cc07-43ff-afb1-6a2792d48b7f + Operating State: DISABLED + Synced: true + ``` + + + +5. Set the deviceProperties + + ```bash + # Ensure adminState = UNLOCKED + $ kubectl patch devices.device.openyurt.io hangzhou-random-boolean-device -p '{"spec":{"adminState":"UNLOCKED"}}' --type=merge + + # Ensure operatingState = ENABLED + $ kubectl patch devices.device.openyurt.io hangzhou-random-boolean-device -p '{"spec":{"operatingState":"ENABLED"}}' --type=merge + ``` + + Because the `putURL` of random-boolean-device's bool property may change after `adminState` or `operingState` is changed. Therefore, you need to query the deviceProperty status again to obtain the latest `putURL`: + + ```bash + $ kubectl describe device hangzhou-random-boolean-device + ``` + + The status is : + + ```yaml + # .... + Status: + Admin State: UNLOCKED + Conditions: + Last Transition Time: 2021-09-23T06:24:02Z + Status: True + Type: Ready + Last Transition Time: 2021-09-23T06:24:02Z + Status: True + Type: DeviceManaging + Last Transition Time: 2021-09-22T06:03:05Z + Status: True + Type: DeviceSynced + Device Properties: + Bool: + Actual Value: true + Get URL: http://edgex-core-command:48082/api/v1/device/07b0d343-cc07-43ff-afb1-6a2792d48b7f/command/9a61a8d5-7c15-4d1b-b552-15b7879d9fc8 + Name: Bool + Bool Array: + Actual Value: [true,false,true,true,true] + Get URL: http://edgex-core-command:48082/api/v1/device/07b0d343-cc07-43ff-afb1-6a2792d48b7f/command/5407cb4f-0f99-47dc-8cce-3fd39cedaddf + Name: BoolArray + Edge Id: 07b0d343-cc07-43ff-afb1-6a2792d48b7f + Operating State: ENABLED + Synced: true + ``` + + Set the `Bool` property of the device to ` false`: + + ```bash + $ kubectl patch devices.device.openyurt.io hangzhou-random-boolean-device --type=merge -p '{ + "spec":{ + "deviceProperties":{ + "Bool":{ + "desiredValue":"false", + "name":"Bool", + "putURL":"http://edgex-core-command:48082/api/v1/device/07b0d343-cc07-43ff-afb1-6a2792d48b7f/command/9a61a8d5-7c15-4d1b-b552-15b7879d9fc8" + } + } + } + }' + ``` + + Check the status of deviceProperties in the Edgex Foundry: + + ```bash + $ kubectl get service | grep edgex-core-command + edgex-core-command NodePort 10.96.39.34 48082:30082/TCP 39h + + $ curl http://10.96.39.34:48082/api/v1/device/07b0d343-cc07-43ff-afb1-6a2792d48b7f/command/9a61a8d5-7c15-4d1b-b552-15b7879d9fc8 + {"device":"random-boolean-device","origin":1632378327952106491,"readings":[{"origin":1632378327951971484,"device":"random-boolean-device","name":"Bool","value":"false","valueType":"Bool"}],"EncodedEvent":null} + ``` +