-
Notifications
You must be signed in to change notification settings - Fork 49
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
Expose the workarounds
struct as part of public API
#133
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,6 +56,43 @@ typedef int64_t i64; | |
#define SML_TYPE_NUMBER_32 sizeof(u32) | ||
#define SML_TYPE_NUMBER_64 sizeof(u64) | ||
|
||
// A bitmap to configure workarounds. | ||
typedef int16_t sml_workarounds; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would make this |
||
|
||
/* | ||
* Workaround for certain DZG meters that encode the consumption wrongly. | ||
* Affected: | ||
* - Model TODO with serial numbers starting with 6 (in decimal) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. DVS74 |
||
* | ||
* We only get the serial number, not the meter model via SML. Since model | ||
* DWSB.2TH (serial starting with 4) does not exhibit this bug, we can't | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is that an EWE specific model? I only found this then again, there's this which documents the whole series - so maybe this is the whole DVSB series? |
||
* apply the workaround automatically. | ||
* | ||
* The value uses a scaler of -2, so e.g. 328.05 should be | ||
* encoded as an unsigned int with 2 bytes (called Unsigned16 in the standard): | ||
* 63 80 25 (0x8025 == 32805 corresponds to 328.05W) | ||
* or as an unsigned int with 3 bytes (not named in the standard): | ||
* 64 00 80 25 | ||
* or as a signed int with 3 bytes (not named in the standard): | ||
* 54 00 80 25 | ||
* but they encode it as a signed int with 2 bytes (called Integer16 in the standard): | ||
* 53 80 25 | ||
* which reads as -32731 corresponding to -327.31W. | ||
* | ||
* Luckily, it doesn't attempt to do any compression on | ||
* negative values, they're always encoded as, e.g. | ||
* 55 ff fe 13 93 (== -126061 -> -1260.61W) | ||
* | ||
* Since we cannot have positive values >= 0x80000000 | ||
* (that would be 21474836.48 W, yes, >21MW), we can | ||
* assume that for 1, 2, 3 bytes, if they look signed, | ||
* they really were intended to be unsigned. | ||
* | ||
* Note that this will NOT work if a meter outputs negative | ||
* values compressed as well - but mine doesn't. | ||
*/ | ||
#define SML_WORKAROUND_DZG_NEGATIVE 0x0001 | ||
|
||
// This sml_buffer is used in two different use-cases. | ||
// | ||
// Parsing: the raw data is in the buffer field, | ||
|
@@ -74,6 +111,7 @@ typedef struct { | |
size_t cursor; | ||
int error; | ||
char *error_msg; | ||
sml_workarounds workarounds; | ||
} sml_buffer; | ||
|
||
sml_buffer *sml_buffer_init(size_t length); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,11 +27,14 @@ | |
// EDL meter must provide at least 250 bytes as a receive buffer | ||
#define SML_FILE_BUFFER_LENGTH 512 | ||
|
||
sml_file *sml_file_parse(unsigned char *buffer, size_t buffer_len) { | ||
sml_file *sml_file_parse(unsigned char *buffer, | ||
size_t buffer_len, | ||
const sml_workarounds workarounds) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i'm a bit confused that our "constructor" is named |
||
sml_file *file = (sml_file *)malloc(sizeof(sml_file)); | ||
*file = (sml_file){.messages = NULL, .messages_len = 0, .buf = NULL}; | ||
|
||
sml_buffer *buf = sml_buffer_init(buffer_len); | ||
buf->workarounds = workarounds; | ||
memcpy(buf->buffer, buffer, buffer_len); | ||
file->buf = buf; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in "production" we should probably not have an extra flag for each workaround, but i guess in an example program and while there is only one, this is ok :)