Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


Typ: LOB-S-HYB-1WIRE

Image Added

 

Image Modified

Order
Codes
Numbers/Variants
8000170: Default Variant
:
8000186 - Multi Temperatur Box v2 (LoRaWAN, NB-IoT, RJ45)

8000170 - Multi Temperatur V2 (LoRaWAN, NB-IoT, 1m Temp.-Fühler)

Compatible Replacement for old articles:

    • 8000001 - LoRaWAN Multi Temperatur Box (Kabeldurchführung,
8000072, 8000094

Quickstart

    • AA-Batterien)
    • 8000072 - LoRaWAN Multi Temperatur Box (XH Batterieanschluss, IP66 Gehäuse, DAE, 1m Temp.-Fühler)
    • 8000094 - NB-IoT Multi Temperatur Box (XH Batterieanschluss, IP66 Gehäuse, DAE, 1m Temp.-Fühler)


Table of Contents

Table of Contents

Quickstart


Image Modified


  1. Connect to the device with the Lobaro Tool using the Lobaro Config Adapter
  2. Under Configuration click "Reload Config" and change the configuration according to your needs
  3. Register the device in your LoRaWAN network
  4. Connect D-cell Battery via XH connector

Key Features

  • (tick) Supports up to 20 DS18x20 1-Wire sensors
  • (tick) 8-Port easy installation Hub available
  • (tick) IP67 outdoor housing with pressure compensating element
  • (tick) Comes with one sensor attached
  • (tick) Sensor output order can be configured
  • (tick) Testmode for easy sensor identification
  • (tick) Big 19Ah size "D" battery for 10 years+ possible battery lifetime (not included)
  • (tick) LoRaWAN 1.0.x and 1.1 network servers supported
  • (tick) LoRaWAN Class A
  • (tick) LoRaWAN time synchronisation
  • (tick) Variant with external power-supply and or external antenna available on request
  • (tick) Quick closing screws with cover retainer on housing

Target Measurement / Purpose

The Multi Temperature Sensor Box is used to read out up to up to 25 DS18x20 1-Wire temperature sensors. The temperature from all sensors is read regualarly and sent via LoRaWAN uplink automatically splitting the data into multiple uplinks if the payload gets too big for a single LoRaWAN message. Sensors can be attached in series or in star configuration.

Additional Hardware

1-Wire 8-Port Hub (Clamp System)

For easy connection of up to 7 DS18x20 1-Wire sensors consider using our Modbus & 1-Wire 8-Port Hub (Order number: 8000130). Multiple Hubs can be connected to each other to achieve the limit of 25 sensors per Box.

Panel
 


Image Modified

Image Modified

Configuration

The configuration is done using Lobaro Maintenance Tool and the Lobaro USB PC adapter.

Networking Parameters (NB-IoT / LoRaWAN)

NameDescriptionDefault ValueValue Description & ExamplesWANRadio technology used for connection to backendlte
  • lte: use either cellular NB-IoT or LTE-M
  • nbiot: use cellular NB-IoT
  • ltem: use cellular LTE-M
  • lorawan: use LoRaWAN with OTAA
  • lorawan-abp: use LoRaWAN with ABP
Host

Hostname / IP of the Lobaro Platform API

Not used for LoRaWAN uplink

94.130.20.3794.130.20.37 = platform.lobaro.com (warning) DNS is not supported yet

Order Numbers/Variants:

  • 8000130 HUB IP66 (8x: 1-Wire or Modbus)


 

1-Wire 8-Port Hub (RJ45) System

Image Added

Image Added

Order Numbers/Variants:

1-wire DS18B20 Temp. sensor RJ45 (3m cable)
  • 3000793 1-Wire Hub 8x RJ45
  • 3000784 - DS18B20 Temp.-Sensor RJ45

Pinout (Front-side)

Image Added


Pin 2: 3V3 provided by Lobaro Box

Pin 4: 1-Wire Data

Pin 5: 1-Wire GND

Configuration

The configuration is done using Lobaro Maintenance Tool and the Lobaro USB PC adapter.

Networking Parameters (NB-IoT / LoRaWAN)

NameDescriptionDefault ValueValue Description & Examples
WANRadio technology used for connection to backendlte
  • lte: use either cellular NB-IoT or LTE-M
  • nbiot: use cellular NB-IoT
  • ltem: use cellular LTE-M
  • lorawan: use LoRaWAN with OTAA
  • lorawan-abp: use LoRaWAN with ABP
Host

Hostname / IP of the Lobaro Platform API

Not used for LoRaWAN uplink

