Skip to content

Commit

Permalink
0.9.8
Browse files Browse the repository at this point in the history
## [0.9.8] - 2025-01-13

### Added

- VIF FB2C frequency
- VIF FB34 apparent power
- VIF FB02 reactive energy
- VIF FB14 reactive power
- additve / multiplicative corretion factor is now working for every VIF

### Changed

- unknown VIFs do not longer stop decoding
  • Loading branch information
Zeppelin500 committed Jan 13, 2025
1 parent 0059e55 commit c32446c
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 24 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [0.9.8] - 2025-01-13

### Added

- VIF FB2C frequency
- VIF FB34 apparent power
- VIF FB02 reactive energy

- additve / multiplicative corretion factor is now working for every VIF

### Changed

- unknown VIFs do not longer stop decoding

## [0.9.7] - 2024-11-05

### Changed
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MBusinoLib - an Arduino M-Bus Decoder Library

[![version](https://img.shields.io/badge/version-0.9.7-brightgreen.svg)](CHANGELOG.md)
[![version](https://img.shields.io/badge/version-0.9.8-brightgreen.svg)](CHANGELOG.md)
[![license](https://img.shields.io/badge/license-GPL--3.0-orange.svg)](LICENSE)


Expand Down Expand Up @@ -108,7 +108,7 @@ Returns the last error ID, once returned the error is reset to OK. Possible erro
```c
uint8_t getError(void);
```

if you receive error code 4 or an "UNSUPPORTED_VIF", please open an issue

### Home Assistant

Expand Down
2 changes: 1 addition & 1 deletion examples/MbusinoLibExample/MbusinoLibExample.ino
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with thi
#include <ArduinoJson.h> // is used to transfer the decoded recordings

#define START_ADDRESS 0x13 // Start address for decoding
unsigned long timerMbus = 0;
unsigned long timerMbus = 5000;

void setup() {
Serial.begin(9600);
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=MBusinoLib
version=0.9.7
version=0.9.8
author=Zeppelin500 <[email protected]>
maintainer=Zeppelin500 <[email protected]>
sentence=an Arduino M-Bus decode Library
Expand Down
92 changes: 76 additions & 16 deletions src/MBusinoLib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ uint8_t MBusinoLib::decode(uint8_t *buffer, uint8_t size, JsonArray& root) {
uint8_t customVIFlen = 0;
char customVIF[20] = {0};
bool ifcustomVIF = false;
uint8_t firstVifeExtension = 1; //8.4.5 Codes for Value Information Field Extension (VIFE)

do {
if (index == size) {
Expand Down Expand Up @@ -270,7 +271,7 @@ uint8_t MBusinoLib::decode(uint8_t *buffer, uint8_t size, JsonArray& root) {
ifcustomVIF = true;
}

if((vifarray[1] & 0x80) == 0x80){ // set se first bit of first VIFE from 1 to 0 to find the right def
if((vifarray[1] & 0x80) == 0x80){ // set the first bit of first VIFE from 1 to 0 to find the right def
vif = (vif & 0xFF7F);
}

Expand All @@ -280,9 +281,40 @@ uint8_t MBusinoLib::decode(uint8_t *buffer, uint8_t size, JsonArray& root) {
if (def < 0) {
_error = MBUS_ERROR::UNSUPPORTED_VIF;
def = 0;
return 0;
//return 0;
}

//find VIF extensions like the table 8.4.5 Codes for Value Information Field Extension (VIFE)

int8_t extensionScaler = 0; // additional scaler (x * 10 ^extensionScaler)
double extensionAdditiveConstant = 0;

if(vifcounter-1 > 0){
if(vifarray[0] == 0xFB || vifarray[0] == 0xFD){
firstVifeExtension = 2;
}
uint8_t extensionsCounter = firstVifeExtension;
do{
if((vifarray[extensionsCounter] & 0x7F) == 0x7D){ // from table "Codes for Value Information Field Extension" E111 1101 Multiplicative correction factor: 1000
extensionScaler = 3; // x1000
}
else if((vifarray[extensionsCounter] & 0x78) == 0x70){ // from table "Codes for Value Information Field Extension" E111 0nnn Multiplicative correction factor: 10nnn-6
extensionScaler = (vifarray[extensionsCounter] & 7) - 6;
}
else if((vifarray[extensionsCounter] & 0x7C) == 0x78){ // from table "Codes for Value Information Field Extension" E111 10nn Additive correction constant: 10nn-3 • unit of VIF (offset)
int8_t extensionAdditiveConstantScaler = 0;
extensionAdditiveConstantScaler = (vifarray[extensionsCounter] & 3) - 3;
extensionAdditiveConstant = 1;
for (int8_t i=0; i<extensionAdditiveConstantScaler; i++) extensionAdditiveConstant *= 10;
for (int8_t i=extensionAdditiveConstantScaler; i<0; i++) extensionAdditiveConstant /= 10;
}
extensionsCounter++;
}while(extensionsCounter <= vifcounter);

}



// Check buffer overflow
if (index + len > size) {
_error = MBUS_ERROR::BUFFER_OVERFLOW;
Expand Down Expand Up @@ -479,13 +511,14 @@ uint8_t MBusinoLib::decode(uint8_t *buffer, uint8_t size, JsonArray& root) {
double scaled = 0;
int8_t scalar = 0;
if(def != 0){ // with unknown vif (def 0) we cant set the scalar
scalar = vif_defs[def].scalar + vif - vif_defs[def].base;
scalar = vif_defs[def].scalar + vif - vif_defs[def].base + extensionScaler;
}
if(dataCodingType == 3){
scaled = valueFloat;
if(vifarray[0] != 0xFF){
for (int8_t i=0; i<scalar; i++) scaled *= 10;
for (int8_t i=scalar; i<0; i++) scaled /= 10;
scaled = scaled + extensionAdditiveConstant;
}
}
else if(vifarray[0]==0xFF){
Expand All @@ -495,16 +528,9 @@ uint8_t MBusinoLib::decode(uint8_t *buffer, uint8_t size, JsonArray& root) {
scaled = value;
for (int8_t i=0; i<scalar; i++) scaled *= 10;
for (int8_t i=scalar; i<0; i++) scaled /= 10;
scaled = scaled + extensionAdditiveConstant;
}

if(vifarray[1] == 0x7D){ // from table "Codes for Value Information Field Extension" E111 1101 Multiplicative correction factor: 1000
scaled = scaled * 1000;
}
else if((vifarray[1] & 0x78) == 0x70){ // from table "Codes for Value Information Field Extension" E111 0nnn Multiplicative correction factor: 10nnn-6
scalar = (vifarray[1] & 7) - 6;
for (int8_t i=scalar; i<0; i++) scaled /= 10;
}

// Init object
JsonObject data = root.add<JsonObject>();
//data["vif"] = String("0x" + String(vif,HEX));
Expand Down Expand Up @@ -663,7 +689,19 @@ const char * MBusinoLib::getCodeUnits(uint8_t code) {
return "month";

case MBUS_CODE::RELATIVE_HUMIDITY:
return "%";
return "%";

case MBUS_CODE::REACTIVE_ENERGY:
return "kvarh";

case MBUS_CODE::REACTIVE_POWER:
return "kvar";

case MBUS_CODE::APPARENT_POWER:
return "kVA";

case MBUS_CODE::FREQUENCY:
return "Hz";

default:
break;
Expand Down Expand Up @@ -846,6 +884,18 @@ const char * MBusinoLib::getCodeName(uint8_t code) {
case MBUS_CODE::RELATIVE_HUMIDITY:
return "humidity";

case MBUS_CODE::REACTIVE_ENERGY:
return "reactive_energy";

case MBUS_CODE::REACTIVE_POWER:
return "reactive_power";

case MBUS_CODE::APPARENT_POWER:
return "apparent_power";

case MBUS_CODE::FREQUENCY:
return "frequency";

default:
break;

Expand All @@ -859,7 +909,7 @@ const char * MBusinoLib::getDeviceClass(uint8_t code) {
switch (code) {

case MBUS_CODE::ENERGY_WH:
case MBUS_CODE::ENERGY_J:
case MBUS_CODE::ENERGY_J:
return "energy";

case MBUS_CODE::VOLUME_M3:
Expand Down Expand Up @@ -934,6 +984,9 @@ const char * MBusinoLib::getDeviceClass(uint8_t code) {
case MBUS_CODE::RELATIVE_HUMIDITY:
return "humidity";

case MBUS_CODE::FREQUENCY:
return "frequency";

case MBUS_CODE::UNKNOWN_VIF:
case MBUS_CODE::FABRICATION_NUMBER:
case MBUS_CODE::BUS_ADDRESS:
Expand Down Expand Up @@ -961,6 +1014,9 @@ const char * MBusinoLib::getDeviceClass(uint8_t code) {
case MBUS_CODE::CUMULATION_COUNTER:
case MBUS_CODE::CUSTOMIZED_VIF:
case MBUS_CODE::MANUFACTURER_SPECIFIC:
case MBUS_CODE::REACTIVE_ENERGY:
case MBUS_CODE::REACTIVE_POWER:
case MBUS_CODE::APPARENT_POWER:
return "";
default:
break;
Expand Down Expand Up @@ -1000,7 +1056,7 @@ const char * MBusinoLib::getStateClass(uint8_t code) {
return "measurement";

case MBUS_CODE::ENERGY_WH:
case MBUS_CODE::ENERGY_J:
case MBUS_CODE::ENERGY_J:
case MBUS_CODE::UNKNOWN_VIF:
case MBUS_CODE::VOLUME_M3:
case MBUS_CODE::VOLUME_FT3:
Expand Down Expand Up @@ -1048,7 +1104,11 @@ const char * MBusinoLib::getStateClass(uint8_t code) {
case MBUS_CODE::RESET_COUNTER:
case MBUS_CODE::CUMULATION_COUNTER:
case MBUS_CODE::CUSTOMIZED_VIF:
case MBUS_CODE::MANUFACTURER_SPECIFIC:
case MBUS_CODE::MANUFACTURER_SPECIFIC:
case MBUS_CODE::REACTIVE_ENERGY:
case MBUS_CODE::REACTIVE_POWER:
case MBUS_CODE::FREQUENCY:
case MBUS_CODE::APPARENT_POWER:
return "total";
default:
break;
Expand Down Expand Up @@ -1084,4 +1144,4 @@ uint32_t MBusinoLib::_getVIF(uint8_t code, int8_t scalar) {

return 0xFF; // this is not a valid VIF

}
}
16 changes: 12 additions & 4 deletions src/MBusinoLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,22 @@ enum MBUS_CODE {
CUMULATION_COUNTER,

// VIFE 0xFB
REACTIVE_ENERGY,
REACTIVE_POWER,
RELATIVE_HUMIDITY,
VOLUME_FT3,
VOLUME_GAL,
VOLUME_FLOW_GAL_M,
VOLUME_FLOW_GAL_H,
VOLUME_FLOW_GAL_H,
APPARENT_POWER,
FLOW_TEMPERATURE_F,
RETURN_TEMPERATURE_F,
TEMPERATURE_DIFF_F,
EXTERNAL_TEMPERATURE_F,
TEMPERATURE_LIMIT_F,
TEMPERATURE_LIMIT_C,
MAX_POWER_W,
FREQUENCY,

// VIFE 0xFC
CUSTOMIZED_VIF,
Expand All @@ -142,7 +146,7 @@ enum MBUS_ERROR {

// VIF codes

#define MBUS_VIF_DEF_NUM 84
#define MBUS_VIF_DEF_NUM 88

typedef struct {
uint8_t code;
Expand Down Expand Up @@ -231,8 +235,10 @@ static const vif_def_type vif_defs[MBUS_VIF_DEF_NUM] = {

// VIFE 0xFB
{ MBUS_CODE::ENERGY_WH , 0xFB00 , 2, 5},
{ MBUS_CODE::REACTIVE_ENERGY , 0xFB02 , 2, 0},
{ MBUS_CODE::ENERGY_J , 0xFB08 , 2, 8},
{ MBUS_CODE::VOLUME_M3 , 0xFB10 , 2, 2},
{ MBUS_CODE::REACTIVE_POWER , 0xFB14 , 4, -3},
{ MBUS_CODE::MASS_KG , 0xFB18 , 2, 5},
{ MBUS_CODE::RELATIVE_HUMIDITY , 0xFB1A , 2, -1},

Expand All @@ -242,7 +248,9 @@ static const vif_def_type vif_defs[MBUS_VIF_DEF_NUM] = {
{ MBUS_CODE::VOLUME_FLOW_GAL_M , 0xFB25 , 1, 0},
{ MBUS_CODE::VOLUME_FLOW_GAL_H , 0xFB26 , 1, 0},
{ MBUS_CODE::POWER_W , 0xFB28 , 2, 5},
{ MBUS_CODE::FREQUENCY , 0xFB2C , 4, -3},
{ MBUS_CODE::POWER_J_H , 0xFB30 , 2, 8},
{ MBUS_CODE::APPARENT_POWER , 0xFB34 , 4, -3},
{ MBUS_CODE::FLOW_TEMPERATURE_F , 0xFB58 , 4, -3},
{ MBUS_CODE::RETURN_TEMPERATURE_F , 0xFB5C , 4, -3},
{ MBUS_CODE::TEMPERATURE_DIFF_F , 0xFB60 , 4, -3},
Expand All @@ -252,7 +260,7 @@ static const vif_def_type vif_defs[MBUS_VIF_DEF_NUM] = {
{ MBUS_CODE::MAX_POWER_W , 0xFB78 , 8, -3},

// VIFE 0xFC
{ MBUS_CODE::CUSTOMIZED_VIF , 0xFC00 , 254, -5},
{ MBUS_CODE::CUSTOMIZED_VIF , 0xFC00 , 254, 0},

// VIFE 0xFF
{ MBUS_CODE::MANUFACTURER_SPECIFIC , 0xFF00 , 254, 0}
Expand Down Expand Up @@ -289,4 +297,4 @@ class MBusinoLib {
uint8_t _error = NO_ERROR;

};
#endif
#endif

0 comments on commit c32446c

Please sign in to comment.