Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for 5 Channel S0 USB Pulse meter (original: 5-kanaals S0 Pulse Meter op USB) #596

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions etc/vzlogger.conf.sos_s0_reader
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
* vzlogger configuration
*
* Use properly encoded JSON with javascript comments
*
* Take a look at the wiki for detailed information:
* http://wiki.volkszaehler.org/software/controller/vzlogger#configuration
*
* For an online configuration editor refer to:
* http://volkszaehler.github.io/vzlogger/
*/

{
// General settings
"verbosity": 10, // log verbosity (0=log_alert, 1=log_error, 3=log_warning, 5=log_info, 10=log_debug, 15=log_finest)
"log": "/var/log/vzlogger.log", // log file, optional
"retry": 30, // http retry delay in seconds

// Build-in HTTP server
"local": {
"enabled": false, // enable local HTTPd for serving live readings
"port": 8080, // TCP port for local HTTPd
"index": true, // provide index listing of available channels if no UUID was requested
"timeout": 30, // timeout for long polling comet requests in seconds (0 disables comet)
"buffer": -1 // HTTPd buffer configuration for serving readings, default -1
// >0: number of seconds of readings to serve
// <0: number of tuples to server per channel (e.g. -3 will serve 3 tuples)
},

// realtime notification settings
//"push": [
// {
// "url": "http://127.0.0.1:5582" // notification destination, e.g. frontend push-server
// }
//],

// mqtt client support (if ENABLE_MQTT set at cmake generation)
"mqtt": {
"enabled": false, // enable mqtt client. needs host and port as well
"host": "test.mosquitto.org", // mqtt server addr
"port": 1883, // 1883 for unencrypted, 8883 enc, 8884 enc cert needed,
"cafile": "", // optional file with server CA
"capath": "", // optional path for server CAs. see mosquitto.conf. Specify only cafile or capath
"certfile": "", // optional file for your client certificate (e.g. client.crt)
"keyfile": "", // optional path for your client certficate private key (e.g. client.key)
"keypass": "", // optional password for your private key
"keepalive": 30, // optional keepalive in seconds.
"topic": "vzlogger/data", // optional topic dont use $ at start and no / at end
"id": "", // optional static id, if not set "vzlogger_<pid>" will be used
"user": "", // optional user name for the mqtt server
"pass": "", // optional password for the mqtt server
"retain": false, // optional use retain message flag
"rawAndAgg": false, // optional publish raw values even if agg mode is used
"qos": 0, // optional quality of service, default is 0
"timestamp": false // optional whether to include a timestamp in the payload
},

// Meter configuration
"meters": [
{
// Example SOS S0 meter

"enabled": true, // disabled meters will be ignored (default)
"allowskip": false, // errors when opening meter may be ignored if enabled
"protocol": "sos_s0", // meter protocol, see 'vzlogger -h' for full list
"device": "/dev/ttyACM0", // meter device

// "aggtime": 20, // aggregate meter readings and send middleware update after <aggtime> seconds
"interval": -1, // wait time in seconds until new values will transmitted to middleware
// "send_zero": false,

"channels": [{
"uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeee",
"identifier": "M1", // S0 Port identifier
"api": "null",
"aggmode": "SUM" // aggregation mode: aggregate meter readings during <aggtime> interval
}, {
"uuid": "aaaaaaaa-bbbb-cccc-dddd-ffffffff",
"identifier": "M2", // S0 Port identifier
"api": "null",
"aggmode": "SUM" // aggregation mode: aggregate meter readings during <aggtime> interval
}, {
"uuid": "aaaaaaaa-bbbb-cccc-dddd-11111111",
"identifier": "M3", // S0 Port identifier
"api": "null",
"aggmode": "SUM" // aggregation mode: aggregate meter readings during <aggtime> interval
}, {
"uuid": "aaaaaaaa-bbbb-cccc-dddd-22222222",
"identifier": "M4", // S0 Port identifier
"api": "null",
"aggmode": "SUM" // aggregation mode: aggregate meter readings during <aggtime> interval
}, {
"uuid": "aaaaaaaa-bbbb-cccc-dddd-33333333",
"identifier": "M5", // S0 Port identifier
"api": "null",
"aggmode": "SUM" // aggregation mode: aggregate meter readings during <aggtime> interval
}
]
}
]
}

32 changes: 31 additions & 1 deletion etc/vzlogger_generic.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,35 @@
"required": ["protocol"]
}]
},

