kopia lustrzana https://github.com/weetmuts/wmbusmeters
Now supply the configuration on the command line instead of hard coded in main.
rodzic
d075beac50
commit
45f535692f
76
main.cc
76
main.cc
|
@ -27,36 +27,76 @@
|
|||
#include<string.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
void printMeter(Meter *meter) {
|
||||
printf("%s\t%s\t% 3.3f m3\t%s\n",
|
||||
meter->name().c_str(),
|
||||
meter->id().c_str(),
|
||||
meter->totalWaterConsumption(),
|
||||
meter->datetimeOfUpdate().c_str());
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc > 1) {
|
||||
if (!strcmp(argv[1], "--verbose")) {
|
||||
verboseEnabled(true);
|
||||
} else {
|
||||
printf("wmbusmeters version: " WMBUSMETERS_VERSION "\n\n");
|
||||
printf("Usage: wmbusmeters [--verbose]\n");
|
||||
exit(0);
|
||||
}
|
||||
if (argc < 2) {
|
||||
printf("wmbusmeters version: " WMBUSMETERS_VERSION "\n\n");
|
||||
printf("Usage: wmbusmeters [--verbose] [usbdevice] { [meter_name] [meter_id] [meter_key] }* \n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int i=1;
|
||||
if (!strcmp(argv[i], "--verbose")) {
|
||||
verboseEnabled(true);
|
||||
i++;
|
||||
}
|
||||
|
||||
char *usbdevice = argv[i];
|
||||
i++;
|
||||
if (!usbdevice) error("You must supply the usb device to which the wmbus dongle is connected.\n");
|
||||
verbose("Using usbdevice: %s\n", usbdevice);
|
||||
|
||||
if ((argc-i) % 3 != 0) {
|
||||
error("For each meter you must supply a: name,id and key.\n");
|
||||
}
|
||||
int num_meters = (argc-i)/3;
|
||||
verbose("Number of meters: %d\n", num_meters);
|
||||
|
||||
auto manager = createSerialCommunicationManager();
|
||||
|
||||
onExit(call(manager,stop));
|
||||
|
||||
auto wmbus = openIM871A("/dev/ttyUSB0", manager);
|
||||
auto wmbus = openIM871A(usbdevice, manager);
|
||||
|
||||
wmbus->setLinkMode(C1a);
|
||||
if (wmbus->getLinkMode()!=C1a) error("Could not set link mode to C1a\n");
|
||||
|
||||
auto house = createMultical21(wmbus, "MyHouseWater", "12345678", "00112233445566778899AABBCCDDEEFF");
|
||||
if (num_meters > 0) {
|
||||
Meter *meters[num_meters];
|
||||
|
||||
house->onUpdate([](Meter*meter){
|
||||
printf("%s\t%s\t% 3.3f m3\t%s\n",
|
||||
meter->name().c_str(),
|
||||
meter->id().c_str(),
|
||||
meter->totalWaterConsumption(),
|
||||
meter->datetimeOfUpdate().c_str());
|
||||
});
|
||||
for (int m=0; m<num_meters; ++m) {
|
||||
char *name = argv[m*3+i+0];
|
||||
char *id = argv[m*3+i+1];
|
||||
char *key = argv[m*3+i+2];
|
||||
|
||||
if (!isValidId(id)) error("Not a valid meter id \"%s\"\n", id);
|
||||
if (!isValidKey(key)) error("Not a valid meter key \"%s\"\n", key);
|
||||
|
||||
verbose("Configuring meter: \"%s\" \"%s\" \"%s\"\n", name, id, key);
|
||||
meters[m] = createMultical21(wmbus, name, id, key);
|
||||
meters[m]->onUpdate(printMeter);
|
||||
}
|
||||
} else {
|
||||
printf("No meters configured. Printing id:s of all telegrams heard! Add --verbose to get more data.\n");
|
||||
printf("To configure a meter, add a triplet to the command line: name id key\n");
|
||||
printf("Where name is your string identifying the meter.\n");
|
||||
printf(" id is the 8 digits printed on the meter.\n");
|
||||
printf(" key is 32 hex digits with the aes key.\n\n");
|
||||
|
||||
wmbus->onTelegram([](Telegram *t){
|
||||
printf("Received telegram from id: %02x%02x%02x%02x \n",
|
||||
t->a_field_address[0], t->a_field_address[1], t->a_field_address[2], t->a_field_address[3]);
|
||||
});
|
||||
}
|
||||
|
||||
manager->waitForStop();
|
||||
}
|
||||
|
|
|
@ -101,12 +101,14 @@ void MeterMultical21::handleTelegram(Telegram *t) {
|
|||
t->a_field_address[1] != id_[1] ||
|
||||
t->a_field_address[0] != id_[0]) {
|
||||
|
||||
verbose("Ignoring meter %02x %02x %02x %02x \n",
|
||||
t->a_field_address[3], t->a_field_address[2], t->a_field_address[1], t->a_field_address[0]);
|
||||
verbose("Meter %s ignores message with id %02x%02x%02x%02x \n",
|
||||
name_.c_str(),
|
||||
t->a_field_address[0], t->a_field_address[1], t->a_field_address[2], t->a_field_address[3]);
|
||||
return;
|
||||
} else {
|
||||
verbose("Update from meter %02x %02x %02x %02x!\n",
|
||||
t->a_field_address[3], t->a_field_address[2], t->a_field_address[1], t->a_field_address[0]);
|
||||
verbose("Meter %s receives update with id %02x%02x%02x%02x!\n",
|
||||
name_.c_str(),
|
||||
t->a_field_address[0], t->a_field_address[1], t->a_field_address[2], t->a_field_address[3]);
|
||||
}
|
||||
|
||||
int cc_field = t->payload[0];
|
||||
|
|
27
util.cc
27
util.cc
|
@ -23,6 +23,7 @@
|
|||
#include<signal.h>
|
||||
#include<stdarg.h>
|
||||
#include<stddef.h>
|
||||
#include<string.h>
|
||||
#include<string>
|
||||
|
||||
using namespace std;
|
||||
|
@ -73,17 +74,21 @@ int char2int(char input)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void hex2bin(const char* src, vector<uchar> *target)
|
||||
bool hex2bin(const char* src, vector<uchar> *target)
|
||||
{
|
||||
if (!src) return;
|
||||
if (!src) return false;
|
||||
while(*src && src[1]) {
|
||||
if (*src == ' ') {
|
||||
src++;
|
||||
} else {
|
||||
target->push_back(char2int(*src)*16 + char2int(src[1]));
|
||||
int hi = char2int(*src);
|
||||
int lo = char2int(src[1]);
|
||||
if (hi<0 || lo<0) return false;
|
||||
target->push_back(hi*16 + lo);
|
||||
src += 2;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
char const hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A','B','C','D','E','F'};
|
||||
|
@ -126,3 +131,19 @@ void verbose(const char* fmt, ...) {
|
|||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
bool isValidId(char *id)
|
||||
{
|
||||
if (strlen(id) != 8) return false;
|
||||
for (int i=0; i<8; ++i) {
|
||||
if (id[i]<'0' || id[i]>'9') return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValidKey(char *key)
|
||||
{
|
||||
if (strlen(key) != 32) return false;
|
||||
vector<uchar> tmp;
|
||||
return hex2bin(key, &tmp);
|
||||
}
|
||||
|
|
4
util.h
4
util.h
|
@ -32,7 +32,7 @@ typedef unsigned char uchar;
|
|||
#define call(A,B) ([A](){A->B();})
|
||||
#define calll(A,B,T) ([A](T t){A->B(t);})
|
||||
|
||||
void hex2bin(const char* src, std::vector<uchar> *target);
|
||||
bool hex2bin(const char* src, std::vector<uchar> *target);
|
||||
std::string bin2hex(std::vector<uchar> &target);
|
||||
|
||||
void xorit(uchar *srca, uchar *srcb, uchar *dest, int len);
|
||||
|
@ -42,6 +42,8 @@ void verbose(const char* fmt, ...);
|
|||
|
||||
void verboseEnabled(bool b);
|
||||
|
||||
bool isValidId(char *id);
|
||||
bool isValidKey(char *key);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue