Project: Shifu (Provisioning / Automation & Configuration)
File: WOT_technical.md

This is done by writing a YAML file to describe the device and its capabilities. We'd like to switch our definition to TD defined in WoT. Currently, If the device supports public protocols, we can support it seamlessly with our framework. We currently support: MQTT, OPCUA, HTTP, Socket, TCP, Modbus, Simens s7 and all the protocl supported by plc4x (AB-Ethernet, ADS /AMS, BACnet/IP, CANopen, DeltaV, DF1, EtherNet/IP, Firmata, KNXnet/IP, Modbus, OPC-UA, S7) If the device only supports proprietary protocols, we would create a reusable driver for the device to abstract its capabilities and package it into a docker container, and then make the container a completely reusable digital twin called deviceShifu. Whenever you have a new project, you can just mix&match deviceShifu and configure it with the necessary parameters, just like how you play with lego blocks. An example for this scenario can be found : We first created a driver called which is a python webserver that works as the driver for the camera. We than build it into a docker image and put it as sidecar with our deviceshifuHTTP andd added necessary configs into our deployment.yaml like: ```yaml image: edgehub/camera-python:v0.0.1 name: camera-python ports: containerPort: 11112 volumeMounts: name: deviceshifu-config mountPath: "/etc/edgedevice/config" readOnly: true env: name: EDGEDEVICE_NAME value: "edgedevice-camera" name: EDGEDEVICE_NAMESPACE value: "devices" name: IPCAMERAADDRESS value: "192.168.14.254" name: IPCAMERAHTTP_PORT value: "" name: IPCAMERARTSP_PORT value: "" name: IPCAMERAUSERNAME value: "admin" name: IPCAMERAPASSWORD ``` so that users can use this integration with proprietary protocol as with standard `deviceshifuHttp`. Also, the driver can be reused for different projects with different configurations. We also have a GPT-Powered AI assistant called IOT Driver Copilot to help us create the driver, which can make our life easier. We think IOT Driver Copilot can be a great starting point to auto-genaerate reusable WOT-compliant device drivers. Our framework by default will retrieve raw data from the device. Depending on the application use case, user may need to write a driver and can use the help of IOT Driver Copilot to generate the driver and package it into a container. For the case that values from the device need to be processed/normalized, we have integrated a FaaS(function as a service) like service to let users handle the raw data the way they like, called customizedDeviceShifu. Users can write custom code to deal with the raw data and transform it to whatever data format they need. We have a detailed example : In the configmap, user can add a field called customInstructionsPython to specify the function defined in python to transform data. ```yaml customInstructionsPython: | humiditycustom: humidityraw_data ``` The corresponding will utilize this function to transform the raw data before returning it to the user. We do have a end to end test suites for all the existing interactions defined in our integrations. We also have a set of physical devices for testing if necessary. The setup of our e2e tests can be found . Before packaging the device driver into a deviceShifu, users would be responsible for making sure the device driver is working properly as they are the device owners. We are responsible for the general framework's correctness. This is the biggest strength of our offerings. Without our solution, applications are tightly coupled with devices, because they built device drivers into their applications. With our solution, we can abstract the device drivers into reusable components called deviceShifu and package them into docker

We then deploy the containers into kubernetes cluster and expose them as kubernetes services. Applications can then use the deviceShifu as a service and interact with the devices via the deviceShifu. The following diagrams show the difference between the two approaches: ```mermaid graph BT subgraph APP[Application] APPAL[Actual Logic] DDA[Device Driver A] DDB[Device Driver B] ... end DA[Device A] <--"device protocol"--> DDA DB[Device B] <--"device protocol"--> DDB ``` ```mermaid graph BT subgraph APP[Application] APPAL[Actual Logic] end subgraph Shifu[Shifu] direction LR SHIFUDDA[DeviceShifu A] SHIFUDDB[DeviceShifu B] ... end DA[Device A] <--"device protocol"--> SHIFUDDA DB[Device B] <--"device protocol"--> SHIFUDDB Shifu <--"HTTP/MQTT/OPCUA"--> APP ``` Where Shifu is a logical grouping of DeviceShifu, which can be treated as reusable lego blocks. ```mermaid graph BT subgraph DSA[DeviceShifu A] direction LR DSANBC[Northbound Connector] DSADD[Device Driver] DSANBC <--> DSADD end subgraph DSB[DeviceShifu B] direction LR DSBNBC[Northbound Connector] DSBDD[Device Driver] DSBNBC <--> DSBDD end A[Device A] <--"device protocol"--> DSADD B[Device B] <--"device protocol"--> DSBDD DSANBC <--"HTTP/MQTT/OPCUA"--> APP[Application, DB, etc] DSBNBC <--"HTTP/MQTT/OPCUA"--> APP ``` We do have a catalog or library of drivers we have done so far so we can reuse it for different scenarios. Also our framework is protocol based and vendor agnostic, so it can guarantee reusability in its best efforts. It can be observed from our CRD definition: ```go type ProtocolSettings struct { MQTTSetting *MQTTSetting `json:"MQTTSetting,omitempty"` OPCUASetting *OPCUASetting `json:"OPCUASetting,omitempty"` SocketSetting *SocketSetting `json:"SocketSetting,omitempty"` PLC4XSetting *PLC4XSetting `json:"PLC4XSetting,omitempty"` TCPSetting *TCPSetting `json:"TCPSetting,omitempty"` } // EdgeDeviceSpec defines the desired state of EdgeDevice type EdgeDeviceSpec struct { // INSERT ADDITIONAL SPEC FIELDS - desired state of EdgeDevice // Important: Run "make" to regenerate code after modifying this file // Sku specifies the EdgeDevice's SKU. Sku *string `json:"sku,omitempty"` Connection *Connection `json:"connection,omitempty"` Address *string `json:"address,omitempty"` Protocol *Protocol `json:"protocol,omitempty"` ProtocolSettings *ProtocolSettings `json:"protocolSettings,omitempty"` CustomMetadata *map[string]string `json:"customMetadata,omitempty"` // TODO: add other fields like disconnectTimemoutInSeconds } ``` Each EdegeDevice 's spec only contains settings for protocol, we then choose which protocol specific binary to run on our kubernetes deployment: ```yaml template: metadata: labels: app: deviceshifu-mqtt-deployment spec: containers: image: edgehub/deviceshifu-http-mqtt:nightly name: deviceshifu-http ports: containerPort: 8080 ``` The above example is how we run devices using MQTT protocol. The instructions for different use cases are dynamically configurable via configmaps, so for different scenarios, users can just put different instructions in the configmap. ```yaml instructions: | instructions: get_value: protocolPropertyList: OPCUANodeID: "ns=2;i=2" get_time: protocolPropertyList: OPCUANodeID: "i=2258" get_server: protocolPropertyList: OPCUANodeID: "i=2261" ``` For mor details on protocol abstractions can be found To make it clear, we provide the framework and tools for integration, but not the actual integration itself. Unless you hire us to implement the actual project. That's when we have access to the physical devices. Meanwhile, we also validate the integration by simulators and mocks if we don't have the physical device in our office. This contains all the mocks we have done so far. But we will try to test the integration against real device whenever we have the chance. To integrate devices of the same type, we have a feature called swarm mode. It is documented . To alias the instructions so the applicatio developer can always handle power consumption in kWh and use the same name for the datapoint in his/her code, we have a feature called instructionMap. . List Shifu to be one of the preferred WoT-compliant application development and device integration frameworks. Get some real world use cases ASAP. Figure out how we can coordinate our efforts and come up with a blueprint/best practice for building scalable AIoT solutions.