Best Practices for Kelvin SmartApp™ Developers
When starting to develop Kelvin SmartApps™ for the Kelvin platform, it is important even in the pilot project stage to structure your program and environment correctly.
By following these best practices, you will be able to easily scale your Kelvin SmartApp™ while maintaining cost-effective infrastructure and maintenance routines.
Software Design
Asynchronous Code
Programs can leverage concurrency in many ways, the easiest of which may be utilizing coroutines and asyncio. These allow portions of code to be written as asynchronous routines which Python will execute through a form of cooperative multitasking. This allows code, especially that which typically waits such as I/O-bound operations, to effectively execute in parallel thereby making the most efficient use of processor time.
Here is an example of an asynchronous program demonstrating three routines which are run in parallel, each for 1 second, but with total execution time of only 1 second:
import asyncio
import time
async def dwell(duration=1.0):
await asyncio.sleep(duration)
return duration
async def main():
return await asyncio.gather(*[dwell() for _ in range(3)])
start_time = time.time()
times = asyncio.run(main())
print(f"Tasks total time: {sum(times):.1f}")
print(f"Wall time: {time.time() - start_time:.1f}")
Combined time: 3.0 Wall time: 1.0
Subscription vs Polling
Some protocols such as OPC-UA can be configured for subscription-based readings which are much more efficient than polling mechanisms. With a subscription, a one-time request for values from the endpoint will result in values being published to Kelvin SmartApps™ only when they change. This reduces loan on both systems and facilitates an event-driven design where Kelvin SmartApps™ can respond to only those changes.
Some Kelvin Connectors such as OPC-UA and MQTT offer subscription-based readings whereas some like Modbus only support polling.
Event-Driven Design
Rather than running a process or function at a regular interval which might waste processing on unchanged readings, for instance, Kelvin SmartApps™ should use features such as queues or socket.select() to execute code when new data is available.
An example of this is Kelvin SmartApps™ watching for new datastream readings and performing processing upon receipt of a new metric value.
Logging
Implementing logging within Kelvin SmartApps™ can greatly improve Kelvin SmartApps™ testing process as well as facilitate troubleshooting when there is an issue. Especially when implemented using available severity levels (DEBUG, INFO, WARNING, ERROR, CRITICAL), thorough log messages can help a developer or engineer find and focus on the information that is pertinent.
Logging verbosity can be adjusted, even at run-time, using a Kelvin Asset Parameter. Kelvin SmartApps™ designer can include a custom Asset Parameter with, say, multiple log levels pre-defined. When a user changes the parameter in the UI, it is synchronized to Kelvin SmartApps™ which can respond and adjust the log level accordingly.
Open vs Closed Loop Control
Kelvin Recommendations are used by Kelvin SmartApps™ to suggest control changes and other outputs which are applied to a system. Recommendations can be open-loop where a user is required to accept the changes in the UI, or they can be closed-loop with the changes being automatically applied. When combined with a Kelvin Asset Parameter to control the mode of operation, Kelvin SmartApps™ can afford the user the ability to selectively decide when to have recommendations applied automatically based on e.g. operating conditions or trust in Kelvin SmartApps™ performance.
Deployments
Workload Resources
Workloads are run within a container with separate compute resources, CPU and memory, allocated to each container. How much of each resource is reserved or restricted for a given Kelvin SmartApps™ is determined by the Requests and Limits respectively, which can be defined for each Kelvin SmartApps™.
Proper adjustment of these settings can provide safeguards for Kelvin SmartApps™ operation while optimizing the number of workloads deployed to a machine. Cluster Telemetry and Workload Telemetry can be used to profile the resource performance of the cluster and Kelvin SmartApps™, respectively, in order to apply the optimal settings.
Requests
A resource request is a reservation of that resource within the cluster and is used by the system for allocating workloads to available cluster nodes. When a resource for a node has been fully reserved, no additional workloads can be allocated to that node.
Limits
A resource limit is a restriction on how much of a node’s resource is available to a workload. A resource for a node is allowed to be over-allocated with respect to the total limits from all workloads but, in the case that actual available resources are exhausted, workloads will be subject to repercussions which depend on the resource type.
Memory
Memory is a finite resource available on the machine that runs containers. When it is exhausted for Kelvin SmartApps™, Kelvin SmartApps™ is likely to experience unrecoverable errors unless it was purposefully built to handle that scenario through optimistic allocation.
CPU
CPU, or processor, is a “compressible” resource in that it can never truly be exhausted. The multitasking performed by the OS will always yield some time for Kelvin SmartApps™ to execute with a potential penalty in performance if the processor is fully utilized.
Asset to Workload Assignment
It is very easy to write a program that handles data from an asset and then deploy this as a workload. But, because compute resources are associated to each workload, scaling Kelvin SmartApps™ to many assets can dramatically increase the processor and memory requirements of the solution.
Kelvin allows multiple assets to be deployed to a single workload which reduces resource requirements by allowing one Kelvin SmartApps™ to handle data and processing for many assets without the overhead of individual workloads. Kelvin SmartApps™ is made aware of the assets that it are assigned to it, and it is free to determine how best to handle them. This can allow Kelvin SmartApps™ to process assets in sequence or in parallel, or to avoid processing an asset altogether if it is not in an appropriate state.
Secrets
While not a performance consideration, the usage of Kelvin’s secret management system can facilitate a more secure deployment for Kelvin SmartApps™. Examples of secrets are an API authentication key for AWS or a password used to connect to an MQTT server. Once created, a secret can only be replaced or deleted but cannot be viewed by any users.
Secrets are defined globally in the cloud environment and then embedded into Kelvin SmartApps™ configuration using tokens. When deployed, the token is replaced by the system with the actual value where Kelvin SmartApps™ can utilize it at run-time.