94.130.20.3794.130.20.37 = platform.lobaro.com (warning) DNS is not supported yet
Port

Port number of the Lobaro Platform API

Not used for LoRaWAN uplink

5683

NB-IoT Parameters (WAN = "lte", "nbiot", "ltem")

The LTE functionality is enabled if the WAN parameter is set to lte, nbiot, or ltem. Using this mode requires an appropriate SIM-Card to be inserted.

NameDescriptionDefault ValueValue Description & Examples
OperatorMobile Operator Code (optional)2620126201 (=Deutsche Telekom), for other operators, see above.
BandNB-IoT Band8"8", "20", "8,20", Empty = Auto detect (longer connecting time)
APNMobile operator APN (optional)iot.1nce.net

1nce

Port

Port number of the Lobaro Platform API

Not used for LoRaWAN uplink

5683

NB-IoT Parameters (WAN = "lte", "nbiot", "ltem")

The LTE functionality is enabled if the WAN parameter is set to lte, nbiot, or ltem. Using this mode requires an appropriate SIM-Card to be inserted.

NameDescriptionDefault ValueValue Description & ExamplesOperatorMobile Operator Code (optional)2620126201 (=Deutsche Telekom), for other operators, see above.BandNB-IoT Band8"8", "20", "8,20", Empty = Auto detect (longer connecting time)APNMobile operator APN (optional)iot.1nce.net1nce

: iot.1nce.net

Vodafone Easy Connect: lpwa.vodafone.com (l = littel L)

PINSIM PIN (optional)
Empty or 4 digits (e.g. 1234)

LoRaWAN

The connection to the LoRaWAN network is defined by multiple configuration parameters. This need to be set according to your LoRaWAN network and the way your device is supposed to be attached to it, or the device will not be able to send any data.

For a detailed introduction into how this values need to be configured, please refer to the chapter LoRaWAN configuration in our LoRaWAN background article.

NameDescription
Note

Downlink configuration via LoRaWAN is not supported yet.


NameDescriptionType
Type
Default ValueValues
DevEUIDevEUI used to identify the Devicebyte[8]
e.g. 0123456789abcdef
JoinEUIUsed for OTAA (called AppEUI in v1.0)byte[8]
e.g. 0123456789abcdef
AppKeyKey used for OTAA (v1.0 and v1.1)byte[16]

SFInitial / maximum Spreading Factorint127 - 12
OpModeOperation ModestringAA= Class A, C= Class C
LostRebootDays without downlink before rebootint5days, 0=don't reboot


Operation

Without configuration the sensors will be transmitted ordered by the 48 Bit id, ignoring the Sensorfamily prefix and the Checksum.

namedescriptionexample value
TestModeRun device in Testing Mode to help identify sensors. Must be false for normal operations.true or false
MeasureCronCron expression defining when to read out sensors0 0/15 * * * *(every 15 minutes)
SendInternalTempToggle output of internal sensor. Will always be sent first.true or false
SendSensorIdInclude Sensor ID in upload. Changes Payload format and Port.true or false
SensorIdOrderSemicolon separated list of 48 Bit IDs in hex (up to 25)22ffffff0000;44ffffff0000;11ffffff0000


 See also our Introduction to Cron expressions.

Temperature and Error values

Temperature is transmitted in 10th of degrees Centigrade (d°C), to avoid having to deal with floating point numbers. Error conditions for individual sensors are transmitted as temperatures below -300°C.

temperaturehex valueerror condition
-899.0°C0xdce2Sensor not found (for sensors set in SensorIdOrder).
-997.0°C0xd90eCommunication timed out.
-998.0°C0xd904Temperature read out error.
-999.0°C0xd8faNo temperature value.


Sensor IDs

A complete sensor ID consists of 8 bytes:

Panel
byte    0: family code
bytes 1-6: serial number
byte    7: crc cecksum 

Only the serial number is used by the device. Family code and checksum are omitted for uploads and in configuration.

Internal Sensor

There is a temperature sensor included in the board of the device. If SendInternalTemp is set to true, that sensor will be included in uploads. It will always be the first sensor in the list.

Sensor order

The sensors will be ordered by their IDs (without the leading byte indicating the sensor type). You can fix the upload order by listing sensors in SensorIdOrder. Sensors included here will always be included in upload messages, whether the sensor is found or not. If the sensor cannot be found, a temperature value of -899.0°C (=0xdce2) is sent.

If the internal sensor is included (by SendInternalTemp=true), the internal sensor will still be sent first, before the first sensor listed in SensorIdOrder.

