2018-04-01 06:53:37 +00:00
|
|
|
/*
|
2022-01-13 14:06:53 +00:00
|
|
|
Copyright (C) 2018-2022 Fredrik Öhrström
|
2018-04-01 06:53:37 +00:00
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef DVPARSER_H
|
|
|
|
#define DVPARSER_H
|
|
|
|
|
|
|
|
#include"util.h"
|
2022-01-13 08:51:08 +00:00
|
|
|
#include"units.h"
|
2018-04-01 06:53:37 +00:00
|
|
|
#include"wmbus.h"
|
|
|
|
|
|
|
|
#include<map>
|
|
|
|
#include<stdint.h>
|
2019-01-01 20:04:06 +00:00
|
|
|
#include<time.h>
|
2018-04-01 06:53:37 +00:00
|
|
|
#include<functional>
|
|
|
|
#include<vector>
|
|
|
|
|
2019-01-27 23:03:25 +00:00
|
|
|
#define LIST_OF_VALUETYPES \
|
2022-01-13 08:51:08 +00:00
|
|
|
X(Volume,0x10,0x17,Quantity::Volume,Unit::M3) \
|
|
|
|
X(OperatingTime,0x24,0x27, Quantity::Time, Unit::Second) \
|
|
|
|
X(VolumeFlow,0x38,0x3F, Quantity::Flow, Unit::M3H) \
|
|
|
|
X(FlowTemperature,0x58,0x5B, Quantity::Temperature, Unit::C) \
|
|
|
|
X(ReturnTemperature,0x5C,0x5F, Quantity::Temperature, Unit::C) \
|
|
|
|
X(TemperatureDifference,0x60,0x63, Quantity::Temperature, Unit::C) \
|
|
|
|
X(ExternalTemperature,0x64,0x67, Quantity::Temperature, Unit::C) \
|
|
|
|
X(HeatCostAllocation,0x6E,0x6E, Quantity::HCA, Unit::HCA) \
|
|
|
|
X(Date,0x6C,0x6C, Quantity::PointInTime, Unit::DateTimeLT) \
|
|
|
|
X(DateTime,0x6D,0x6D, Quantity::PointInTime, Unit::DateTimeLT) \
|
|
|
|
X(EnergyMJ,0x0E,0x0F, Quantity::Energy, Unit::MJ) \
|
|
|
|
X(EnergyWh,0x00,0x07, Quantity::Energy, Unit::KWH) \
|
|
|
|
X(PowerW,0x28,0x2f, Quantity::Power, Unit::KW) \
|
|
|
|
X(ActualityDuration,0x74,0x77, Quantity::Time, Unit::Second) \
|
2019-01-27 23:03:25 +00:00
|
|
|
|
|
|
|
enum class ValueInformation
|
|
|
|
{
|
2020-03-23 17:58:34 +00:00
|
|
|
None,
|
2022-01-06 17:28:22 +00:00
|
|
|
Any,
|
2022-01-13 08:51:08 +00:00
|
|
|
#define X(name,from,to,quantity,unit) name,
|
2019-01-27 23:03:25 +00:00
|
|
|
LIST_OF_VALUETYPES
|
|
|
|
#undef X
|
|
|
|
};
|
|
|
|
|
2020-01-28 18:09:39 +00:00
|
|
|
const char *toString(ValueInformation v);
|
2022-01-13 08:51:08 +00:00
|
|
|
Unit toDefaultUnit(ValueInformation v);
|
2020-01-28 18:09:39 +00:00
|
|
|
ValueInformation toValueInformation(int i);
|
2019-01-27 23:03:25 +00:00
|
|
|
|
2022-01-06 17:28:22 +00:00
|
|
|
struct DifVifKey
|
|
|
|
{
|
|
|
|
DifVifKey(string key) : key_(key) {}
|
|
|
|
string str() { return key_; }
|
|
|
|
bool useSearchInstead() { return key_ == ""; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
string key_;
|
|
|
|
};
|
|
|
|
|
|
|
|
static DifVifKey NoDifVifKey = DifVifKey("");
|
|
|
|
|
|
|
|
struct StorageNr
|
|
|
|
{
|
|
|
|
StorageNr(int n) : nr_(n) {}
|
|
|
|
int intValue() { return nr_; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
int nr_;
|
|
|
|
};
|
|
|
|
|
|
|
|
static StorageNr AnyStorageNr = StorageNr(-1);
|
|
|
|
|
|
|
|
struct TariffNr
|
|
|
|
{
|
|
|
|
TariffNr(int n) : nr_(n) {}
|
|
|
|
int intValue() { return nr_; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
int nr_;
|
|
|
|
};
|
|
|
|
|
|
|
|
static TariffNr AnyTariffNr = TariffNr(-1);
|
|
|
|
|
|
|
|
struct IndexNr
|
|
|
|
{
|
|
|
|
IndexNr(int n) : nr_(n) {}
|
|
|
|
int intValue() { return nr_; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
int nr_;
|
|
|
|
};
|
|
|
|
|
|
|
|
static IndexNr AnyIndexNr = IndexNr(-1);
|
|
|
|
|
2019-01-27 23:03:25 +00:00
|
|
|
bool loadFormatBytesFromSignature(uint16_t format_signature, vector<uchar> *format_bytes);
|
2018-04-01 06:53:37 +00:00
|
|
|
|
|
|
|
bool parseDV(Telegram *t,
|
2018-12-28 17:35:32 +00:00
|
|
|
std::vector<uchar> &databytes,
|
2018-04-01 06:53:37 +00:00
|
|
|
std::vector<uchar>::iterator data,
|
|
|
|
size_t data_len,
|
2019-01-27 23:03:25 +00:00
|
|
|
std::map<std::string,std::pair<int,DVEntry>> *values,
|
2018-04-01 06:53:37 +00:00
|
|
|
std::vector<uchar>::iterator *format = NULL,
|
|
|
|
size_t format_len = 0,
|
2019-08-12 09:47:39 +00:00
|
|
|
uint16_t *format_hash = NULL);
|
2018-04-01 06:53:37 +00:00
|
|
|
|
2019-01-27 23:03:25 +00:00
|
|
|
// Instead of using a hardcoded difvif as key in the extractDV... below,
|
|
|
|
// find an existing difvif entry in the values based on the desired value information type.
|
|
|
|
// Like: Volume, VolumeFlow, FlowTemperature, ExternalTemperature etc
|
|
|
|
// in combination with the storagenr. (Later I will add tariff/subunit)
|
2020-01-29 06:42:24 +00:00
|
|
|
bool findKey(MeasurementType mt, ValueInformation vi, int storagenr, int tariffnr,
|
|
|
|
std::string *key, std::map<std::string,std::pair<int,DVEntry>> *values);
|
2021-10-02 09:36:33 +00:00
|
|
|
// Some meters have multiple identical DIF/VIF values! Meh, they are not using storage nrs or tariff nrs.
|
|
|
|
// So here we can pick for example nr 2 of an identical set if DIF/VIF values.
|
|
|
|
// Nr 1 means the first found value.
|
2022-01-06 17:28:22 +00:00
|
|
|
bool findKeyWithNr(MeasurementType mt, ValueInformation vi, int storagenr, int tariffnr, int indexnr,
|
2021-10-02 09:36:33 +00:00
|
|
|
std::string *key, std::map<std::string,std::pair<int,DVEntry>> *values);
|
2020-01-29 06:42:24 +00:00
|
|
|
|
2019-01-27 23:03:25 +00:00
|
|
|
#define ANY_STORAGENR -1
|
2020-01-29 06:42:24 +00:00
|
|
|
#define ANY_TARIFFNR -1
|
2019-01-27 23:03:25 +00:00
|
|
|
|
2019-03-01 14:41:11 +00:00
|
|
|
bool hasKey(std::map<std::string,std::pair<int,DVEntry>> *values, std::string key);
|
|
|
|
|
2019-11-26 15:12:32 +00:00
|
|
|
bool extractDVuint8(std::map<std::string,std::pair<int,DVEntry>> *values,
|
|
|
|
std::string key,
|
|
|
|
int *offset,
|
|
|
|
uchar *value);
|
|
|
|
|
2019-01-27 23:03:25 +00:00
|
|
|
bool extractDVuint16(std::map<std::string,std::pair<int,DVEntry>> *values,
|
2018-04-01 06:53:37 +00:00
|
|
|
std::string key,
|
|
|
|
int *offset,
|
|
|
|
uint16_t *value);
|
|
|
|
|
2020-07-30 10:19:54 +00:00
|
|
|
bool extractDVuint24(std::map<std::string,std::pair<int,DVEntry>> *values,
|
|
|
|
std::string key,
|
|
|
|
int *offset,
|
|
|
|
uint32_t *value);
|
|
|
|
|
2020-09-24 11:29:25 +00:00
|
|
|
bool extractDVuint32(std::map<std::string,std::pair<int,DVEntry>> *values,
|
|
|
|
std::string key,
|
|
|
|
int *offset,
|
|
|
|
uint32_t *value);
|
|
|
|
|
2021-03-06 06:42:37 +00:00
|
|
|
// All values are scaled according to the vif and wmbusmeters scaling defaults.
|
2019-01-27 23:03:25 +00:00
|
|
|
bool extractDVdouble(std::map<std::string,std::pair<int,DVEntry>> *values,
|
2022-01-13 14:06:53 +00:00
|
|
|
std::string key,
|
|
|
|
int *offset,
|
|
|
|
double *value,
|
|
|
|
bool auto_scale = true,
|
|
|
|
bool assume_signed = false);
|
2018-04-01 06:53:37 +00:00
|
|
|
|
2021-03-06 06:42:37 +00:00
|
|
|
// Extract a value without scaling. Works for 8bits to 64 bits, binary and bcd.
|
|
|
|
bool extractDVlong(map<string,pair<int,DVEntry>> *values,
|
|
|
|
string key,
|
|
|
|
int *offset,
|
|
|
|
uint64_t *value);
|
|
|
|
|
2019-01-27 23:03:25 +00:00
|
|
|
bool extractDVstring(std::map<std::string,std::pair<int,DVEntry>> *values,
|
2019-01-01 20:04:06 +00:00
|
|
|
std::string key,
|
|
|
|
int *offset,
|
|
|
|
string *value);
|
|
|
|
|
2019-01-27 23:03:25 +00:00
|
|
|
bool extractDVdate(std::map<std::string,std::pair<int,DVEntry>> *values,
|
2019-01-01 20:04:06 +00:00
|
|
|
std::string key,
|
|
|
|
int *offset,
|
2019-03-01 14:41:11 +00:00
|
|
|
struct tm *value);
|
2019-01-01 20:04:06 +00:00
|
|
|
|
|
|
|
void extractDV(string &s, uchar *dif, uchar *vif);
|
2018-04-01 06:53:37 +00:00
|
|
|
|
|
|
|
#endif
|