kopia lustrzana https://github.com/weetmuts/wmbusmeters
commit
6e87f9f611
|
@ -63,14 +63,14 @@ telegram=|5744b40988227711101b7ab20800000265a00842658f088201659f08226589081265a0
|
|||
# Test IZAR RC 868 I R4 PL water meter telegram
|
||||
|
||||
telegram=|1944304C72242421D401A2|013D4013DD8B46A4999C1293E582CC|
|
||||
{"media":"water","meter":"izar","name":"IzarWater","id":"21242472","total_m3":3.488,"last_month_total_m3":3.486,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
|IzarWater;21242472;3.488000;3.486000;1111-11-11 11:11.11
|
||||
{"media":"water","meter":"izar","name":"IzarWater","id":"21242472","total_m3":3.488,"last_month_total_m3":3.486,"last_month_measure_date":"2019-09-30","remaining_battery_life_y":14.5,"current_alarms":"meter_blocked,underflow","previous_alarms":"no_alarm","timestamp":"1111-11-11T11:11:11Z"}
|
||||
IzarWater;21242472;3.488000;3.486000;2019-09-30;14.500000;meter_blocked,underflow;no_alarm;1111-11-11 11:11.11
|
||||
|
||||
# Test new version of IZAR
|
||||
|
||||
telegram=|2944A511780729662366A20118001378D3B3DB8CEDD77731F25832AAF3DA8CADF9774EA673172E8C61F2|
|
||||
{"media":"water","meter":"izar","name":"IzarWater2","id":"66290778","total_m3":16.76,"last_month_total_m3":11.84,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
|IzarWater2;66290778;16.760000;11.840000;1111-11-11 11:11.11
|
||||
{"media":"water","meter":"izar","name":"IzarWater2","id":"66290778","total_m3":16.76,"last_month_total_m3":11.84,"last_month_measure_date":"2019-11-30","remaining_battery_life_y":12,"current_alarms":"no_alarm","previous_alarms":"no_alarm","timestamp":"1111-11-11T11:11:11Z"}
|
||||
IzarWater2;66290778;16.760000;11.840000;2019-11-30;12.000000;no_alarm;no_alarm;1111-11-11 11:11.11
|
||||
|
||||
# Test Hydrus water meter telegram
|
||||
telegram=|4E44A5116464646470077AED004005|2F2F01FD08300C13741100007C1300000000FC101300000000FC201300000000726C00000B3B00000002FD748713025A6800C4016D3B177F2ACC011300020000|
|
||||
|
|
|
@ -20,13 +20,30 @@
|
|||
#include"wmbus.h"
|
||||
#include"wmbus_utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include<algorithm>
|
||||
#include<stdbool.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define PRIOS_DEFAULT_KEY1 "39BC8A10E66D83F8"
|
||||
#define PRIOS_DEFAULT_KEY2 "51728910E66D83F8"
|
||||
|
||||
/** Contains all the booleans required to store the alarms of a PRIOS device. */
|
||||
typedef struct _izar_alarms {
|
||||
bool general_alarm;
|
||||
bool leakage_currently;
|
||||
bool leakage_previously;
|
||||
bool meter_blocked;
|
||||
bool back_flow;
|
||||
bool underflow;
|
||||
bool overflow;
|
||||
bool submarine;
|
||||
bool sensor_fraud_currently;
|
||||
bool sensor_fraud_previously;
|
||||
bool mechanical_fraud_currently;
|
||||
bool mechanical_fraud_previously;
|
||||
} izar_alarms;
|
||||
|
||||
struct MeterIzar : public virtual WaterMeter, public virtual MeterCommonImplementation {
|
||||
MeterIzar(WMBus *bus, MeterInfo &mi);
|
||||
|
||||
|
@ -35,6 +52,9 @@ struct MeterIzar : public virtual WaterMeter, public virtual MeterCommonImplemen
|
|||
bool hasTotalWaterConsumption();
|
||||
|
||||
double lastMonthTotalWaterConsumption(Unit u);
|
||||
string setH0Date();
|
||||
string currentAlarmsText();
|
||||
string previousAlarmsText();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -44,8 +64,13 @@ private:
|
|||
uint32_t uint32FromBytes(const vector<uchar> &data, int offset, bool reverse = false);
|
||||
vector<uchar> decodePrios(const vector<uchar> &payload, uint32_t key);
|
||||
|
||||
double remaining_battery_life;
|
||||
uint16_t h0_year;
|
||||
uint8_t h0_month;
|
||||
uint8_t h0_day;
|
||||
double total_water_consumption_l_ {};
|
||||
double last_month_total_water_consumption_l_ {};
|
||||
izar_alarms alarms;
|
||||
|
||||
vector<uint32_t> keys;
|
||||
};
|
||||
|
@ -88,6 +113,27 @@ MeterIzar::MeterIzar(WMBus *bus, MeterInfo &mi) :
|
|||
[&](Unit u){ return lastMonthTotalWaterConsumption(u); },
|
||||
"The total water consumption recorded by this meter around end of last month.",
|
||||
true, true);
|
||||
|
||||
addPrint("last_month_measure_date", Quantity::Text,
|
||||
[&](){ return setH0Date(); },
|
||||
"The date when the meter recorded the most recent billing value.",
|
||||
true, true);
|
||||
|
||||
addPrint("remaining_battery_life", Quantity::Time, Unit::Year,
|
||||
[&](Unit u){ return convert(remaining_battery_life, Unit::Year, u); },
|
||||
"How many more years the battery is expected to last",
|
||||
true, true);
|
||||
|
||||
addPrint("current_alarms", Quantity::Text,
|
||||
[&](){ return currentAlarmsText(); },
|
||||
"Alarms currently reported by the meter.",
|
||||
true, true);
|
||||
|
||||
addPrint("previous_alarms", Quantity::Text,
|
||||
[&](){ return previousAlarmsText(); },
|
||||
"Alarms currently reported by the meter.",
|
||||
true, true);
|
||||
|
||||
}
|
||||
|
||||
double MeterIzar::totalWaterConsumption(Unit u)
|
||||
|
@ -107,6 +153,69 @@ double MeterIzar::lastMonthTotalWaterConsumption(Unit u)
|
|||
return convert(last_month_total_water_consumption_l_, Unit::L, u);
|
||||
}
|
||||
|
||||
string MeterIzar::setH0Date()
|
||||
{
|
||||
char result[11];
|
||||
snprintf(result, sizeof(result), "%04d-%02d-%02d", h0_year, h0_month, h0_day);
|
||||
return result;
|
||||
}
|
||||
|
||||
string MeterIzar::currentAlarmsText()
|
||||
{
|
||||
string s;
|
||||
if (alarms.leakage_currently) {
|
||||
s.append("leakage,");
|
||||
}
|
||||
if (alarms.meter_blocked) {
|
||||
s.append("meter_blocked,");
|
||||
}
|
||||
if (alarms.back_flow) {
|
||||
s.append("back_flow,");
|
||||
}
|
||||
if (alarms.underflow) {
|
||||
s.append("underflow,");
|
||||
}
|
||||
if (alarms.overflow) {
|
||||
s.append("overflow,");
|
||||
}
|
||||
if (alarms.submarine) {
|
||||
s.append("submarine,");
|
||||
}
|
||||
if (alarms.sensor_fraud_currently) {
|
||||
s.append("sensor_fraud,");
|
||||
}
|
||||
if (alarms.mechanical_fraud_currently) {
|
||||
s.append("mechanical_fraud,");
|
||||
}
|
||||
if (s.length() > 0) {
|
||||
if (alarms.general_alarm) {
|
||||
return "general_alarm";
|
||||
}
|
||||
s.pop_back();
|
||||
return s;
|
||||
}
|
||||
return "no_alarm";
|
||||
}
|
||||
|
||||
string MeterIzar::previousAlarmsText()
|
||||
{
|
||||
string s;
|
||||
if (alarms.leakage_previously) {
|
||||
s.append("leakage,");
|
||||
}
|
||||
if (alarms.sensor_fraud_previously) {
|
||||
s.append("sensor_fraud,");
|
||||
}
|
||||
if (alarms.mechanical_fraud_previously) {
|
||||
s.append("mechanical_fraud,");
|
||||
}
|
||||
if (s.length() > 0) {
|
||||
s.pop_back();
|
||||
return s;
|
||||
}
|
||||
return "no_alarm";
|
||||
}
|
||||
|
||||
uint32_t MeterIzar::uint32FromBytes(const vector<uchar> &data, int offset, bool reverse)
|
||||
{
|
||||
if (reverse)
|
||||
|
@ -156,9 +265,36 @@ void MeterIzar::processContent(Telegram *t)
|
|||
return;
|
||||
}
|
||||
|
||||
// get the remaining battery life (in year)
|
||||
remaining_battery_life = (frame[12] & 0x1F) / 2.0;
|
||||
|
||||
total_water_consumption_l_ = uint32FromBytes(decoded_content, 1, true);
|
||||
last_month_total_water_consumption_l_ = uint32FromBytes(decoded_content, 5, true);
|
||||
|
||||
// get the date when the second measurement was taken
|
||||
h0_year = ((decoded_content[10] & 0xF0) >> 1) + ((decoded_content[9] & 0xE0) >> 5);
|
||||
if (h0_year > 80) {
|
||||
h0_year += 1900;
|
||||
} else {
|
||||
h0_year += 2000;
|
||||
}
|
||||
h0_month = decoded_content[10] & 0xF;
|
||||
h0_day = decoded_content[9] & 0x1F;
|
||||
|
||||
// read the alarms:
|
||||
alarms.general_alarm = frame[11] >> 7;
|
||||
alarms.leakage_currently = frame[12] >> 7;
|
||||
alarms.leakage_previously = frame[12] >> 6 & 0x1;
|
||||
alarms.meter_blocked = frame[12] >> 5 & 0x1;
|
||||
alarms.back_flow = frame[13] >> 7;
|
||||
alarms.underflow = frame[13] >> 6 & 0x1;
|
||||
alarms.overflow = frame[13] >> 5 & 0x1;
|
||||
alarms.submarine = frame[13] >> 4 & 0x1;
|
||||
alarms.sensor_fraud_currently = frame[13] >> 3 & 0x1;
|
||||
alarms.sensor_fraud_previously = frame[13] >> 2 & 0x1;
|
||||
alarms.mechanical_fraud_currently = frame[13] >> 1 & 0x1;
|
||||
alarms.mechanical_fraud_previously = frame[13] & 0x1;
|
||||
|
||||
// override incorrectly reported medium (oil)
|
||||
t->dll_type = 7;
|
||||
}
|
||||
|
|
|
@ -104,6 +104,12 @@ void MeterCommonImplementation::addPrint(string vname, Quantity vquantity,
|
|||
prints_.push_back( { vname, vquantity, defaultUnitForQuantity(vquantity), getValueFunc, NULL, help, field, json });
|
||||
}
|
||||
|
||||
void MeterCommonImplementation::addPrint(string vname, Quantity vquantity, Unit unit,
|
||||
function<double(Unit)> getValueFunc, string help, bool field, bool json)
|
||||
{
|
||||
prints_.push_back( { vname, vquantity, unit, getValueFunc, NULL, help, field, json });
|
||||
}
|
||||
|
||||
void MeterCommonImplementation::addPrint(string vname, Quantity vquantity,
|
||||
function<string()> getValueFunc,
|
||||
string help, bool field, bool json)
|
||||
|
|
|
@ -84,6 +84,8 @@ protected:
|
|||
void addManufacturer(int m);
|
||||
void addPrint(string vname, Quantity vquantity,
|
||||
function<double(Unit)> getValueFunc, string help, bool field, bool json);
|
||||
void addPrint(string vname, Quantity vquantity, Unit unit,
|
||||
function<double(Unit)> getValueFunc, string help, bool field, bool json);
|
||||
void addPrint(string vname, Quantity vquantity,
|
||||
function<std::string()> getValueFunc, string help, bool field, bool json);
|
||||
bool handleTelegram(vector<uchar> frame);
|
||||
|
|
|
@ -23,6 +23,10 @@ using namespace std;
|
|||
#define LIST_OF_CONVERSIONS \
|
||||
X(Second, Hour, {vto=vfrom/3600.0;}) \
|
||||
X(Hour, Second, {vto=vfrom*3600.0;}) \
|
||||
X(Year, Second, {vto=vfrom*3600.0*24.0*365;}) \
|
||||
X(Second, Year, {vto=vfrom/3600.0/24.0/365;}) \
|
||||
X(Hour, Year, {vto=vfrom/24.0/365;}) \
|
||||
X(Year, Hour, {vto=vfrom*24.0*365;}) \
|
||||
X(KWH, GJ, {vto=vfrom*0.0036;}) \
|
||||
X(GJ, KWH,{vto=vfrom/0.0036;}) \
|
||||
X(M3, L, {vto=vfrom*1000.0;}) \
|
||||
|
|
|
@ -45,7 +45,8 @@
|
|||
X(HCA,hca,"hca",HCA,"heat cost allocation") \
|
||||
X(TXT,txt,"txt",Text,"text") \
|
||||
X(Second,s,"s",Time,"second") \
|
||||
X(Hour,h,"h",Time,"hour")
|
||||
X(Hour,h,"h",Time,"hour") \
|
||||
X(Year,y,"y",Time,"year")
|
||||
|
||||
enum class Unit
|
||||
{
|
||||
|
|
Ładowanie…
Reference in New Issue