Cloud Service
To get the EMBER Cloud service, you need to have at least one EMBER Hotspot.
With this service, you get your own instance of ChirpStack and Node-RED accessible through the web management UI.
Access is secured by the HTTPS/TLSv1.3 protocol, and the user identity is created in the EMBER Cloud service by the HARDWARIO team during service setup.
You do not need any specialized software on your PC/mobile to manage the service. An up-to-date web browser is sufficient.
Web Management
The web management provides access to ChirpStack and Node-RED applications through the Teleport service.
HARDWARIO support team will create a user account.
The web management login URL: https://<customer identifier>-<service index>.ember.hardwario.cloud/
You have to replace <customer identifier> with your identification assigned by HARDWARIO (usually a company name).
You need one of those methods for multifactor authentication:
Google Authenticator or a compatible application on mobile
FIDO2 - universal 2nd factor (U2F) USB key (e.g., Security Key Series)
FIDO2 - universal 2nd Factor (U2F) passwordless (e.g., YubiKey Bio Series)
The services mentioned below are accessible through the Applications menu item. The services are identified by these abbreviations:
cs
- ChirpStack applicationnr
- Node-RED application
To access the specific service, click on the LAUNCH button.
ChirpStack LoRaWAN Server
The Teleport service will bring the user to the following URL:
https://ember-<customer identifier>-<service index>-cs.tp.hardwario.com/
These are the default login credentials:
Username:
admin
Password:
admin
You do need to change that because you are identified and authenticated by logging into the Teleport web user interface.
LoRaWAN Gateways
List of all EMBER Hotspots with the Last seen value and activity overview.
LoRaWAN Applications
In this section, the user can define the method to pass data from the LoRaWAN devices to LoRaWAN applications (which can be the user's endpoints).
Each application encapsulates a list of LoRaWAN devices (e.g. CHESTER).
You can check the LoRaWAN activity for any CHESTER device.
Every CHESTER device has to be registered in the Application section.
The recommended option is to use the ABP method (Activation By Personalization). For this method, the user will need to specify (or generate) the following parameters:
Device EUI - also referred to as
DevEUI
Network session key - also referred to as
NwkSKey
Application session key - also referred to as
AppSKey
In ChirpStack, The ABP method is used when the user does not enable the Device supports OTAA
checkbox under the specific device profile.
For security reasons, the ABP method is suitable for the LoRaWAN devices where reboots are not expected.
Node-RED Application
The Teleport service will bring the user to the following URL:
https://ember-<customer identifier>-<service index>-nr.tp.hardwario.com/
Data are passed from the LoRaWAN server to Node-RED by Mosquitto (the MQTT server). The MQTT server is provided by the EMBER Cloud service at localhost:1883
.
The uplink data are published using this topic:
application/+/device/+/event/up
The data processing flow in the Node-RED application starts with the MQTT message.
In Node-RED, use the mqtt client
node to subscribe to the above topic.
After the MQTT message is received, the device payload data needs to be decoded based on firmware used in the LoRaWAN device (e.g. CHESTER).
While it is possible to decode the payload in the ChirpStack directly, we recommend doing that later in Node-RED where the user has a full-featured Node.js library for binary buffer parsing and a more robust JavaScript interpreter with advanced debugging tools.
Below is the example of the Node-RED function (in JavaScript) for decoding the Base64 payload provided by ChirpStack in the MQTT message:
if (msg.payload.applicationName !== 'ember-application-chester-clime') {
return null;
}
if (typeof msg.payload.data === 'string') {
msg.payload.data = decode(Buffer.from(msg.payload.data, 'base64'));
}
return msg;
function decode(buffer) {
let data = {};
let offset = 0;
let header = buffer.readUInt8(0);
offset += 1;
if ((header & 0x01) !== 0) {
data.voltage_rest = buffer.readUInt16LE(offset);
offset += 2;
data.voltage_load = buffer.readUInt16LE(offset);
offset += 2;
data.current_load = buffer.readUInt8(offset);
offset += 1;
if (data.voltage_rest === 0xffff) {
data.voltage_rest = null;
} else {
data.voltage_rest = data.voltage_rest / 1000;
}
if (data.voltage_load === 0xffff) {
data.voltage_load = null;
} else {
data.voltage_load = data.voltage_load / 1000;
}
if (data.current_load === 0xff) {
data.current_load = null;
}
}
if ((header & 0x02) !== 0) {
data.orientation = buffer.readUInt8(offset);
offset += 1;
if (data.orientation === 0xff) {
data.orientation = null;
}
}
if ((header & 0x04) !== 0) {
data.therm_temperature = buffer.readInt16LE(offset);
offset += 2;
if (data.therm_temperature === 0x7fff) {
data.therm_temperature = null;
} else {
data.therm_temperature = data.therm_temperature / 100;
}
}
if ((header & 0x10) !== 0) {
data.hygro_temperature = buffer.readInt16LE(offset);
offset += 2;
data.hygro_humidity = buffer.readUInt8(offset);
offset += 1;
if (data.hygro_temperature === 0x7fff) {
data.hygro_temperature = null;
} else {
data.hygro_temperature = data.hygro_temperature / 100;
}
if (data.hygro_humidity === 0xff) {
data.hygro_humidity = null;
} else {
data.hygro_humidity = data.hygro_humidity / 2;
}
}
if ((header & 0x20) !== 0) {
data.w1_thermometers = [];
let count = buffer.readUInt8(offset);
offset += 1;
for (let i = 0; i < count; i++) {
let t = buffer.readInt16LE(offset);
offset += 2;
if (t === 0x7fff) {
t = null;
} else {
t = t / 100;
}
data.w1_thermometers.push(t);
}
}
if ((header & 0x40) !== 0) {
data.rtd_thermometers = [];
let count = buffer.readUInt8(offset);
offset += 1;
for (let i = 0; i < count; i++) {
let t = buffer.readInt16LE(offset);
offset += 2;
if (t === 0x7fff) {
t = null;
} else {
t = t / 100;
}
data.rtd_thermometers.push(t);
}
}
return data;
}
After decoding, you can further process the data - scalarizing, adding attributes, etc. The last action in the flow should be delivering the data through some common connector, e.g., an HTTPS request.
To tune and troubleshoot flow, you can use the debug
node and the console view in Node-RED.
Integration Examples
Data can be passed to any service via the Internet for processing - e.g., visualization, data storage, and integration with business applications.
Some common integration examples are:
REST API
Data streaming services:
Azure Event Hub
Azure IoT Hub
AWS IoT Core
...
Microsoft Power BI
Ubidots