Any sensors that are found and are neither internal nor listed in SensorIdOrder will be appended after the last sensor from SensorIdOrder, ordered by their IDs.

Payload

Example payloads for each port:

Status Message (Port 1)

Only for Firmware < v0.2.0

Payload: 00040001070ce3

Decoded:

Code Block
languagejs
themeConfluence
linenumberstrue
{
  "temp": 26.3,
  "vBat": 3.299,
  "version": "v0.4.0"
}

Data Message (Port 2)

Payload with temperature measurements when Sensor-ID is included.

Structure:

namelentypedescription
success1uint80 = Read error, 1 = Success
sensor id6uint8[6]6-Byte 1-Wire Sensor Id
temperature2int16 BETemperature in 1/10 °C
...

... sensor id and temperature fields repeat ...


When the total length of data exceeds 50 bytes, the message will be split and uploaded in multiple packets using this format.

Example Payload: 01551e46920d0200da96b446920c0200d7dafc46920d0200d5202e4692050200dc

Decoded:

Code Block
languagejs
themeConfluence
linenumberstrue
{
  "sensors": [
    {
      "id": "551e46920d02",
      "temp": 21.8
    },
    {
      "id": "96b446920c02",
      "temp": 21.5
    },
    {
      "id": "dafc46920d02",
      "temp": 21.3
    },
    {
      "id": "202e46920502",
      "temp": 22
    }
  ],
  "success": true
}

Data Message (Port 3)

Payload with temperature measurements when Sensor-ID is omitted.

Before v0.4.0 this format is sent on Port 2.

Structure:

namelentypedescription
success1uint80 = Read error, 1 = Success
temperature2int16 BETemperature in 1/10 °C
...

... temperature field repeats ...


When the total length of data exceeds 50 bytes, the message will be split and uploaded in multiple packets using this format.

Example Payload: 0100f500f500f800f500f300f8

Code Block
titleDecoded
:
{
    "sensors": [
      24.5,
      24.5,
      24.8,
      24.5,
      24.3,
      24.8
    ],
    "success": true
}




Error Message (Port 4)

Error Message containing a single 0 Byte to indicate that not a single temperature sensor could be found and therefore no data exists.

Status Message (Port 64)

Since v0.2.1

Example Payload:  545031 000202 000000 0e6c 010e


namelentypedescription
Firmware
Identifyer
Identifier3String3
Caharcter
Charcter FW
Identifyer
Identifier TP1
Firmware Version3

uint8[3]

Version: <major>.<minor>.<patch>
Status1uint8RFU - always 0
Rebot
Reboot reason1uint8RFU - always 0
Final words1uint8RFU - always 0
vBat2int16battery Voltage in mV
Temperature2int16Internal temperature from controller in 1/10 °C

Parser

Lobaro Platform / TheThingsNetwork (TTN) / ChirpStack


