Device updates to telemetry state
This guide describes the concept and syntax when a device to update changes of telemetry state to its Virtual Twin. When a device updates the telemetry state, the whole telemetry state schema will be sent to Neuko Cloud IoT platform and the platform will update the Virtual Twin and store the data in a timestream database.
The interval between data sends to the platform is based on device’s tier that being configured during creating telemetry state schema as in this guide. Within Neuko Device SDK, a looping called tick-tock
is running by the interval of the device tier. Table below shows the interval based on the tier.
Tier | Interval |
---|---|
S1 | Every 1 seconds |
S5 | Every 5 seconds |
S30 | Every 30 seconds |
M1 | Every 1 minute |
MP5 | Every 5 minutes |
This can be illustrated as below time progression – although the device keep measuring new data, only data available during tock will be sent to the platform.
To update the telemetry, the function updateState()
has to be invoked. However, by default, invoking this function would not immediately send the data to the platform. Neuko Device SDK has a local variable that will change whenever the function is invoked. When the loop tick-tock reach the interval, the SDK will copy the variable and send to the platform.
Syntax to update telemetry state
Below telemetry state schema with a state name of smart_plug_state will be used throughout this guide.
{ "electricity": { "power": 0, "votage": 0 }, "switch": { "toggle": false, "led": { "front": false, "back": true } } }
Code below shows several examples when device updates the attributes of power and voltage.
import { Device, DeviceIdentifier, DeviceIdentifierStore, CertificateStore, ConnectionStore } from "@neukolabs/device-sdk-js"; import { readFileSync, writeFileSync, unlinkSync, existsSync } from 'fs'; import path from 'path'; class deviceIdentifier extends DeviceIdentifierStore { // ... some content inside } class deviceCertificate extends CertificateStore { // ... some content inside } class deviceConnection extends ConnectionStore { // ... some content inside } async function main() { const device: Device = new Device(); device.identifierStore = new deviceIdentifier(); device.connectionStore = new deviceConnection(); device.certificateStore = new deviceCertificate(); // start the device await device.start(); // example 1 - to update instantenously a telemetry state's attribute let voltage = some_hardware_func_to_read_voltage(); await device.updateState("smart_plug_state", { "electricity": { "voltage": voltage } }); // example 2 - looping to update telemetry state's attributes setInterval(async () => { const power = some_hardware_func_to_read_power(); const volt = some_hardware_func_to_read_voltage(); await device.updateState("smart_plug_state", { "electricity": { "power": power "voltage": volt } }); }, 1000); }
import sys import asyncio import concurrent.futures from threading import Thread from time import sleep from neuko.device.identifierStore import DeviceIdentifierStore from neuko.connection.certificateStore import CertificateStore from neuko.connection.connectionStore import ConnectionStore from neuko.device.model import DeviceIdentifier, TelemetricStateChangeParameter from neuko.device.device import Device, DeviceState class deviceIdentifier(DeviceIdentifierStore): # ... some content here class deviceCertificate(CertificateStore): # ... some content here class deviceConnection(ConnectionStore): # ... some content here class MyDevice: def __init__(self) -> None: self.device = None self.RUNNING = False self._ready = False # Example - Measure and send update telemetry state def measure_electricty(self): volt = some_hardware_func_to_measure_volt() power = some_hardware_func_to_measure_power() self.device.updateTelemetricState("smart_plug_state", { "electricity": { "power": power "voltage": volt } }) # set interval def setInterval(period, callback, *args): Thread(target=call_at_interval, args=(period, callback, args)).start() # Call at interval def call_at_interval(period, callback, args): while True: sleep(period) callback(*args) def init(self): self.device = Device(deviceIdentifier(), deviceConnection(), deviceCertificate()) self.device.start_threadsafe() # looping, measure and update telemetry state self.setInterval(10, measure_electricty, None) async def start(self): self.RUNNING = True while self.RUNNING: if (self._ready == False): if (self.gateway.state == DeviceState.READY): self._ready = True self._initalizeDevices() else: # example 1 - to update instantenously a telemetry state's attribute volt = some_hardware_func_to_measure_volt() self.device.updateTelemetricState("smart_plug_state", { "electricity": { "voltage": volt } }) await asyncio.sleep(1) async def forever(): mydevice = MyDevice() mydevice.init() await mydevice.start() def main(): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) loop.run_until_complete(forever()) if __name__ == "__main__": main()
Force upload telemetry state to Neuko IoT
Neuko Device SDK provides flexibility for a use case that needs to update and upload the data to the platform although before the tock event.
This is especially important for a sensor-type of device that the “measured” event happens randomly. This can be achieved by passing a true boolean at the 3rd argument of updateState()
function.
As a side note, for a sensor device, Neuko encourages the device to be associated with tier MP5. The random event of sensing can use this method to force upload the telemetry state data.
// pass a true at the 3rd argument await device.updateState("smart_plug_state", { "electricity": { "voltage": voltage } }, true);
# pass a True at the 3rd argument self.device.updateTelemetricState("smart_plug_state", { "electricity": { "voltage": volt } }, True)