Project: Shifu (Provisioning / Automation & Configuration)
File: design-customized-deviceshifu.md

Customizing deviceShifu will enable deviceShifu to handle customized logic such as parsing data from devices. ```mermaid sequenceDiagram participant id as IoT device participant cd as customized deviceShifu id->>cd: raw data cd->>cd: parse raw data via handler function cd->>application: parsed data ``` Anything between `raw data` and `app-friendly data` are components in `deviceShifu`: ```mermaid flowchart LR IoT-device --> |raw data|deviceShifu-data-adapter-->deviceShifu-data-handler-->deviceShifu-data-sender-->|app-friendly data|application ``` Examples: `raw data` provided by IoT device: ``` root@nginx:/# curl http://deviceshifu-test.deviceshifu.svc.cluster.local/18000851;echo ``` ```json { "statusCode": "200", "message":"success", "entity":[{ "deviceId":"20990922009", "datatime":"2022-06-30 07:55:51", "eUnit":"", "eValue":"37", "eKey":"e3", "eName":"atmosphere temperature", "eNum":"101" }, { "deviceId":"20990922009", "datatime":"2022-06-30 07:55:51", "eUnit":"%RH", "eValue":"88", "eKey":"e4", "eName":"atmosphere humidity", "eNum":"102" }] } ``` `parsed data` required by application: ```json { [{ "code":"20990922009", "name":"atmosphere temperature", "val":"37", "unit":"", "exception":"temperature is too high" }, { "code":"20990922009", "name":"atmosphere humidity", "val":"88", "unit":"", "exception":"humidity is too high" }] } ``` ```mermaid flowchart LR subgraph devgd[develop general deviceShifu] wdyf[Write deviceShifu yaml files]-->dd[deploy general deviceShifu] dd-->tdc[test device connection] end subgraph devcd[develop customized deviceShifu] idhf[implement deviceShifu handler functions] idhf-->tdhf[test deviceShifu handler functions] tdhf-->bcde[build customized deviceShifu executable] bcde-->bcdi[build customized deviceShifu image] bcdi-->dcd[deploy customized deviceShifu] dcd-->tcd[test customized deviceShifu] end devgd-->devcd ``` By default, `deviceShifu` will provide raw data from physical device to the applications. To make `deviceShifu` able to "translate" the raw data to a more application-friendly format as well as filter out unneeded data, we can provide customized handlers to `deviceShifu`. For example, using Python, we add customized handlers like this: in `deviceshifu/pythoncustomizedhandlers/customized_handlers.py`, add a new function with the function name being instruction name. make sure the function takes a string (rawdata) and returns a string (processeddata which app-friendly). By default, `deviceShifu` will use the default command handler to process the data of each instruction, and calling the endpoint of the instruction will give a response of raw data from device. If user registers the custom handler, `deviceShifu` will switch to use the custom handler for that instruction. As a result, a call to the endpoint of that instruction will respond the processed data instead of raw data. As for error handling, we expect the `deviceShifu` to log out an error on a handler failure. customized_handlers.py\ We add a function to process data from instruction ```humidity```: ```python def humidity(raw_data): new_data = [] entities = raw_data["entity"] for i in range(len(entities)): newdataentry = {"code": entities, "name": entities, "val": entities, "unit": entities, "exception": checkregularmeasurement_exception(entities, entities)} newdata.append(newdata_entry) return new_data ``` and we can have helper and constants here like this: ```python TEMPERATURE_MEASUREMENT = "atmosphere temperature" HUMIDITY_MEASUREMENT = "atmosphere humidity" def checkregularmeasurementexception(measurementname, measurement_value): exception_message = "" if measurementname == TEMPERATUREMEASUREMENT: if int(measurement_value) > 35: exception_message = "temperature is too high" elif measurementname == HUMIDITYMEASUREMENT: if int(measurement_value) > 60: exception_message = "humidity is too high" return exception_message ``` `deviceShifu`'s handling of data contains 4 components: data-adapter, data-handler, data-provider, data-cache: data-adapter is responsible for receiving data from physical device. `deviceShifu` loads the driver and enables the data flow from physical device to data-adapter. data-handler has custom-implemented handlers that process the data in action, handler function is invoked every time new data comes. data-provider is the portal for actively sending data to applications or for applications to ask for data. data-cache is cutsomizable to store data used very frequently.