Code Block
function 
readVersion
parse_sint16(bytes, idx) {
if (bytes.length<3) {
    bytes = bytes.slice(idx || 0);
    var t = bytes[0] << 8 | bytes[1] << 0;
    if( (t & 1<<15) > 0){ // temp is negative (16bit 2's complement)
        t = ((~t)& 0xffff)+1; // invert 16bits & add 1 => now positive value
        t=t*-1;
    }
    return t;
}

function parse_uint16(bytes, idx) {
    bytes = bytes.slice(idx || 0);
    var t = bytes[0] << 8 | bytes[1] << 0;
    return t;
}

function parse_hex(bytes, idx, end) {
    var chars = "0123456789abcdef";
    bytes = bytes.slice(idx || 0, end || null);
    var s = "";
    for (var i=0; i<bytes.length; i++) {
        var byte = bytes[i];
        s += chars.charAt(byte>>4);
        s += chars.charAt(byte & 0xf);
    }
    return s;
}

function NB_ParseConfigQuery(input) {
    for (var key in input.d) {
        Device.setConfig(key, input.d[key]);
    }
    return null;
}

function DecoderPort1(bytes) {
    return {
        "version":readVersion(bytes),
        "temp": parse_sint16(bytes, 3) / 10,
        "vBat": parse_uint16(bytes, 5) / 1000,
    };
}

function DecoderPort2(bytes) {
    // Decode an uplink message from a buffer
    // (array) of bytes to an object of fields.
    var sensors = [];
    var success = false;

    var pos = 0;
    if ( bytes.length ) {
        pos+=1;
        success = bytes[0] !== 0;
    }
    var left = bytes.length - pos;
    while (left>=8) {
        var sensor = {
            //'id_': bytes.slice(pos, pos+6),
            'id': parse_hex(bytes, pos, pos+6),
            'temp': parse_sint16(bytes, pos+6) / 10.0
        };
        sensors.push(sensor);
        pos += 8;
        left = bytes.length 
return
- 
null
pos;
    }
    
return "v" + bytes[0] + "." + bytes[1] + "." + bytes[2]; } function parse_sint16(bytes, idx) {
// if (port === 1) decoded.led = bytes[0];

    var decoded = {};
    
bytes
decoded['success'] =
bytes.slice(idx || 0)
 success;
    decoded['sensors'] = sensors;
    
var t = bytes[0] << 8 | bytes[1] << 0; if( (t & 1<<15) > 0){ // temp is negative (16bit 2's complement)
return decoded;
}

function DecoderPort3(bytes) {
    // Decode an uplink message from a buffer
    // (array) of bytes to an object of fields.
    var sensors = [];
 
t
 
=
 
((~t)& 0xffff)+1; // invert 16bits & add 1 => now positive value
 var success = false;

    var pos = 0;
    if ( bytes.length 
t=t*-1;
) {
    
}
    
return t
pos+=1;
} function parse_uint16(bytes, idx) {
        
bytes
success = bytes
.slice(idx ||
[0] !== 0
)
;
    
var
}
 
t
 
=
 
bytes[0]
 
<<
var 
8
left 
|
= bytes
[1] << 0
.length - pos;
    
return
var 
t
nr=0;
} function parse_hex(bytes, idx, end
    while (left>=2) {
      var 
chars
temp = 
"0123456789abcdef"; bytes = bytes.slice(idx || 0, end || null);
parse_sint16(bytes, pos) / 10.0
        sensors.push(temp);
       
var
 
s
pos += 
""
2;
    
for (var i=0; i<
    left = bytes.length - pos;
i++) {

    }
    // if (port === 
var byte
1) decoded.led = bytes[
i
0];

    var 
decoded 
s +
= 
chars.charAt(byte>>4)
{};
    decoded['success'] = success;
  
s
 
+= chars.charAt(byte & 0xf)
 decoded['sensors'] = sensors;
    
}
return 
s
decoded;
}

function DecoderPort1(bytes) { return
function readVersion(bytes, i) {
    if (bytes.length < 
"version":readVersion(bytes),
3) {
        
"temp": parse_sint16(bytes, 3) / 10,
return null;
    }
    return "v" + bytes[i] + "
vBat
."
: parse_uint16(bytes, 5) / 1000, }
 + bytes[i + 1] + "." + bytes[i + 2];
}