"meterSOS_S0": {
"title": "SOS S0 Pulse meter devices",
"allOf": [{
"$ref": "#/definitions/meter"
}, {
"properties": {
"protocol": {
"type": "string",
"enum": ["sos_s0"],
"default": "sos_s0"
},
"device": {
"type": "string",
"description": "UART device the device is connected to. E.g. /dev/ttyACM0"
},
"read_timeout": {
"type": "integer",
"default": 10,
"description": "Read timeout in secs. Data readout is considered finished if no state change after that timeout."
},
"send_zero": {
"type": "boolean",
"default": false,
"description": "If active/true send data once a second even if no impulses have been received. Use aggregation is this case to reduce frequency."
}
},
"required": ["protocol", "device"]
}]
},
"channels": {
"type": "array",
"items": {
Expand Down Expand Up @@ -1009,6 +1037,8 @@
"$ref": "#/definitions/meterOMS"
}, {
"$ref": "#/definitions/meterW1therm"
}, {
"$ref": "#/definitions/meterSOS_S0"
}

]
Expand Down
1 change: 1 addition & 0 deletions include/meter_protocol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@ typedef enum meter_procotol {
meter_protocol_ocr,
meter_protocol_w1therm,
meter_protocol_oms,
meter_protocol_sos_s0,
} meter_protocol_t;
#endif /* _meter_protocol_hpp_ */
72 changes: 72 additions & 0 deletions include/protocols/MeterSOS_S0.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Plaintext protocol of S0 Pulse meter devices
* --> https://www.sossolutions.nl/5-kanaals-s0-pulse-meter-op-usb
*
* The device is a USB s0 logger device.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe just a little bit more description of the communication, at least "sending a text-based protocol over a usb-connected uart interface"?
maybe the usb-IDs used by the device or a udev rule to identify it.

*
* The protocol is defined as follows:
* ‘ID:x:I:y:M1:a:b:M2:c:d:M3:e:f:M4:g:h:M5:i:j’’
* - x = ID des S0 pulse meter (unique)
* - y = number of seconds since last message (default: 10 second)
* - M1,M2,M3,M4,M5 = identifier name for corresponding S0 port on device
* - a,c,e,g,i = number of pulses since last message
* - b,d,f,h,j = total number of pulses since start of device
*
* @package vzlogger
* @copyright Copyright (c) 2011 - 2023, The volkszaehler.org project
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
* @author Lurchi70 <https://github.com/Lurchi70/vzlogger>
*/
/*
* This file is part of volkzaehler.org
*
* volkzaehler.org 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
* any later version.
*
* volkzaehler.org 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 volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
*/
// RW: added ack
#ifndef _SOS_S0_H_
#define _SOS_S0_H_

#include <protocols/Protocol.hpp>
#include <termios.h>

class MeterSOS_S0 : public vz::protocol::Protocol {
public:
MeterSOS_S0(std::list<Option> &options);
virtual ~MeterSOS_S0();

int open();
int close();
ssize_t read(std::vector<Reading> &rds, size_t n);
virtual bool allowInterval() const {
return false;
} // only allow conf setting interval if pull is set (otherwise meter sends autom.)

const char *device() const { return _device.c_str(); }

private:
std::string _device;
std::string _dump_file;
int _baudrate;
parity_type_t _parity;
size_t _read_timeout_s;
bool _send_zero;

int _fd; /* file descriptor of port */
struct termios _oldtio; /* required to reset port */

int _openDevice(struct termios *old_tio, speed_t baudrate);
bool _is_valid_fd();
};

#endif /* _D0_H_ */
6 changes: 6 additions & 0 deletions src/Meter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <protocols/MeterFluksoV2.hpp>
#include <protocols/MeterRandom.hpp>
#include <protocols/MeterS0.hpp>
#include <protocols/MeterSOS_S0.hpp>
#ifdef SML_SUPPORT
#include <protocols/MeterSML.hpp>
#endif
Expand All @@ -61,6 +62,7 @@ static const meter_details_t protocols[] = {
METER_DETAIL(fluksov2, Fluksov2, "Read from Flukso's onboard SPI fifo", 16),
METER_DETAIL(s0, S0, "S0-meter directly connected to RS232", 4),
METER_DETAIL(d0, D0, "DLMS/IEC 62056-21 plaintext protocol", 400),
METER_DETAIL(sos_s0, SOS_S0, "SOS S0 Pulse Meter via USB", 5),
#ifdef SML_SUPPORT
METER_DETAIL(sml, Sml, "Smart Message Language as used by EDL-21, eHz and SyM²", 32),
#endif // SML_SUPPORT
Expand Down Expand Up @@ -187,6 +189,10 @@ Meter::Meter(std::list<Option> pOptions) : _name("meter") {
_identifier = ReadingIdentifier::Ptr(new ObisIdentifier());
break;
#endif
case meter_protocol_sos_s0:
_protocol = vz::protocol::Protocol::Ptr(new MeterSOS_S0(pOptions));
_identifier = ReadingIdentifier::Ptr(new StringIdentifier());
break;
default:
break;
}
Expand Down
1 change: 1 addition & 0 deletions src/Reading.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ ReadingIdentifier::Ptr reading_id_parse(meter_protocol_t protocol, const char *s
case meter_protocol_file:
case meter_protocol_exec:
case meter_protocol_s0:
case meter_protocol_sos_s0:
case meter_protocol_ocr:
case meter_protocol_w1therm:
rid = ReadingIdentifier::Ptr(new StringIdentifier(string));
Expand Down
1 change: 1 addition & 0 deletions src/protocols/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ endif( OMS_SUPPORT )
set(proto_srcs
MeterS0.cpp ../../include/protocols/MeterS0.hpp
MeterD0.cpp ../../include/protocols/MeterD0.hpp
MeterSOS_S0.cpp ../../include/protocols/MeterSOS_S0.hpp
${sml_srcs}
MeterFluksoV2.cpp
${ocr_srcs}
Expand Down
Loading
Loading