> For the complete documentation index, see [llms.txt](https://docs.tesenso.com/tesenso-products/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tesenso.com/tesenso-products/hardware/tesenso-m-bus-lorawan.md).

# Tesenso M-Bus LoRaWAN

## Quickstart

{% tabs %}
{% tab title="QuickStart Guide EN" %}
{% file src="/files/hutEYctFU4CCwtFLvtSs" %}
{% endtab %}

{% tab title="QuickStart Guide DE" %}
{% file src="/files/IVTdFl7sXJUIl6X8gKXl" %}
{% endtab %}
{% endtabs %}

## Product Datasheet

{% tabs %}
{% tab title="Datenblatt DE" %}
{% file src="/files/LoREHz7eE0XrvJupuu42" %}
{% endtab %}

{% tab title="Datasheet EN" %}
{% file src="/files/ZAOVrTNM1sWawhglFmTr" %}
{% endtab %}
{% endtabs %}

## Uplink documentation

{% tabs %}
{% tab title="V2.0 (currrent version)" %}

### M-BUS message formats

| Name:  | Length | MsgType | Data depending on MsgType |
| ------ | ------ | ------- | ------------------------- |
| Unit:  |        | Enum    |                           |
| Bytes  |        |         |                           |
| Range: | 0..255 | 0..127  |                           |

### Uplink message ports

<table data-header-hidden><thead><tr><th width="371"></th><th align="right"></th></tr></thead><tbody><tr><td><strong>Uplink message port:</strong> </td><td align="right">2</td></tr><tr><td><strong>Uplink message port for split messages</strong></td><td align="right">12</td></tr><tr><td><strong>Status Uplink message port:</strong></td><td align="right">50</td></tr></tbody></table>

### ENUM definitions

| MsgType Enum                   |    |                   |
| ------------------------------ | -- | ----------------- |
| 0                              | 0  | Status message    |
| 1                              | 1  | Scan Result       |
| 2                              | 2  | Telegram Response |
| 3                              | 3  | Read Meter        |
| 4                              | 4  | Read Meter Raw    |
| ...                            |    |                   |
| 123                            | 7B | HW\_ID\_UL        |
| 124                            | 7C | MCU\_ID\_UL       |
| 125                            | 7D | Firmware\_hash    |
| Port for ID-s (123-125) is 200 |    |                   |

### Message Types

### 0: Status message

{% hint style="info" %}
**Port 50**
{% endhint %}

| Name:                      | Length | MsgType | Voltage    | Temp | Saved slaves | Read interval | Flags | Status interval |     |
| -------------------------- | ------ | ------- | ---------- | ---- | ------------ | ------------- | ----- | --------------- | --- |
| Unit:                      |        | Enum    | 1/100 -170 |      | Count        | Min(s)        |       | Min(s)          |     |
| Bytes                      | 1      | 1       | 1          | 1    | 1            | 1             | 1     | MSB             | LSB |
| Range:                     | 8      | 0       |            |      |              |               |       |                 |     |
| Example                    | 08     | 0       |            |      |              |               |       |                 |     |
| 08 00 9e 30 00 03 a0 05 a0 |        |         |            |      |              |               |       |                 |     |

###

### 1: Scan Result

| Name:  | Length | MsgType | slave addresses |   |
| ------ | ------ | ------- | --------------- | - |
| Unit:  |        | Enum    |                 |   |
| Bytes  | 1      | 1       | X               |   |
| Range: |        | 1       |                 |   |

###

### 2: Telegram Response

| Name:  | Length | MsgType | Slave response |   |
| ------ | ------ | ------- | -------------- | - |
| Unit:  |        | Enum    |                |   |
| Bytes  | 1      | 1       | X              |   |
| Range: |        | 2       |                |   |

###

### 3: Read Meter

| 3: Read Meter |        | Meter properties block | Meter properties block |             |        |     |             |     |   |          |   |         |   |    |
| ------------- | ------ | ---------------------- | ---------------------- | ----------- | ------ | --- | ----------- | --- | - | -------- | - | ------- | - | -- |
| Name:         | Length | MsgType                | no. of slaves          | ID          | Medium | VIF | Volume      | ... |   |          |   |         |   |    |
| Unit:         |        | Enum                   | count                  | BCD encoded |        |     | BCD encoded |     |   |          |   |         |   |    |
| Bytes         | 1      | 1                      | 1                      | 1           | 1      | 1   | 1           | 1   | 1 | 1        | 1 | 1       | 1 | 10 |
| Range:        |        | 3                      |                        | HighByte    |        |     | LowByte     |     |   | HighByte |   | LowByte |   |    |

###

### 4: Read Meter Raw

{% hint style="info" %}
**Port 2**
{% endhint %}

|        |        |         |           |                        | Has to be decoded in the backend (contains all information) |
| ------ | ------ | ------- | --------- | ---------------------- | ----------------------------------------------------------- |
| Name:  | Length | MsgType | Slave No. | Full response telegram |                                                             |
| Unit:  |        | Enum    | Byte      |                        |                                                             |
| Bytes  | 1      | 1       | 1         | X                      |                                                             |
| Range: |        | 4       |           |                        |                                                             |

###

### 4: Read Meter Raw SPLIT

{% hint style="info" %}
**Port 12**
{% endhint %}

|        |        |         |           |         |                        | Has to be decoded in the backend (contains all information) |
| ------ | ------ | ------- | --------- | ------- | ---------------------- | ----------------------------------------------------------- |
| Name:  | Length | MsgType | Slave No. | Pointer | Full response telegram |                                                             |
| Unit:  |        | Enum    | Byte      | Byte    |                        |                                                             |
| Bytes  | 1      | 1       | 1         | 1       | X                      |                                                             |
| Range: |        | 4       |           |         |                        |                                                             |

###

### 123: HW\_ID\_UL

|        |         |         |
| ------ | ------- | ------- |
| Name:  | MsgType | HWID    |
| Unit:  | Enum    | version |
| Bytes  | 123     |         |
| Range: |         | 0..7    |

###

### 124: MCU\_ID\_UL

| Name:  | MsgType | MCU\_ID  |   |   |         |
| ------ | ------- | -------- | - | - | ------- |
| Unit:  | Enum    |          |   |   |         |
| Bytes  | 124     | HighByte |   |   | LowByte |
| Range: |         |          |   |   |         |

###

### 125: Firmware\_hash\_UL

<table><thead><tr><th width="171">Name:</th><th>MsgType</th><th>Firmware version and hash</th><th></th><th></th></tr></thead><tbody><tr><td>Unit:</td><td>Enum</td><td>String</td><td></td><td></td></tr><tr><td>Bytes</td><td>125</td><td>Size varies</td><td></td><td></td></tr><tr><td>Range:</td><td></td><td></td><td></td><td></td></tr></tbody></table>
{% endtab %}

{% tab title="V2.1" %}
(not available yet, coming soon)
{% endtab %}
{% endtabs %}

### Uplink Decoder

```
// V3.0 10.05.2022, copyright by Tesenso GmbH

//Code entry
if (msg.data) {
    var decoded = decodeFromHex(msg.data);
    decoded.ts = msg.ts;
    decoded.rssi = msg.rssi;
    decoded.snr = msg.snr;
    decoded.toa = msg.toa;
    decoded.frequency = msg.frequency;
    decoded.dr = msg.dr;
    decoded.bat = decodeBattery(msg.bat);
    decoded.hex = msg.data;

    return {
        msg: decoded,
        metadata: metadata,
        msgType: msgType
    };
} else {
    return {
        msg: msg,
        metadata: metadata,
        msgType: msgType
    };
}


function decodeFromHex(data) {
    // Decode uplink message
    var decoded = {};

    //Parse string as bytes
    var bytes = parseHexString(data);
    //scale to manage the different scales with none, one or more decimals on the meter.
    var scale = metadata.ss_scale;

    //various info that can be extracted
    var length = bytes[0];
    var msgType = bytes[1];
    var slaveCount = bytes[2];
    var startCharacter1 = bytes[3];
    var length1 = bytes[4];
    var length2 = bytes[5];
    var startCharacter2 = bytes[6];
    var c = bytes[7];
    var a = bytes[8];
    //72 or 76 -> variable; 73 or 77 -> fixed
    var ciField = bytes[9];
    var medium = data.substr(34, 2);
    var checkSum = bytes[36];


    //Different medium IDs, register positions vary
    if (medium == "02") {
        var volume = data.substr(72, 2) + data.substr(70,
            2) + data.substr(68, 2) + data.substr(66, 2);
        decoded.electricityMeterEnergyHt = parseInt(volume,
            16) * scale;
        volume = data.substr(88, 2) + data.substr(86, 2) +
            data.substr(84, 2) + data.substr(82, 2);
        decoded.electricityMeterEnergyNt = parseInt(volume,
            16) * scale;
    }
    if (medium == "03") {
        var volume = data.substr(66, 2) + data.substr(64,
            2) + data.substr(62, 2) + data.substr(60, 2);
        decoded.gasMeterVolume = parseInt(volume) * scale;
    }
    if (medium == "16") {
        var volume = data.substr(54, 2) + data.substr(52,
            2) + data.substr(50, 2) + data.substr(48, 2);
        decoded.waterMeter = parseInt(volume, 16) * scale;
    }

    return decoded;
}

//Helper functions
function parseHexString(hex) {
    for (var bytes = [], c = 0; c < hex.length; c += 2)
        bytes.push(parseInt(hex.substr(c, 2), 16));
    return bytes;
}

function decodeBattery(byte) {
    if (byte == 0) {
        return 'External power source';
    } else if (byte > 0 && byte < 255) {
        return byte / 254 * 100;
    } else {
        return 'Unknown battery state';
    }
}

function parseFloat(str) {
    var float = 0,
        sign, order, mantissa, exp,
        int = 0,
        multi = 1;
    if (/^0x/.exec(str)) {
        int = parseInt(str, 16);
    } else {
        for (var i = str.length - 1; i >= 0; i -= 1) {
            if (str.charCodeAt(i) > 255) {
                console.log('Wrong string parameter');
                return false;
            }
            int += str.charCodeAt(i) * multi;
            multi *= 256;
        }
    }
    sign = (int >>> 31) ? -1 : 1;
    exp = (int >>> 23 & 0xff) - 127;
    mantissa = ((int & 0x7fffff) + 0x800000).toString(2);
    for (i = 0; i < mantissa.length; i += 1) {
        float += parseInt(mantissa[i]) ? Math.pow(2, exp) :
            0;
        exp--;
    }
    return float * sign;
}
```

{% hint style="info" %}
All Downlinks shall be sent on **Port 3**
{% endhint %}

### Downlink samples

### Add secundary adress manually to EEPROM

| Name:  | Length | MsgType | ID          |   |   |         |
| ------ | ------ | ------- | ----------- | - | - | ------- |
| Unit:  |        | Enum    | BCD encoded |   |   |         |
| Bytes  | 1      | 1       | 1           | 1 | 1 | 1       |
| Range: | 5      | 133     | HighByte    |   |   | LowByte |

* 05 --> Length
* 85 --> MsgType
* 17670401 --> secondaryAdress of the meter

```json
058517670401
```

### Downlink for Scan M-Bus slave on the M-Bus

| Name:  | Length | MsgType | Retry |
| ------ | ------ | ------- | ----- |
| Unit:  |        | Enum    |       |
| Bytes  | 1      | 1       | 1     |
| Range: | 2      | 130     | 0..3  |

* 02 --> Length&#x20;
* 82 --> MsgType&#x20;
* 01 --> Retry

```
028201
```

### Delete saved slaves from EEPROM

| Name:  | Length | MsgType |
| ------ | ------ | ------- |
| Unit:  |        | Enum    |
| Bytes  | 1      | 1       |
| Range: | 1      | 131     |

* 01 --> Length&#x20;
* 83 --> MsgType&#x20;

```
0183
```

### **Change send Intervall:**

| Message Types |        |         |       |                     |                |   |
| ------------- | ------ | ------- | ----- | ------------------- | -------------- | - |
| Name:         | Length | MsgType | Flags | status msg interval | Meter interval |   |
| Unit:         |        | Enum    |       | Min(s)              | Min(s)         |   |
| Bytes         | 1      | 1       | 1     | MSB                 | LSB            | 1 |
| Range:        | 0..255 | 128     |       |                     |                |   |

**sample downlinks to change the intervall:**

* 05800000001E --> 30 minutes
* 05800000000F --> 15minutes
* 058000000005 --> 5minutes

### Troubleshoot Checklist:

* take a photo of the meter and the full installation
* power device
* make sure that the connection (wires/cables) are connected correctly