function 
DecoderPort2(bytes
decode_status_code(code) {
  switch 
// Decode an uplink message from a buffer
(code) {
    case 0:
    
//
 
(array)
 
of bytes to an object of fields.
return "OK";
    default:
    
var
 
sensors
 
= []
return "UNKNOWN";
  }
}

function 
var success = false; var pos = 0; if ( bytes.length ) {
decode_reboot_reason(code) {
  // STM reboot code from our HAL:
  switch (code) {
    case 1:
      
pos+=1
return "LOW_POWER_RESET";
    case 2:
   
success
 
=
 
bytes[0] !== 0
 return "WINDOW_WATCHDOG_RESET";
    
}
case 3:
    
var
 
left
 
= bytes.length - pos
return "INDEPENDENT_WATCHDOG_RESET";
    
while (left>=8) {
case 4:
    
var
 
sensor
 
= {
return "SOFTWARE_RESET";
    case 5:
      
//'id_': bytes.slice(pos, pos+6),
return "POWER_ON_RESET";
    case 6:
      return "EXTERNAL_RESET_PIN_RESET";
    case 
'id'
7:
parse_hex(bytes, pos, pos+6),

      return "OBL_RESET";
    default:
      return "UNKNOWN";
  
'temp': parse_sint16(bytes, pos+6) / 10.0 }; sensors.push(sensor); pos += 8; left = bytes.length - pos; } // if (port === 1) decoded.led = bytes[0]; var decoded = {}; decoded['success'] = success; decoded['sensors'] = sensors; return decoded; } function DecoderPort3(bytes) { // Decode an uplink message from a buffer // (array) of bytes to an object of fields. var sensors = []; var success = false; var pos = 0; if ( bytes.length ) { pos+=1; success = bytes[0] !== 0; } var left = bytes.length - pos; var nr=0; while (left>=2) { var temp = parse_sint16(bytes, pos) / 10.0 sensors.push(temp); pos += 2;
}
}

function DecoderPort64(bytes) {
  // legacy format, firmware 4.x
  // Decode an uplink message from a buffer
  // (array) of bytes to an object of fields.
  var firmware = String.fromCharCode.apply(null, bytes.slice(0, 3));
  var version = readVersion(bytes, 3);
  var status_code = bytes[6];
  var status_text = decode_status_code(status_code);
  var reboot_code = bytes[7];
  var reboot_reason = decode_reboot_reason(reboot_code);
  var final_code = bytes[8];
  var vcc = (parse_uint16(bytes, 9) / 1000) || 0.0;
  var temp = (parse_sint16(bytes, 11) / 10) || -0x8000;
  var app_data = bytes.slice(13);
  
  Device.setProperty("firmware", firmware);
  Device.setProperty("version", version);
  Device.setProperty("status_code", status_code);
  Device.setProperty("status_text", status_text);
  Device.setProperty("reboot_code", reboot_code);
  Device.setProperty("reboot_reason", reboot_reason);
  Device.setProperty("final_code", final_code);
  Device.setProperty("app_data", app_data);
  Device.setProperty("temperature", temp);
  Device.setProperty("voltage", vcc);
  
  return {
    "firmware": firmware,
    "version": version,
    "status_code": status_code,
    "status_text": status_text,
    "reboot_code": reboot_code,
    "reboot_reason": reboot_reason,
    "final_code": final_code,
    "temperature": temp,
    "voltage": vcc,
    "app_data": app_data
  };
}

function Decoder(bytes, port) {
    switch (port) {
        
left
case 
= bytes.length - pos;
1:
       
}
    
//
 
if
return 
(port === 1) decoded.led = bytes[0];
DecoderPort1(bytes);
       
var
 
decoded = {};
case 2:
    
decoded['success'] = success;
       
decoded['sensors'] = sensors;
 return DecoderPort2(bytes);
     
return decoded; }
function DecoderPort64(bytes) {
    return {
        "fw": String.fromCharCode(bytes[0]) + String.fromCharCode(bytes[1]) + String.fromCharCode(bytes[2]),
        "version":readVersion(bytes.slice(3)),
        "status": bytes[6],
        "rebootReason": bytes[7],
        "finalWords": bytes[8],
        "vBat": parse_uint16(bytes, 9) / 1000,
        "temp": parse_sint16(bytes, 11) / 10,
    };
}
function Decoder(bytes, port)
   case 3:
            return DecoderPort3(bytes);
        case 4:
            return "error: No sensors found";
        case 64:
            return DecoderPort64(bytes);
    }
    return {
    
switch
 
(port)
 
{
  "error": "Invalid port",
    
case
 
1:
   "port": port
    };
}

// Wrapper for Lobaro 
return
Platform
function 
DecoderPort1
Parse(
bytes
input)
;
 {
    // Decode an incoming 
case
message 
2:
to an object of fields.
    var b 
return DecoderPort2(bytes
= bytes(atob(input.data));
    
    
case 3:
if (input.i && input.d) {
      // NB-IoT
     
return DecoderPort3(bytes);
 var decoded = {};
      decoded = 
case 64:
            return DecoderPort64(bytes);    
}
input.d;
      decoded.address = input.i;
      decoded.fCnt = input.n;
     
return
 
{

      var 
"error": "Invalid port",
query = input.q || "data";
     
"port":
 
port

   
}; } //
 
Wrapper
 
for
 
Lobaro
switch 
Platform function Parse
(
input
query) {
      
//
 
Decode
 
an incoming message to an object of fields.
case "config":
          
var
 
b
 
=
return 
bytes
NB_ParseConfigQuery(
atob(
input
.data));
);
        default:
    
var
 
decoded
 
= Decoder(b, input.fPort);
}
      return decoded;
    }
// Wrapper
 
for
 
Loraserver
 
/
 
ChirpStack

function
 
Decode(fPort,
 
bytes)
 
{
 var decoded 
return
= Decoder(
bytes
b, input.fPort);
} //
 
Wrapper
 
for
 
Digimondo
 
niota platform /* module.exports = function (payload, meta) {

    decoded.rssi = input.rssi;
    
const port
decoded.fCnt = 
meta
input.
lora.fport
fCnt;

    return 
const buf = Buffer.from(payload, 'hex');
decoded;
}

// Wrapper for Loraserver / ChirpStack
function Decode(fPort, bytes) {
    return Decoder(
buf
bytes, 
port
fPort);
}
*/




CE Declaration of Conformity

CE Declaration of Conformity (pdf).

toc