Settings schema
Settings schema is a specification of the form that will be displayed for the module on the device configuration page. Grid modules define settings schema as a data structure in TypeScript file supplemented with doxygen-style annotations for each field of this data structure.
Here is an example:
export type Settings = { enabled: false; } | { /** * @title Enabled * @default false */ enabled: true; /** * @title Some variable * @default “some-value” */ some_variable: string; };
Note the conditional type here. In this example an instance of type Settings
may have one of 2 interfaces: either enabled
field has a value of false
, or it is true
and then some_variable
field is required. When a settings form is rendered that would mean that some_variable
field will be hidden, unless enabled
field has a value of true
(it will be rendered as a checkbox, so the checkbox must be checked).
All fields in this data structure are mandatory, the form will display an error if some fields are empty. To make any field optional, use standard TypeScript syntax:
some_optional_field?: string;
Naturally, if a @title
annotation is missing, the field will be displayed with the same title as field name.
Fields can have various types: booleans will be rendered as checkboxes, strings and numbers will be rendered as regular input fields. Objects and arrays will be rendered as form elements, but currently their values are not passed to the module.
Settings values are passed to the module as environment variables, each variable name is capitalised and an (also capitalised) module name prefix is added before it: value of some_variable
for MyAwesomeModule
module will be visible to the module as MYAWESOMEMODULE_SOME_VARIABLE
. Note that due to the nature of environment variables, values of type number
will have type string
when accessed from inside of the module.
When any value is changed in module settings, the module will be restarted.
Javascript modules can use gridos.js
helper file to acquire variable values:
const some_var = module.getSetting('some_var');
Settings values are currently not available in module twin.
Module-to-app communication
A module is able to send messages to an application by invoking an RPC call on GdmAgent
module. Reference implementation in JS:
await client.invokeMethod(process.env.IOTEDGE_DEVICEID, 'GdmAgent', { methodName: 'broadcast', payload: { type: ‘Test.Message’, some: ‘data’ }, });
A broadcast
method of GdmAgent
module should be invoked, payload
should be an object with a type
field, a string
specifying message type, and any number of additional data fields.
Also a gridos.js
helper library can be used for node.js based modules:
const gridos = require(‘./gridos’); ... const client = await gridos.connect(); ... client.broadcast({ type: 'Test.Message', some: 'data' });
Receiving messages in the app
From the app side, @ombori/ga-messaging
library should be used. Reference implementation:
import { useSubscribe } from ‘@ombori/ga-messaging’; const App = () => { ... const {count, setCount} = useState(0); const useSubscribe('Test.Message', (msg) => { setCount(ct => ct + 1); }, [setCount]); return <div>Received {count} messages</div> };
App-to-module communication
To send messages from app to a module, use @ombori/ga-messaging
library. Example:
import { usePublish } from ‘@ombori/ga-messaging’; const App = () => { ... const publish = usePublish(); const onClick = useCallback(() => { publish({type: ‘Hello.There’, some: ‘data here’}); }, [broadcast]); return <button onClick={onClick} /> };
Receiving messages in the module
A module is receiving messages via an inbound RPC call of broadcast
method. Reference implementation:
client.onMethod(broadcast => (req, res) => { try { const data = req.payload; swtch(data.type) { case 'Hello.There': console.log('a hello event is received', data); break; } res.send(200, 'ok'); } catch (e) { res.send(500, e.toString()) } })
Nodejs-based modules can use gridos
library instead:
const gridos = require('./gridos'); ... const client = await gridos.connect(); ... client.onEvent('Hello.There', (data) => { console.log('a hello event is received', data); });