Giter Site home page Giter Site logo

volkszaehler / libsml Goto Github PK

View Code? Open in Web Editor NEW

This project forked from dailab/libsml

82.0 17.0 47.0 572 KB

Implementation in C of the Smart Message Language (SML) protocol

License: GNU General Public License v3.0

Makefile 0.75% C 99.20% Shell 0.06%
smartmeter sml

libsml's Introduction

libSML

Build Status Join the chat at https://gitter.im/volkszaehler/volkszaehler.org

libSML is a library which implements the Smart Message Language (SML) protocol specified by VDE's Forum Netztechnik/Netzbetrieb (FNN). It can be utilized to communicate to FNN specified Smart Meters or Smart Meter components (EDL/MUC).

This is the official libSML repo, the original dailab libsml repo on GitHub is dead

Usage

An example how to use libSML is in the examples directory.

Dependencies

Ubuntu

apt-get install uuid-dev uuid-runtime

Compilation

make

The resulting binaries are located in sml/lib

Debian and Raspbian Packages

Hosted By: Cloudsmith

We now build Debian packages for amd64, armhf and arm64 and Raspbian packages for armhf as part of our releases. Unfortunately Debian armhf packages do not run on Raspberry Pi 1 although the architecture on the RPi is named armhf. Using Raspian armhf packages fixes that.

The ones attached to the release are meant for debian trixie. These and packages for bookworm and bullseye are also provided through a repository graciously provided by Cloudsmith.

The setup of the repository is also explained by Cloudsmith. This boils down to adding a file to /etc/apt/sources.list.d/ containing

deb [signed-by=/usr/share/keyrings/volkszaehler-volkszaehler-org-project-archive-keyring.gpg] https://dl.cloudsmith.io/public/volkszaehler/volkszaehler-org-project/deb/debian bookworm main
deb-src [signed-by=/usr/share/keyrings/volkszaehler-volkszaehler-org-project-archive-keyring.gpg] https://dl.cloudsmith.io/public/volkszaehler/volkszaehler-org-project/deb/debian bookworm main

You need to replace bookworm with your distro and debian with raspbian in case you are using an RPi 1. You also need to retrieve our repository key as a trusted one.

curl -1sLf "https://dl.cloudsmith.io/public/volkszaehler/volkszaehler-org-project/gpg.21DBDAC56DF44DA1.key" | \
	gpg --dearmor > /usr/share/keyrings/volkszaehler-volkszaehler-org-project-archive-keyring.gpg

There is also a libsml package that is part of Debian. While the version in older Debian releases is somewhat outdated the version in trixie is recent. Other than the project packages the official Debian package has a version postfix separated by a hyphen (e.g. 1.0.2-3). It has minor differences in packaging and is maintained as part of the project in the debian branch.

Testing

For testing data have a look at https://github.com/devZer0/libsml-testing

License

Copyright 2011 Juri Glass, Mathias Runge, Nadim El Sayed - DAI-Labor, TU-Berlin Copyright 2014-2018 libSML contributors

libSML 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.

libSML 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.

See the file LICENSE for the full license text.

Thanks

Steffen Vogel, Thorben Thuermer, Daniel Pauli, He Bowei

Thirdparty Acknowledgements

This product includes software developed for the Unity Project, by Mike Karlesky, Mark VanderVoord, and Greg Williams and other contributors

libsml's People

Contributors

ampelbein avatar andig avatar dapaulid avatar dbeyer avatar devzer0 avatar hacki11 avatar hmueller01 avatar jmberg avatar juriglx avatar mbehr1 avatar mh-er avatar mruettgers avatar mtdcr avatar narc-ontakac2 avatar neiser avatar r00t- avatar rotorman avatar stv0g avatar thecount avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libsml's Issues

timeout

Hi!
I use the sml_server for getting the counter values with the command:
Z1_280=$(/usr/bin/sml_server /dev/zaehler_1 | head -n10 | grep -oP '2\.8\.0\*255#\K.*(?=#)')

This call is blocking.

I have 4 counters and if one of the IR reading heads does not answer, it blocks forever. So, it would be fine to have a timeout value.

At the moment I solved it with this:
while true; do
dd if=/dev/zaehler_1 of=Z1.bin bs=1 count=8192 iflag=fullblock status=none &
dd if=/dev/zaehler_2 of=Z2.bin bs=1 count=8192 iflag=fullblock status=none &
sleep 30
pkill dd

Two counters for getting the values Z1 1.8.0/2.8.0 and Z2 1.8.1/1.8.2/2.8.0.

Unfortunately I have no idea how to integrate a timeout into the sml_server.

cheers
Christian

PS
Nice work!

More Examples

I started working with libsml. So i try to understand this library.

The server example is good. But I miss an example for creating a SML Message to request values from an bidrectional meter.

An perhaps a short example to create a client Example. Creating list_response_message.

So could someone who are familar with sml can create such examples ? Or help howto create these Messages.

So I can test the request/response on my machine with the Server and a Client.

Not builing on current gcc version 10

libSML does not build fine on gcc 10.x

~% make clean && docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp gcc:10 make   
make[1]: Entering directory '/usr/src/myapp/sml'
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_file.o src/sml_file.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_attention_response.o src/sml_attention_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_transport.o src/sml_transport.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_octet_string.o src/sml_octet_string.c
src/sml_octet_string.c: In function 'sml_octet_string_parse':
src/sml_octet_string.c:80:17: warning: comparison of integer expressions of different signedness: 'int' and 'size_t' {aka 'long unsigned int'} [-Wsign-compare]
   80 |  if (l < 0 || l >= (buf->buffer_len - buf->cursor)) { // sanity check: doesnt fit into buffer...
      |                 ^~
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_shared.o src/sml_shared.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_number.o src/sml_number.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_message.o src/sml_message.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_time.o src/sml_time.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_list.o src/sml_list.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_status.o src/sml_status.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_value.o src/sml_value.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_tree.o src/sml_tree.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_boolean.o src/sml_boolean.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_crc16.o src/sml_crc16.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_open_request.o src/sml_open_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_open_response.o src/sml_open_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_list_request.o src/sml_get_list_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_list_response.o src/sml_get_list_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_close_request.o src/sml_close_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_close_response.o src/sml_close_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_set_proc_parameter_request.o src/sml_set_proc_parameter_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_proc_parameter_request.o src/sml_get_proc_parameter_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_proc_parameter_response.o src/sml_get_proc_parameter_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_profile_pack_request.o src/sml_get_profile_pack_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_profile_pack_response.o src/sml_get_profile_pack_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_profile_list_request.o src/sml_get_profile_list_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_profile_list_response.o src/sml_get_profile_list_response.c
cc -Wl,-soname=libsml.so.1 -shared -o lib/libsml.so.1 src/sml_file.o src/sml_attention_response.o src/sml_transport.o src/sml_octet_string.o src/sml_shared.o src/sml_number.o src/sml_message.o src/sml_time.o src/sml_list.o src/sml_status.o src/sml_value.o src/sml_tree.o src/sml_boolean.o src/sml_crc16.o src/sml_open_request.o src/sml_open_response.o src/sml_get_list_request.o src/sml_get_list_response.o src/sml_close_request.o src/sml_close_response.o src/sml_set_proc_parameter_request.o src/sml_get_proc_parameter_request.o src/sml_get_proc_parameter_response.o src/sml_get_profile_pack_request.o src/sml_get_profile_pack_response.o src/sml_get_profile_list_request.o src/sml_get_profile_list_response.o -luuid
ar -rs lib/libsml.a src/sml_file.o src/sml_attention_response.o src/sml_transport.o src/sml_octet_string.o src/sml_shared.o src/sml_number.o src/sml_message.o src/sml_time.o src/sml_list.o src/sml_status.o src/sml_value.o src/sml_tree.o src/sml_boolean.o src/sml_crc16.o src/sml_open_request.o src/sml_open_response.o src/sml_get_list_request.o src/sml_get_list_response.o src/sml_close_request.o src/sml_close_response.o src/sml_set_proc_parameter_request.o src/sml_get_proc_parameter_request.o src/sml_get_proc_parameter_response.o src/sml_get_profile_pack_request.o src/sml_get_profile_pack_response.o src/sml_get_profile_list_request.o src/sml_get_profile_list_response.o
ar: creating lib/libsml.a
ld -r -o lib/libsml.o src/sml_file.o src/sml_attention_response.o src/sml_transport.o src/sml_octet_string.o src/sml_shared.o src/sml_number.o src/sml_message.o src/sml_time.o src/sml_list.o src/sml_status.o src/sml_value.o src/sml_tree.o src/sml_boolean.o src/sml_crc16.o src/sml_open_request.o src/sml_open_response.o src/sml_get_list_request.o src/sml_get_list_response.o src/sml_close_request.o src/sml_close_response.o src/sml_set_proc_parameter_request.o src/sml_get_proc_parameter_request.o src/sml_get_proc_parameter_response.o src/sml_get_profile_pack_request.o src/sml_get_profile_pack_response.o src/sml_get_profile_list_request.o src/sml_get_profile_list_response.o
make[1]: Leaving directory '/usr/src/myapp/sml'
make[1]: Entering directory '/usr/src/myapp/examples'
cc -I../sml/include/ -g -std=c99 -Wall -Wextra -pedantic -c sml_server.c -o sml_server.o
cc sml_server.o ../sml/lib/libsml.a -lm -luuid -o sml_server
make[1]: Leaving directory '/usr/src/myapp/examples'
make[1]: Entering directory '/usr/src/myapp/test'
make[2]: Entering directory '/usr/src/myapp/sml'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/usr/src/myapp/sml'
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c unity/unity.c -o unity/unity.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c unity/unity_fixture.c -o unity/unity_fixture.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/test_helper.c -o src/test_helper.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_octet_string_test.c -o src/sml_octet_string_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_buffer_test.c -o src/sml_buffer_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_number_test.c -o src/sml_number_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_boolean_test.c -o src/sml_boolean_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_value_test.c -o src/sml_value_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_status_test.c -o src/sml_status_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_list_test.c -o src/sml_list_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_time_test.c -o src/sml_time_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_tree_test.c -o src/sml_tree_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_file_test.c -o src/sml_file_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_open_request_test.c -o src/sml_open_request_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_get_profile_pack_request_test.c -o src/sml_get_profile_pack_request_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_message_test.c -o src/sml_message_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -luuid unity/unity.o unity/unity_fixture.o src/test_helper.o src/sml_octet_string_test.o src/sml_buffer_test.o src/sml_number_test.o src/sml_boolean_test.o src/sml_value_test.o src/sml_status_test.o src/sml_list_test.o src/sml_time_test.o src/sml_tree_test.o src/sml_file_test.o src/sml_open_request_test.o src/sml_get_profile_pack_request_test.o src/sml_message_test.o ../sml/lib/libsml.a test_main.c -o test -luuid
/usr/bin/ld: src/sml_buffer_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_number_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_boolean_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_value_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_status_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_list_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_time_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_tree_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_file_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_open_request_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_get_profile_pack_request_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_message_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:33: test] Error 1
make[1]: Leaving directory '/usr/src/myapp/test'
make: *** [Makefile:5: all] Error 2

Software is building fine in gcc 9.3:

~# make clean && docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp gcc:9.3 make
make[1]: Entering directory '/usr/src/myapp/sml'
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_file.o src/sml_file.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_attention_response.o src/sml_attention_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_transport.o src/sml_transport.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_octet_string.o src/sml_octet_string.c
src/sml_octet_string.c: In function 'sml_octet_string_parse':
src/sml_octet_string.c:80:17: warning: comparison of integer expressions of different signedness: 'int' and 'size_t' {aka 'long unsigned int'} [-Wsign-compare]
   80 |  if (l < 0 || l >= (buf->buffer_len - buf->cursor)) { // sanity check: doesnt fit into buffer...
      |                 ^~
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_shared.o src/sml_shared.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_number.o src/sml_number.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_message.o src/sml_message.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_time.o src/sml_time.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_list.o src/sml_list.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_status.o src/sml_status.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_value.o src/sml_value.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_tree.o src/sml_tree.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_boolean.o src/sml_boolean.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_crc16.o src/sml_crc16.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_open_request.o src/sml_open_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_open_response.o src/sml_open_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_list_request.o src/sml_get_list_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_list_response.o src/sml_get_list_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_close_request.o src/sml_close_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_close_response.o src/sml_close_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_set_proc_parameter_request.o src/sml_set_proc_parameter_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_proc_parameter_request.o src/sml_get_proc_parameter_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_proc_parameter_response.o src/sml_get_proc_parameter_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_profile_pack_request.o src/sml_get_profile_pack_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_profile_pack_response.o src/sml_get_profile_pack_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_profile_list_request.o src/sml_get_profile_list_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic   -c -o src/sml_get_profile_list_response.o src/sml_get_profile_list_response.c
cc -Wl,-soname=libsml.so.1 -shared -o lib/libsml.so.1 src/sml_file.o src/sml_attention_response.o src/sml_transport.o src/sml_octet_string.o src/sml_shared.o src/sml_number.o src/sml_message.o src/sml_time.o src/sml_list.o src/sml_status.o src/sml_value.o src/sml_tree.o src/sml_boolean.o src/sml_crc16.o src/sml_open_request.o src/sml_open_response.o src/sml_get_list_request.o src/sml_get_list_response.o src/sml_close_request.o src/sml_close_response.o src/sml_set_proc_parameter_request.o src/sml_get_proc_parameter_request.o src/sml_get_proc_parameter_response.o src/sml_get_profile_pack_request.o src/sml_get_profile_pack_response.o src/sml_get_profile_list_request.o src/sml_get_profile_list_response.o -luuid
ar -rs lib/libsml.a src/sml_file.o src/sml_attention_response.o src/sml_transport.o src/sml_octet_string.o src/sml_shared.o src/sml_number.o src/sml_message.o src/sml_time.o src/sml_list.o src/sml_status.o src/sml_value.o src/sml_tree.o src/sml_boolean.o src/sml_crc16.o src/sml_open_request.o src/sml_open_response.o src/sml_get_list_request.o src/sml_get_list_response.o src/sml_close_request.o src/sml_close_response.o src/sml_set_proc_parameter_request.o src/sml_get_proc_parameter_request.o src/sml_get_proc_parameter_response.o src/sml_get_profile_pack_request.o src/sml_get_profile_pack_response.o src/sml_get_profile_list_request.o src/sml_get_profile_list_response.o
ar: creating lib/libsml.a
ld -r -o lib/libsml.o src/sml_file.o src/sml_attention_response.o src/sml_transport.o src/sml_octet_string.o src/sml_shared.o src/sml_number.o src/sml_message.o src/sml_time.o src/sml_list.o src/sml_status.o src/sml_value.o src/sml_tree.o src/sml_boolean.o src/sml_crc16.o src/sml_open_request.o src/sml_open_response.o src/sml_get_list_request.o src/sml_get_list_response.o src/sml_close_request.o src/sml_close_response.o src/sml_set_proc_parameter_request.o src/sml_get_proc_parameter_request.o src/sml_get_proc_parameter_response.o src/sml_get_profile_pack_request.o src/sml_get_profile_pack_response.o src/sml_get_profile_list_request.o src/sml_get_profile_list_response.o
make[1]: Leaving directory '/usr/src/myapp/sml'
make[1]: Entering directory '/usr/src/myapp/examples'
cc -I../sml/include/ -g -std=c99 -Wall -Wextra -pedantic -c sml_server.c -o sml_server.o
cc sml_server.o ../sml/lib/libsml.a -lm -luuid -o sml_server
make[1]: Leaving directory '/usr/src/myapp/examples'
make[1]: Entering directory '/usr/src/myapp/test'
make[2]: Entering directory '/usr/src/myapp/sml'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/usr/src/myapp/sml'
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c unity/unity.c -o unity/unity.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c unity/unity_fixture.c -o unity/unity_fixture.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/test_helper.c -o src/test_helper.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_octet_string_test.c -o src/sml_octet_string_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_buffer_test.c -o src/sml_buffer_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_number_test.c -o src/sml_number_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_boolean_test.c -o src/sml_boolean_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_value_test.c -o src/sml_value_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_status_test.c -o src/sml_status_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_list_test.c -o src/sml_list_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_time_test.c -o src/sml_time_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_tree_test.c -o src/sml_tree_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_file_test.c -o src/sml_file_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_open_request_test.c -o src/sml_open_request_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_get_profile_pack_request_test.c -o src/sml_get_profile_pack_request_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_message_test.c -o src/sml_message_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -luuid unity/unity.o unity/unity_fixture.o src/test_helper.o src/sml_octet_string_test.o src/sml_buffer_test.o src/sml_number_test.o src/sml_boolean_test.o src/sml_value_test.o src/sml_status_test.o src/sml_list_test.o src/sml_time_test.o src/sml_tree_test.o src/sml_file_test.o src/sml_open_request_test.o src/sml_get_profile_pack_request_test.o src/sml_message_test.o ../sml/lib/libsml.a test_main.c -o test -luuid
Unity test run 1 of 1
........................................................................................
-----------------------
88 Tests 0 Failures 0 Ignored
OK
libsml: error: message type 0900 not yet implemented
libsml: NYI: sml_message_body_free for message type 0900
libsml: warning: could not read the whole file
make[1]: Leaving directory '/usr/src/myapp/test'

I think there maybe will be a simple solution?

Thanks!

fix gcc-10 build

if this is not fixed, libsml (and dependant packages) won't be in the next debian release.

Date: Fri, 17 Apr 2020 11:05:01 +0000
The package fails to build in a test rebuild on at least amd64 with
gcc-10/g++-10, but succeeds to build with gcc-9/g++-9. The
severity of this report will be raised before the bullseye release,
so nothing has to be done for the buster release.

Severity set to 'serious' from 'normal' (Wed, 22 Jul 2020 08:05:49 GMT)

-- https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=957478

The next release of Debian is codenamed bullseye — no release date has been set
Debian 10 (buster) — current stable release

--- https://www.debian.org/releases/

the actual error seems rather trivial,
the tests fail to link due to conflicting variable names (buf). i remember reading something about changed variable scoping in object files.

make[2]: Leaving directory '/home/r00t/libsml/sml'
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -luuid unity/unity.o unity/unity_fixture.o src/test_helper.o src/sml_octet_string_test.o src/sml_buffer_test.o src/sml_number_test.o src/sml_boolean_test.o src/sml_value_test.o src/sml_status_test.o src/sml_list_test.o src/sml_time_test.o src/sml_tree_test.o src/sml_file_test.o src/sml_open_request_test.o src/sml_get_profile_pack_request_test.o src/sml_message_test.o ../sml/lib/libsml.a test_main.c -o test -luuid
/usr/bin/ld: src/sml_buffer_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_number_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_boolean_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here
/usr/bin/ld: src/sml_value_test.o:(.bss+0x8): multiple definition of `buf'; src/sml_octet_string_test.o:(.bss+0x8): first defined here

several new warnings after the last commits

huh, think you are very productive with merging :)

since there have so many changes i wanted to give the latest version a try and now getting lots of warnings which have not been there before:

make[1]: Entering directory '/root/libsml/libsml/sml'
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_file.o src/sml_file.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_attention_response.o src/sml_attention_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_transport.o src/sml_transport.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_octet_string.o src/sml_octet_string.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_shared.o src/sml_shared.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_number.o src/sml_number.c
src/sml_number.c: In function ‘sml_number_init’:
src/sml_number.c:30:49: warning: unused parameter ‘type’ [-Wunused-parameter]
void _sml_number_init(u64 number, unsigned char type, int size) {
^
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_message.o src/sml_message.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_time.o src/sml_time.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_list.o src/sml_list.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_status.o src/sml_status.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_value.o src/sml_value.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_tree.o src/sml_tree.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_boolean.o src/sml_boolean.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_crc16.o src/sml_crc16.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_open_request.o src/sml_open_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_open_response.o src/sml_open_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_get_list_request.o src/sml_get_list_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_get_list_response.o src/sml_get_list_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_close_request.o src/sml_close_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_close_response.o src/sml_close_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_set_proc_parameter_request.o src/sml_set_proc_parameter_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_get_proc_parameter_request.o src/sml_get_proc_parameter_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_get_proc_parameter_response.o src/sml_get_proc_parameter_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_get_profile_pack_request.o src/sml_get_profile_pack_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_get_profile_pack_response.o src/sml_get_profile_pack_response.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_get_profile_list_request.o src/sml_get_profile_list_request.c
cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_get_profile_list_response.o src/sml_get_profile_list_response.c
ld -luuid -shared -soname libsml.so.1 -o lib/libsml.so.1 src/sml_file.o src/sml_attention_response.o src/sml_transport.o src/sml_octet_string.o src/sml_shared.o src/sml_number.o src/sml_message.o src/sml_time.o src/sml_list.o src/sml_status.o src/sml_value.o src/sml_tree.o src/sml_boolean.o src/sml_crc16.o src/sml_open_request.o src/sml_open_response.o src/sml_get_list_request.o src/sml_get_list_response.o src/sml_close_request.o src/sml_close_response.o src/sml_set_proc_parameter_request.o src/sml_get_proc_parameter_request.o src/sml_get_proc_parameter_response.o src/sml_get_profile_pack_request.o src/sml_get_profile_pack_response.o src/sml_get_profile_list_request.o src/sml_get_profile_list_response.o
ar -rs lib/libsml.a src/sml_file.o src/sml_attention_response.o src/sml_transport.o src/sml_octet_string.o src/sml_shared.o src/sml_number.o src/sml_message.o src/sml_time.o src/sml_list.o src/sml_status.o src/sml_value.o src/sml_tree.o src/sml_boolean.o src/sml_crc16.o src/sml_open_request.o src/sml_open_response.o src/sml_get_list_request.o src/sml_get_list_response.o src/sml_close_request.o src/sml_close_response.o src/sml_set_proc_parameter_request.o src/sml_get_proc_parameter_request.o src/sml_get_proc_parameter_response.o src/sml_get_profile_pack_request.o src/sml_get_profile_pack_response.o src/sml_get_profile_list_request.o src/sml_get_profile_list_response.o
ar: creating lib/libsml.a
ld -r -o lib/libsml.o src/sml_file.o src/sml_attention_response.o src/sml_transport.o src/sml_octet_string.o src/sml_shared.o src/sml_number.o src/sml_message.o src/sml_time.o src/sml_list.o src/sml_status.o src/sml_value.o src/sml_tree.o src/sml_boolean.o src/sml_crc16.o src/sml_open_request.o src/sml_open_response.o src/sml_get_list_request.o src/sml_get_list_response.o src/sml_close_request.o src/sml_close_response.o src/sml_set_proc_parameter_request.o src/sml_get_proc_parameter_request.o src/sml_get_proc_parameter_response.o src/sml_get_profile_pack_request.o src/sml_get_profile_pack_response.o src/sml_get_profile_list_request.o src/sml_get_profile_list_response.o
make[1]: Leaving directory '/root/libsml/libsml/sml'
make[1]: Entering directory '/root/libsml/libsml/examples'
cc -I../sml/include/ -g -std=c99 -Wall -Wextra -pedantic -c sml_server.c -o sml_server.o
sml_server.c: In function ‘main’:
sml_server.c:79:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
int main(int argc, char *_argv) {
^
sml_server.c:79:27: warning: unused parameter ‘argv’ [-Wunused-parameter]
int main(int argc, char *_argv) {
^
cc -I../sml/include/ -g -std=c99 -Wall -Wextra -pedantic sml_server.o -luuid ../sml/lib/libsml.a -o sml_server -luuid
make[1]: Leaving directory '/root/libsml/libsml/examples'
make[1]: Entering directory '/root/libsml/libsml/test'
make[2]: Entering directory '/root/libsml/libsml/sml'
make[2]: Nothing to be done for 'libsml'.
make[2]: Leaving directory '/root/libsml/libsml/sml'
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c unity/unity.c -o unity/unity.o
unity/unity.c:17:8: warning: missing braces around initializer [-Wmissing-braces]
struct _Unity Unity = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , { 0 } };
^
unity/unity.c:17:8: warning: (near initialization for ‘Unity.AbortFrame[0]’) [-Wmissing-braces]
unity/unity.c:17:8: warning: missing initializer for field ‘__mask_was_saved’ of ‘struct __jmp_buf_tag’ [-Wmissing-field-initializers]
In file included from unity/unity_internals.h:11:0,
from unity/unity.h:12,
from unity/unity.c:7:
/usr/include/setjmp.h:41:9: note: ‘__mask_was_saved’ declared here
int _mask_was_saved; / Saved the signal mask? */
^
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c unity/unity_fixture.c -o unity/unity_fixture.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/test_helper.c -o src/test_helper.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_octet_string_test.c -o src/sml_octet_string_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_buffer_test.c -o src/sml_buffer_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_number_test.c -o src/sml_number_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_boolean_test.c -o src/sml_boolean_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_value_test.c -o src/sml_value_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_status_test.c -o src/sml_status_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_list_test.c -o src/sml_list_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_time_test.c -o src/sml_time_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_tree_test.c -o src/sml_tree_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_file_test.c -o src/sml_file_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_open_request_test.c -o src/sml_open_request_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_get_profile_pack_request_test.c -o src/sml_get_profile_pack_request_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/sml_message_test.c -o src/sml_message_test.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -luuid unity/unity.o unity/unity_fixture.o src/test_helper.o src/sml_octet_string_test.o src/sml_buffer_test.o src/sml_number_test.o src/sml_boolean_test.o src/sml_value_test.o src/sml_status_test.o src/sml_list_test.o src/sml_time_test.o src/sml_tree_test.o src/sml_file_test.o src/sml_open_request_test.o src/sml_get_profile_pack_request_test.o src/sml_message_test.o ../sml/lib/libsml.a test_main.c -o test -luuid
Unity test run 1 of 1

......................................................................................

86 Tests 0 Failures 0 Ignored
OK
make[1]: Leaving directory '/root/libsml/libsml/test'

Unsigned current Power Value

According to the SML protocol
https://www.vde.com/resource/blob/951000/252eb3cdf1c7f6cdea10847be399da0d/fnn-lastenheft-edl-1-0-2010-01-13-data.pdf
page 31 the direction (consumption or delivery) is marked using flag.
It seems the SMLlib is not honoring the flag, as it always shows positive values, even when delivering power.
At least in the EMZ ED300L no negative values are shown when delivering power
The (un)sign seems to be addressed already in Tasmota:
arendst/Tasmota#8001 (comment)
and finally in
arendst/Tasmota@61b9735
Maybe we can also add this in the SML lib...

Add note on README.md that this is the active libsml repo

google search for libsml still lists dailab repo as "the only one" and does not give a hint on volkszaehler/libsml being the correct/active one ( see https://www.google.com/search?q=libsml and http://demo.volkszaehler.org/pipermail/volkszaehler-dev/2015-January/004064.html )

so people could start taking a look at dead code and giving up frustrated

at least this repo should announce some info that it's a fork and that this is the active/maintained project and dailab repo is dead end.

maybe somebody with SEO experience could do something about the position in google search...

also mind: volkszaehler/volkszaehler.org#717

i also mailed debian maintainer, as debian seems to use the old dailab repo

Compile error "undefined reference to `test_helper_c2ptoi'"

Copy-pasted from the old repository: dailab#13

I tried to compile libsml on a fresh Debian 9 Stretch amd64 box. uuid-dev and uuid-runtime is installed. This happens:

make[1]: Entering directory '/home/roi/src/libsml/sml'
make[1]: Nothing to be done for 'libsml'.
make[1]: Leaving directory '/home/roi/src/libsml/sml'
make[1]: Entering directory '/home/roi/src/libsml/examples'
make[1]: 'sml_server' is up to date.
make[1]: Leaving directory '/home/roi/src/libsml/examples'
make[1]: Entering directory '/home/roi/src/libsml/test'
make[2]: Entering directory '/home/roi/src/libsml/sml'
make[2]: Nothing to be done for 'libsml'.
make[2]: Leaving directory '/home/roi/src/libsml/sml'
cc -I../sml/include/ -Wall -luuid unity/unity.o unity/unity_fixture.o src/test_helper.o src/sml_octet_string_test.o src/sml_buffer_test.o src/sml_number_test.o src/sml_boolean_test.o src/sml_value_test.o src/sml_status_test.o src/sml_list_test.o src/sml_time_test.o src/sml_tree_test.o src/sml_file_test.o src/sml_open_request_test.o src/sml_get_profile_pack_request_test.o src/sml_message_test.o ../sml/lib/libsml.a test_main.c -o test
src/test_helper.o: In function `hex2binary':
test_helper.c:(.text+0xa3): undefined reference to `test_helper_c2ptoi'
collect2: error: ld returned 1 exit status
Makefile:33: recipe for target 'test' failed
make[1]: *** [test] Error 1
make[1]: Leaving directory '/home/roi/src/libsml/test'
Makefile:3: recipe for target 'all' failed
make: *** [all] Error 2

Bug or did I do something wrong?

DZG - libsml: error: unrecognized sequence

Hello,
when feeding data from a DZG meter to libsml e.g. using sml_server /dev/lesekopf0 the process exits after a couple of seconds with libsml: error: unrecognized sequence.
Reading through past issues it seems this is related to experiences of others with DZG meters.
I checked and adjusted the lesekopf at the meter but the situation is unchanged - seems there are some packets that libsml does not interpret correctly.

1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225125.8#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#100.77#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225125.9#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#115.64#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225125.9#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#126.63#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225125.9#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#123.01#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.0#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#102.05#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.0#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#100.95#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.0#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#110.74#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.1#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#99.18#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.1#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#93.55#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.1#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#99.48#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.1#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#98.01#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.2#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#88.97#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.2#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#105.81#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.2#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#95.58#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.3#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#97.13#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.3#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#95.55#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.3#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#102.10#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.3#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#96.08#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.4#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#95.37#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.4#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#91.80#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.4#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#90.10#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.4#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#93.41#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.5#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#93.53#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.5#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#91.85#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.5#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#100.64#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.5#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#90.72#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.6#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#35.46#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.6#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#35.91#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.6#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#26.28#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.6#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#22.02#W
1-0:96.50.11#DZG#
1-0:96.1.0
255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0255#13225126.6#Wh
1-0:2.8.0
255#17498355.3#Wh
1-0:16.7.0255#25.68#W
1-0:96.50.1
1#DZG#
1-0:96.1.0255#0a 11 43 5a 57 01 02 81 4d 6f #
1-0:1.8.0
255#13225126.7#Wh
1-0:2.8.0255#17498355.3#Wh
1-0:16.7.0
255#91.11#W
libsml: error: unrecognized sequence

[Holley DTZ541] Error while parsing SML message: Error: Wrong TL-Field 0x65 for Choice!

Hi,

unfortunately there is an issue with the Holley DTZ541 Smart Meter which is currently installed in broad area in germany.
Here are mentions of the issue:
Apollon77/smartmeter-obis#63
coolchip/node-red-contrib-smartmeter#8
https://forum.iobroker.net/topic/25091/holley-dtz541-sml-1-04/2

There are two problems:

  1. SML_Time is wrong, missing bytes are:
    0x72: List of two
    0x62: uint8
    0x01 (CHOICE secIndex)
Bytes in [] are not provided by smart meter
 77
    070100010800FF
    65001C0104
    [726201]65011C1EB7
    621E
    52FF
    6500DC5328
    01
77
    070100020800FF
    65001C0104
    [726201]65011C1EB7
    621E
    52FF
    6200
    01

Possible Fix: Introduce hard coded workaround and add bytes during parsing

  1. CRC algorithm uses CRC-16/CCITT (KERMIT) instead of X-25
    Possible Fix: Introduce a switch to choose correct crc (to be discussed)

I can provide a pull request for both issues but i think both solutions should be discussed before hand. Mostly the second issue, i am not sure how to recognize to choose the second crc algorithm. Trying both seems like a sledge hammer solution.

Additionally, i will inform my provider but the meter is directly from china and i do not think my provider will forward this information to the right people.

Last i have to say that its a absolute no go to roll out such a device which is NOT capable of SML. Because of both issues there is no available device to read out the values. Here are 1.8.0 and 2.8.0, two of the most important ones..

add hint to libsml-testing or how to use binary dumps

i think it could be useful for people starting with libsml to know how to use sml_server with binary dumps, so feel free to add a hint to https://github.com/devZer0/libsml-testing or include binary dumps in libsml repo

$ ls -1 *.bin
DrNeuhaus_SMARTY_ix-130.bin
EMH_eHZ-GW8E2A500AK2.bin
EMH_eHZ-HW8E2A5L0EK2P_1.bin
EMH_eHZ-HW8E2A5L0EK2P.bin
EMH_eHZ-HW8E2AWL0EK2P.bin
EMH_eHZ-IW8E2A5L0EK2P_crash.bin

$ ls -1 *.bin |while read line;do echo ; echo $filename; cat $filename | ./sml_server -s - ;done

DrNeuhaus_SMARTY_ix-130.bin
129-129:199.130.3255#DNT#
1-0:0.0.9
255#09 01 44 4e 54 01 00 00 20 30 #
1-0:2.8.0255#4373.0#Wh
1-0:2.8.1
255#4373.0#Wh
1-0:2.8.2255#0.0#Wh
1-0:15.7.0
255#0#W
129-129:199.130.5*255#fe a5 d6 bc 65 8d 73 46 73 f5 79 00 51 d6 1c 2e bd 55 34 4a 62 85 68 6d e3 b6 45 ee 01 04 d6 5f 5a bb a6 cb 68 f1 bf cb 7f cf 94 f9 9c d4 d8 45 #

EMH_eHZ-GW8E2A500AK2.bin
129-129:199.130.3255#EMH#
1-0:0.0.0
255#02280816#
1-0:1.8.1255#14798112.9#Wh
1-0:1.8.2
255#2012.4#Wh
0-0:96.1.255255#0002280816#
1-0:1.7.0
255#13.8#W

EMH_eHZ-HW8E2A5L0EK2P_1.bin
129-129:199.130.3255#EMH#
1-0:0.0.9
255#06 45 4d 48 01 00 1d 46 15 ca #
1-0:1.8.0255#15141809.0#Wh
1-0:1.8.1
255#15141809.0#Wh
1-0:1.8.2255#0.0#Wh
1-0:15.7.0
255#1213.3#W
129-129:199.130.5255#'8d ad f3 a5 d8 01 1e ea 7c 1f 60 cf 20 2d 4e da da 88 98 7e b3 8e e0 f4 e4 ce 46 e8 6d 1a 2b e8 6b 2b 40 65 51 ad 6f 9e 93 67 aa d2 81 9d #

EMH_eHZ-HW8E2A5L0EK2P.bin
129-129:199.130.3255#EMH#
1-0:0.0.9
255#06 45 4d 48 01 02 71 53 c8 c6 #
1-0:1.8.0255#8391648.8#Wh
1-0:1.8.1
255#8391447.6#Wh
1-0:1.8.2255#201.2#Wh
1-0:15.7.0
255#163.5#W
129-129:199.130.5*255#(ab db f4 41 a5 ef 63 35 ec 38 bd 9c 0e 0a 79 03 0d a5 f4 a4 d7 39 5f 69 52 ef 7a 0b 0f f3 fc d1 37 f8 66 d1 14 15 4c f0 a9 52 42 de aa b1 7d #

EMH_eHZ-HW8E2AWL0EK2P.bin
129-129:199.130.3255#EMH#
1-0:0.0.9
255#01 a8 15 98 64 80 02 01 02 #
1-0:1.8.0255#5378499.0#Wh
1-0:1.8.1
255#5378499.0#Wh
1-0:1.8.2255#0.0#Wh
1-0:15.7.0
255#191.9#W
129-129:199.130.5*255#c2 fb 28 83 40 2a d8 7c 9e a2 7a cc fd 04 28 20 6f bd 06 56 6b a7 95 7c 5e b0 de 50 54 a4 40 ab d5 5a 6d 94 d6 77 17 6f dd f8 05 c2 3f 8d ef 1e #

EMH_eHZ-IW8E2A5L0EK2P_crash.bin
129-129:199.130.3255#EMH#
1-0:0.0.9
255#06 45 4d 48 01 07 19 7c 24 56 #
1-0:1.8.0255#2795692.7#Wh
1-0:1.8.1
255#2795692.7#Wh
1-0:1.8.2255#0.0#Wh
1-0:16.7.0
255#136.7#W
129-129:199.130.5255#8b 6a 0e 6e 12 f5 d9 80 f7 30 b6 bd 5e 19 41 83 4e b0 e4 3e 4a 63 23 d9 99 25 95 56 f5 e5 6e 04 04 98 c8 97 38 f0 f6 df f8 78 5b 04 5d 84 e0 d6 #
1-0:96.50.2
4#637#
Error in data stream. entry->value should not be NULL. Skipping this.

Build warning on raspbian

make[2]: Leaving directory '/home/pi/vzlogger/libs/libsml/sml'
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c unity/unity.c -o unity/unity.o
unity/unity.c:17:8: warning: missing braces around initializer [-Wmissing-braces]
 struct _Unity Unity = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , { 0 } };
    ^
unity/unity.c:17:8: warning: (near initialization for ‘Unity.AbortFrame[0]’) [-Wmissing-braces]
unity/unity.c:17:8: warning: missing initializer for field ‘__mask_was_saved’ of ‘struct __jmp_buf_tag’ [-Wmissing-field-initializers]
In file included from unity/unity_internals.h:11:0,
         from unity/unity.h:12,
         from unity/unity.c:7:
/usr/include/setjmp.h:41:9: note: ‘__mask_was_saved’ declared here
     int __mask_was_saved; /* Saved the signal mask?  */
     ^

Consistently reformat sources?

The codebase currently has formatting inconsistencies.

We've seen whitespace and other formatting changes on different PRs. The current codebase is using tabs which makes indenting hard, we're not enforcing a specific coding style.

Applying a tool like clang-format could be used to

  • reformat existing codebase and
  • enforce coding style on future PRs

I have tried clang-format with default settings but the changes are excessive. Amongst others, all tabs are changed to whitespace. Probably a good idea but will make life hard for any downstream forks (if there are any).

ping @mbehr1 are there any best practices that you could think of?

libsml: error: unknown type 0 in sml_value_to_double

i'm getting this libsml error messages. think they have been there for a long time, but i'd like to get rid of those and i think libsml does parsing wrong or incomplete.

Dr.Neuhaus Smarty ix-130:

./sml_server /dev/ttyUSB0
SML file (3 SML messages, 308 bytes)
SML message 101
SML message 701
SML message 201
OBIS data
libsml: error: unknown type 0 in sml_value_to_double
libsml: error: unknown type 0 in sml_value_to_double
1-0:2.8.0255#4373.0#Wh
1-0:2.8.1
255#4373.0#Wh
1-0:15.7.0*255#60.0#W
libsml: error: unknown type 0 in sml_value_to_double

and nearly the same (mind the different position) with EMH eHZ-GW8E2A500AK2

./sml_server /dev/ttyUSB0
SML file (3 SML messages, 236 bytes)
SML message 101
SML message 701
SML message 201
OBIS data
libsml: error: unknown type 0 in sml_value_to_double
libsml: error: unknown type 0 in sml_value_to_double
1-0:1.8.1255#14798741.6#Wh
1-0:1.8.2
255#2012.4#Wh
libsml: error: unknown type 0 in sml_value_to_double
1-0:1.7.0*255#24.9#W

smartmeter-obis (nodejs lib) prints this ones, so apparently libsml is not able to decode some of the obis values:

cat /dev/ttyUSB0 |node StdInSml.js
129-129:199.130.3255: Manufacturer ID = DNT
1-0:0.0.9
255: Device ID = 0901444e540100002030
1-0:2.8.0255: Zählerstand 1 Summe Wirkarbeit Abgabe - (Total) = 4.373 kWh
1-0:2.8.1
255: Zählerstand 1 Summe Wirkarbeit Abgabe - (T1) = 4.373 kWh
1-0:2.8.2255: Zählerstand 1 Summe Wirkarbeit Abgabe - (T2) = 0 kWh
1-0:15.7.0
255: Momentanwert (Total) = 26 W
129-129:199.130.5*255: Forename/Public Key = fea5d6bc658d734673f5790051d61c2ebd55344a6285686de3b645ee0104d65f5abba6cb68f1bfcb7fcf94f99cd4d845

cat /dev/ttyUSB0 |node StdInSml.js
129-129:199.130.3255: Manufacturer ID = EMH
1-0:0.0.0
255: Meter owner number = 02280816
1-0:1.8.1255: Zählerstand 1 Summe Wirkarbeit Bezug + (T1) = 14798.7427 kWh
1-0:1.8.2
255: Zählerstand 1 Summe Wirkarbeit Bezug + (T2) = 2.0124 kWh
0-0:96.1.255255: Factory number = 0002280816
1-0:1.7.0
255: Momentanwert Summe Wirkarbeit Bezug + (Total) = 23.9 W

feature request: please add stdin and output formatting options

i would find

cat /dev/ttyUSB0 >/tmp/binary-sml.dump

cat /tmp/binary-sml.dump | ./sml_server -i stdin

very useful

this way we would not even need to modify sml_server for proper serial initialization, we could do that outside of sml_server and then use

cat /dev/ttyUSB0 | ./sml_server -i stdin

What i would also find usefule besides vzlogger would be a simple and universal binary which gets sml binary stream as input and does decoded, machine-parseable sml/obis as output.

format1:
json
see smartmeter-obis

format2:
parseable envvars (can be read via pipe, so you can use the power of unix...)

example:
cat /dev/ttyUSB0 | ./sml_server -i stdin -o envvars
ENVOBISCODE1="1-0:2.8.0*255" ENVOBSINAME1="Zählerstand 1 Summe Wirkarbeit Abgabe - (Total)" ENVOBISVAL="4.373" ENVOBISUNIT="kWh" ENVOBISCODE2="....." ENVOBISNAME2="..."

This way we could simply do:
cat /dev/ttyUSB0 | ./sml_server -o stdin -o envvars | while read line;do eval $line; echo $ENVOBISVAL1;rrdtool $ENVOBISVAL1 ; curl http://server/path?var=$ENVOBISVAL1 ; your_favourite_tool_here $ENVOBISVAL1;... ;done

format3:
maybe csv or something like that?

OSX build warning

cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c unity/unity.c -o unity/unity.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c unity/unity_fixture.c -o unity/unity_fixture.o
cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c src/test_helper.c -o src/test_helper.o
src/test_helper.c:38:23: warning: unused function 'test_helper_c2toi' [-Wunused-function]
static inline uint8_t test_helper_c2toi(uint8_t c1, uint8_t c2){
                      ^

with current master

Process hangs once a week

I wrote a small program that uses libsml to read meter values and publish them via MQTT. Once a week this process hangs with 100% cpu utilization. I've attached GDB to the process and run a backtrace. Here's the output:

root@heizung:/usr/local/bin# gdb sml2mqtt 2190
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-linux-gnueabihf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
"/usr/local/bin/sml2mqtt": not in executable format: File format not recognized
Attaching to process 2190
[New LWP 2191]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
0xb6f57460 in read () from /lib/arm-linux-gnueabihf/libpthread.so.0
(gdb) info proc all
process 2190
warning: target file /proc/2190/cmdline contained unexpected null characters
cmdline = '/usr/sbin/sml2mqtt'
cwd = '/'
exe = '/usr/sbin/sml2mqtt'
Mapped address spaces:

        Start Addr   End Addr       Size     Offset objfile
        0xb6100000 0xb6121000    0x21000        0x0 
        0xb6121000 0xb6200000    0xdf000        0x0 
        0xb6233000 0xb6234000     0x1000        0x0 
        0xb6234000 0xb6a33000   0x7ff000        0x0 [stack:2191]
        0xb6a33000 0xb6a39000     0x6000        0x0 /lib/arm-linux-gnueabihf/libnss_files-2.24.so
        0xb6a39000 0xb6a49000    0x10000     0x6000 /lib/arm-linux-gnueabihf/libnss_files-2.24.so
        0xb6a49000 0xb6a4a000     0x1000     0x6000 /lib/arm-linux-gnueabihf/libnss_files-2.24.so
        0xb6a4a000 0xb6a4b000     0x1000     0x7000 /lib/arm-linux-gnueabihf/libnss_files-2.24.so
        0xb6a4b000 0xb6a51000     0x6000        0x0 
        0xb6a51000 0xb6a53000     0x2000        0x0 /lib/arm-linux-gnueabihf/libdl-2.24.so
        0xb6a53000 0xb6a62000     0xf000     0x2000 /lib/arm-linux-gnueabihf/libdl-2.24.so
        0xb6a62000 0xb6a63000     0x1000     0x1000 /lib/arm-linux-gnueabihf/libdl-2.24.so
        0xb6a63000 0xb6a64000     0x1000     0x2000 /lib/arm-linux-gnueabihf/libdl-2.24.so
        0xb6a64000 0xb6a6e000     0xa000        0x0 /usr/lib/arm-linux-gnueabihf/libcares.so.2.2.0
        0xb6a6e000 0xb6a7e000    0x10000     0xa000 /usr/lib/arm-linux-gnueabihf/libcares.so.2.2.0
        0xb6a7e000 0xb6a7f000     0x1000     0xa000 /usr/lib/arm-linux-gnueabihf/libcares.so.2.2.0
        0xb6a7f000 0xb6a80000     0x1000     0xb000 /usr/lib/arm-linux-gnueabihf/libcares.so.2.2.0
        0xb6a80000 0xb6bdb000   0x15b000        0x0 /usr/lib/arm-linux-gnueabihf/libcrypto.so.1.1
        0xb6bdb000 0xb6bea000     0xf000   0x15b000 /usr/lib/arm-linux-gnueabihf/libcrypto.so.1.1
        0xb6bea000 0xb6bf9000     0xf000   0x15a000 /usr/lib/arm-linux-gnueabihf/libcrypto.so.1.1
        0xb6bf9000 0xb6c00000     0x7000   0x169000 /usr/lib/arm-linux-gnueabihf/libcrypto.so.1.1
        0xb6c00000 0xb6c04000     0x4000        0x0 
        0xb6c04000 0xb6c3c000    0x38000        0x0 /usr/lib/arm-linux-gnueabihf/libssl.so.1.1
        0xb6c3c000 0xb6c4b000     0xf000    0x38000 /usr/lib/arm-linux-gnueabihf/libssl.so.1.1
        0xb6c4b000 0xb6c4e000     0x3000    0x37000 /usr/lib/arm-linux-gnueabihf/libssl.so.1.1
        0xb6c4e000 0xb6c52000     0x4000    0x3a000 /usr/lib/arm-linux-gnueabihf/libssl.so.1.1
        0xb6c52000 0xb6c57000     0x5000        0x0 /lib/arm-linux-gnueabihf/librt-2.24.so
        0xb6c57000 0xb6c66000     0xf000     0x5000 /lib/arm-linux-gnueabihf/librt-2.24.so
        0xb6c66000 0xb6c67000     0x1000     0x4000 /lib/arm-linux-gnueabihf/librt-2.24.so
        0xb6c67000 0xb6c68000     0x1000     0x5000 /lib/arm-linux-gnueabihf/librt-2.24.so
        0xb6c68000 0xb6c6b000     0x3000        0x0 /lib/arm-linux-gnueabihf/libuuid.so.1.3.0
        0xb6c6b000 0xb6c7a000     0xf000     0x3000 /lib/arm-linux-gnueabihf/libuuid.so.1.3.0
        0xb6c7a000 0xb6c7b000     0x1000     0x2000 /lib/arm-linux-gnueabihf/libuuid.so.1.3.0
        0xb6c7b000 0xb6c7c000     0x1000     0x3000 /lib/arm-linux-gnueabihf/libuuid.so.1.3.0
---Type <return> to continue, or q <return> to quit--- 
        0xb6c7c000 0xb6c85000     0x9000        0x0 /usr/lib/arm-linux-gnueabihf/libmosquitto.so.1
        0xb6c85000 0xb6c94000     0xf000     0x9000 /usr/lib/arm-linux-gnueabihf/libmosquitto.so.1
        0xb6c94000 0xb6c95000     0x1000     0x8000 /usr/lib/arm-linux-gnueabihf/libmosquitto.so.1
        0xb6c95000 0xb6c96000     0x1000     0x9000 /usr/lib/arm-linux-gnueabihf/libmosquitto.so.1
        0xb6c96000 0xb6d6f000    0xd9000        0x0 /lib/arm-linux-gnueabihf/libc-2.24.so
        0xb6d6f000 0xb6d7e000     0xf000    0xd9000 /lib/arm-linux-gnueabihf/libc-2.24.so
        0xb6d7e000 0xb6d80000     0x2000    0xd8000 /lib/arm-linux-gnueabihf/libc-2.24.so
        0xb6d80000 0xb6d81000     0x1000    0xda000 /lib/arm-linux-gnueabihf/libc-2.24.so
        0xb6d81000 0xb6d84000     0x3000        0x0 
        0xb6d84000 0xb6d9c000    0x18000        0x0 /lib/arm-linux-gnueabihf/libgcc_s.so.1
        0xb6d9c000 0xb6dab000     0xf000    0x18000 /lib/arm-linux-gnueabihf/libgcc_s.so.1
        0xb6dab000 0xb6dac000     0x1000    0x17000 /lib/arm-linux-gnueabihf/libgcc_s.so.1
        0xb6dac000 0xb6dad000     0x1000    0x18000 /lib/arm-linux-gnueabihf/libgcc_s.so.1
        0xb6dad000 0xb6e14000    0x67000        0x0 /lib/arm-linux-gnueabihf/libm-2.24.so
        0xb6e14000 0xb6e23000     0xf000    0x67000 /lib/arm-linux-gnueabihf/libm-2.24.so
        0xb6e23000 0xb6e24000     0x1000    0x66000 /lib/arm-linux-gnueabihf/libm-2.24.so
        0xb6e24000 0xb6e25000     0x1000    0x67000 /lib/arm-linux-gnueabihf/libm-2.24.so
        0xb6e25000 0xb6f18000    0xf3000        0x0 /usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.22
        0xb6f18000 0xb6f28000    0x10000    0xf3000 /usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.22
        0xb6f28000 0xb6f2d000     0x5000    0xf3000 /usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.22
        0xb6f2d000 0xb6f2f000     0x2000    0xf8000 /usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.22
        0xb6f2f000 0xb6f31000     0x2000        0x0 
        0xb6f31000 0xb6f3a000     0x9000        0x0 /usr/local/lib/libsml.so.1
        0xb6f3a000 0xb6f49000     0xf000     0x9000 /usr/local/lib/libsml.so.1
        0xb6f49000 0xb6f4a000     0x1000     0x8000 /usr/local/lib/libsml.so.1
        0xb6f4a000 0xb6f4b000     0x1000     0x9000 /usr/local/lib/libsml.so.1
        0xb6f4b000 0xb6f5c000    0x11000        0x0 /lib/arm-linux-gnueabihf/libpthread-2.24.so
        0xb6f5c000 0xb6f6b000     0xf000    0x11000 /lib/arm-linux-gnueabihf/libpthread-2.24.so
        0xb6f6b000 0xb6f6c000     0x1000    0x10000 /lib/arm-linux-gnueabihf/libpthread-2.24.so
        0xb6f6c000 0xb6f6d000     0x1000    0x11000 /lib/arm-linux-gnueabihf/libpthread-2.24.so
        0xb6f6d000 0xb6f6f000     0x2000        0x0 
        0xb6f6f000 0xb6f72000     0x3000        0x0 /usr/lib/arm-linux-gnueabihf/libmosquittopp.so.1
        0xb6f72000 0xb6f81000     0xf000     0x3000 /usr/lib/arm-linux-gnueabihf/libmosquittopp.so.1
        0xb6f81000 0xb6f82000     0x1000     0x2000 /usr/lib/arm-linux-gnueabihf/libmosquittopp.so.1
        0xb6f82000 0xb6f83000     0x1000     0x3000 /usr/lib/arm-linux-gnueabihf/libmosquittopp.so.1
        0xb6f91000 0xb6fa9000    0x18000        0x0 /lib/arm-linux-gnueabihf/ld-2.24.so
        0xb6faf000 0xb6fb8000     0x9000        0x0 
        0xb6fb8000 0xb6fb9000     0x1000    0x17000 /lib/arm-linux-gnueabihf/ld-2.24.so
        0xb6fb9000 0xb6fba000     0x1000    0x18000 /lib/arm-linux-gnueabihf/ld-2.24.so
        0xb6fba000 0xb6fc2000     0x8000        0x0 /usr/sbin/sml2mqtt
        0xb6fd1000 0xb6fd2000     0x1000     0x7000 /usr/sbin/sml2mqtt
---Type <return> to continue, or q <return> to quit---
        0xb6fd2000 0xb6fd3000     0x1000     0x8000 /usr/sbin/sml2mqtt
        0xb7d17000 0xb7d3c000    0x25000        0x0 [heap]
        0xbe8eb000 0xbe90c000    0x21000        0x0 [stack]
        0xffff0000 0xffff1000     0x1000        0x0 [vectors]
Name:   sml2mqtt
State:  t (tracing stop)
Tgid:   2190
Pid:    2190
PPid:   1
TracerPid:      19395
Uid:    0       0       0       0
Gid:    0       0       0       0
FDSize: 256
Groups:
VmPeak:    16144 kB
VmSize:    15120 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:      2416 kB
VmRSS:      2416 kB
VmData:     9468 kB
VmStk:       136 kB
VmExe:        32 kB
VmLib:      4312 kB
VmPTE:        12 kB
VmSwap:        0 kB
Threads:        2
SigQ:   0/7006
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000001000
SigCgt: 0000000180004000
CapInh: 0000000000000000
CapPrm: ffffffffffffffff
CapEff: ffffffffffffffff
CapBnd: ffffffffffffffff
Cpus_allowed:   3
Cpus_allowed_list:      0-1
Mems_allowed:   1
Mems_allowed_list:      0
---Type <return> to continue, or q <return> to quit---
voluntary_ctxt_switches:        20759011
nonvoluntary_ctxt_switches:     2448937
Process: 2190
Exec file: sml2mqtt
State: t
Parent process: 1
Process group: 2190
Session id: 2190
TTY: 0
TTY owner process group: 18446744073709551615
Flags: 0x400100
Minor faults (no memory page): 859
Minor faults, children: 0
Major faults (memory page faults): 0
Major faults, children: 0
utime: 2018022
stime: 6808969
utime, children: 0
stime, children: 0
jiffies remaining in current time slice: 20
'nice' value: 0
jiffies until next timeout: 2
jiffies until next SIGALRM: 0
start time (jiffies since system boot): 901087
Virtual memory size: 15482880
Resident set size: 604
rlim: 4294967295
Start of text: 0xb6fba000
End of text: 0xb6fc1048
Start of stack: 0xbe90bdf0
(gdb) info threads
  Id   Target Id         Frame 
* 1    Thread 0xb6fb1800 (LWP 2190) "sml2mqtt" 0xb6f57460 in read () from /lib/arm-linux-gnueabihf/libpthread.so.0
  2    Thread 0xb6a32420 (LWP 2191) "sml2mqtt" 0xb6cac6f4 in ?? () from /lib/arm-linux-gnueabihf/libc.so.6
(gdb) bt
#0  0xb6f57460 in read () from /lib/arm-linux-gnueabihf/libpthread.so.0
#1  0xb6f3451e in sml_read (fd=6, set=0xbe909ad4, buffer=0xbe907c28 "-", len=4) at src/sml_transport.c:45
#2  0xb6f34698 in sml_transport_read (fd=6, buffer=0xbe909b94 "\033\033\033\033\001\001\001\001v\005\n\035\317\242b", max_len=8096) at src/sml_transport.c:79
#3  0xb6f34784 in sml_transport_listen (fd=6, 
    sml_transport_receiver=0xb6fbe5d1 <SML::transport_listen()::{lambda(unsigned char*, unsigned int)#1}::_FUN(unsigned char*, unsigned int)>) at src/sml_transport.c:112
#4  0xb6fbc5ea in main ()

It seems to hang in sml_transport_listen. Any ideas on how to solve this?

implement DZG meter workaround?

I found that my DZG DVS74 meter has a bug in the encoding of positive values in the range of 327.68..655.36W, it tags them as SIGNED but outputs them as 2 bytes in UNSIGNED format.

I don't know if the library or something else should have a workaround, but I've implemented one in the example server:
jmberg@456d7e3 ("sml_server: implement DZG encoding bug workaround")

no case 0x55 in sml_value_to_double() ?

thread: http://volkszaehler.org/pipermail/volkszaehler-dev/2015-January/004049.html

is this possibly a bug , that libsml does not seem to handle value->type 0x55 ?

from the mail conversation:

according to
https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR03109/TR-03109-1_Anlage_Feinspezifikation_Drahtgebundene_LMN-Schnittstelle_Teilb.pdf
and
http://wiki.volkszaehler.org/hardware/channels/meters/power/edl-ehz/emh-ehz-h1

the value to interpret after "0x55" is "Integer32"

77070100100700FF 01 01 621B 52FF 55 FFFFFF47 0177078181C78

let`s convert that to int32 :

http://www.binaryconvert.com/result_signed_int.html?hexadecimal=FFFFFF47 (netter converter, btw)

result:
-185 !

Apparently, your parser does not work correctly (note: the reporter does not use libslm)

the following makes me curious, as there is no "case" 0x55 return ...int32 ?
Shouldn`t it return int32 for 0x55, too?

https://github.com/dailab/libsml/blob/master/sml/src/sml_value.c

double sml_value_to_double(sml_value *value) {
switch (value->type) {
case 0x51: return *value->data.int8; break;
case 0x52: return *value->data.int16; break;
case 0x54: return *value->data.int32; break;
case 0x58: return *value->data.int64; break;
case 0x61: return *value->data.uint8; break;
case 0x62: return *value->data.uint16; break;
case 0x64: return *value->data.uint32; break;
case 0x68: return *value->data.uint64; break;

Compile warnings after #5

Compile 2 Warnings after applying #5:

cc -I./include/ -fPIC -fno-stack-protector -g -std=c99 -Wall -Wextra -pedantic -c -o src/sml_number.o src/sml_number.c

src/sml_number.c: In function ‘sml_number_init’:
src/sml_number.c:30:49: warning: unused parameter ‘type’ [-Wunused-parameter]

cc -I../sml/include/ -g -std=c99 -Wall -Wextra -pedantic -c sml_server.c -o sml_server.o

sml_server.c: In function ‘main’:
sml_server.c:79:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
sml_server.c:79:27: warning: unused parameter ‘argv’ [-Wunused-parameter]

Calling this library from python?

Hi, did anyone call this library from python? I am stuck with transferring data from python to c - it's just something I never did before.

My code looks like this so far:

import ctypes
import numpy as np
import bitstring
so_file = "/home/pi/libsml/sml/lib/libsml.so.1"
my_functions = ctypes.CDLL(so_file)
my_functions.sml_file_parse.argtypes = (ctypes.POINTER(ctypes.c_char_p), ctypes.c_size_t) # i have no idea if this is correct


print(type(my_functions))
sml = "1b1b1b1b01010101760700110bf402df620062007263010176010107001103c500f50b0901454d4800007514c401016375f300760700110bf402e0620062007263070177010b0901454d4800007514c4070100620affff7262016503c5853c7a77078181c78203ff0101010104454d480177070100000009ff010101010b0901454d4800007514c40177070100010800ff6401018201621e52ff5600051bdfde0177070100020800ff6401018201621e52ff5600000006070177070100010801ff0101621e52ff5600051bdfde0177070100020801ff0101621e52ff5600000006070177070100010802ff0101621e52ff5600000000000177070100020802ff0101621e52ff5600000000000177070100100700ff0101621b52ff55000014f40177078181c78205ff010101018302957c486aaf8c92a257ec681e215fddeff32a2dbf2c8a88721777f5f01e5ed5ccaa694dd48c14dc5589d28e0c5b9ce88e01010163b4c800760700110bf402e362006200726302017101634e85001b1b1b1b1a000337" # from my edl eHZ Generation K

bit_array = bitstring.BitArray(hex=sml)


test = ctypes.create_string_buffer(bit_array.bytes)
test2=ctypes.cast(test,ctypes.c_char_p)


sml_file = my_functions.sml_file_parse(test2, len(test)) 
my_functions.sml_file_print(sml_file)
print(test)

But the output is always
libsml: warning: could not read the whole file
SML file (0 SML messages, 0 bytes)

sml_server or libsml crashing in "faulty" binary sml dump

for a while now there is a "faulty" sml binary dump in https://github.com/devZer0/libsml-testing ( EMH_eHZ-IW8E2A5L0EK2P_crash.bin )

i changed sml_server.c to open fd=0 (which is stdin) and feeding sml_server with that, it's crashing. even with the most recent version from holger's repo.

from what i found so far is that entry->value->type seems to be an invalid pointer/reference, as the crash happens when accessing that.

cat /tmp/EMH_eHZ-IW8E2A5L0EK2P_crash.bin |./sml_server /dev/ttyUSB0
SML file (3 SML messages, 344 bytes)
SML message 101
SML message 701
SML message 201
OBIS data
129-129:199.130.3255#EMH#
1-0:0.0.9
255#06 45 4d 48 01 07 19 7c 24 56 #
1-0:1.8.0255#2795692.7#Wh
1-0:1.8.1
255#2795692.7#Wh
1-0:1.8.2255#0.0#Wh
1-0:16.7.0
255#136.7#W
129-129:199.130.5*255#8b 6a 0e 6e 12 f5 d9 80 f7 30 b6 bd 5e 19 41 83 4e b0 e4 3e 4a 63 23 d9 99 25 95 56 f5 e5 6e 04 04 98 c8 97 38 f0 f6 df f8 78 5b 04 5d 84 e0 d6 #
Speicherzugriffsfehler

i think, whatever data enters libsml and being parsed there - it should not lead to any crash.

sml_server: add a switch to exit after one packet

Off topic I discussed in #29 with @msebald that sml_server is used by the @openhab project rule sml. At the moment sml_server.c is copied there and modified slightly. The main reason for the change is, that the program needs to stop after processing one packet. My idea is to add a switch to do that. Do I get support for this and how should the switch be called? E.g. "-s" for single?

DZG workaround not necessary anymore

It seems there was a generation of DZG meters with a problem with the encoding of the power measurements.
That was fixed by @jmberg using the following pull request:
#66

However, newer versions of the DZG meters do not have that problem anymore.
Furthermore, the assumption described in the comment

* Luckily, it doesn't attempt to do any compression on

does not hold anymore.
The DZG meters do use two-byte long encodings of negative values.

Therefore, libsml, and thus, also vzlogger, currently produce (for more recent DZG meters) wrong measurement values
for small negative values (since the workaround interprets the small negative numbers as positive numbers).

If I remove the workaround, the measurement values are shown correctly.

I propose to introduce a flag for the workaround, such that the default version of the library works with current versions of the DZG meters.

wrong results with EMH_eHZ-HW8E2A5L0EK2P_2.bin from testing repo

Hi,

I added 3 files from two smart meters. One smart meter type is even new in your list.

The new one is parsed by libsml quite well, but the model you have already two other files makes problems:

cat ../../../Desktop/EMH_eHZ-HW8E2A5L0EK2P_2.bin | ./sml_server -
129-129:199.130.3255#EMH#
1-0:0.0.9255#06 45 4d 48 01 02 71 58 20 51 #
1-0:1.8.0255#13312484.9#Wh
1-0:1.8.1255#13312484.9#Wh
1-0:1.8.2255#0.0#Wh
1-0:15.7.0255#139.4#W
129-129:199.130.5*255#19 92 1a 52 65 64 ac ba e3 02 6e 61 35 26 75 ec 28 27 66 83 f0 2d bb 32 fa 70 1e 3a 75 3b 34 21 8b 64 66 b1 50 64 df 59 19 f9 f1 3f 84 b5 b2 c9 #

I do not know about the last output 129-129:199.130.5*255
Is this output correct? is the parser working well here? Maybe not.....

Hope my contribution helps a bit to make your great work even better!

Best regards

Wolfgang

example server should not use %.1f

The example server is printing all values with %.1f which loses precision if the scaler is less than -1, it should use %.*f instead. I've implemented that here:

jmberg@31efb5f ("sml_server: print values with the correct precision")

SML-Errors with Holley DTZ541

Hi everybody,
I have a Holley DTZ541 which is connected to my RaspberryPi using a rs485 to serial converter from weidmann elektronik.
In the vzlogger I can see the following log entries. They occour multiple times per hour.

[Nov 23 01:05:52][sml] reopen called. current fd=4

In stdout i can also see these entries multiple times per hour:

libsml: error: unrecognized sequence

A few weeks ago I was using an infrared head which was connected to my meter. I saw also the log entries from above. I thaught this is related to the weak shining ir led built into the meter.
But after changing to a wired connection, I think the problem must be elsewhere. I do not think the meter is sending fragmentated messages periodically over a half duplex wired connection.

Maybe it is related to the libsml?

Thank you for your help!

do not printf errors on stdout and add "libsml - " to error message

please consider using fprintf(stderr,"libsml - error:.....\n",value); or similar instead

3 reasons for that:

1st:
root@wheezy:~/libsml# while true;do cat /dev/ttyUSB0 |./sml_server_stdio ;done
error: unknown type in sml_value_to_double
error: unknown type in sml_value_to_double
14797050.70 Wh
2012.40 Wh
error: unknown type in sml_value_to_double
20.70 W
^C

where is this error coming from?
how do i get rid of those messages when i want to parse the data ?

if being printed to stderr, you can simple redirect the error messages to /dev/null or to an error-logfile:

root@wheezy:~/libsml# while true;do cat /dev/ttyUSB0 |./sml_server_stdio ;done 2>/dev/null
14797050.80 Wh
2012.40 Wh
21.10 W
^C

2nd:
Because of this behaviour, eople already re-implement sml_value_to_double() within their code - see: http://knx-user-forum.de/201949-post60.html

3rd:
it`s more clear then, that the error message are from libsml and not from the program implementing the library if you add libsml to the message

Note from r00t-:
more correctly, a library should ideally not print errors itself at all,
but report them to the caller.
(for example through a configurable error logging callback.)

yes, i second that - but that`s a little bit more work

regards
roland

root@wheezy:~/libsml/libsml/sml/src# grep print * |egrep "warning|error"
sml_file.c: printf("warning: could not read the whole file\n");
sml_message.c: printf("error: message type %04X not yet implemented\n", *(msg_body->tag));
sml_message.c: printf("error: message type %04X not yet implemented\n", *(message_body->tag));
sml_transport.c: printf("error: unrecognized sequence\n");
sml_tree.c: printf("error: unknown tag in %s\n", FUNCTION);
sml_value.c: printf("error: unknown type in %s\n", FUNCTION);

Compile Error on Alpine: no member named '__jmpbuf'

Hi,
thank you for maintaining this project! I am getting a compile error on Alpine:

cc -I../sml/include/ -std=c99 -Wall -Wextra -pedantic -c unity/unity.c -o unity/unity.o
unity/unity.c:23:21: error: 'struct __jmp_buf_tag' has no member named '__jmpbuf'
   23 |   .AbortFrame = { {.__jmpbuf = {0}, .__mask_was_saved = 0, .__saved_mask = {{0}} } }
      |                     ^~~~~~~~
unity/unity.c:23:38: error: 'struct __jmp_buf_tag' has no member named '__mask_was_saved'
   23 |   .AbortFrame = { {.__jmpbuf = {0}, .__mask_was_saved = 0, .__saved_mask = {{0}} } }
      |                                      ^~~~~~~~~~~~~~~~
unity/unity.c:23:61: error: 'struct __jmp_buf_tag' has no member named '__saved_mask'
   23 |   .AbortFrame = { {.__jmpbuf = {0}, .__mask_was_saved = 0, .__saved_mask = {{0}} } }
      |                                                             ^~~~~~~~~~~~
unity/unity.c:23:3: warning: braces around scalar initializer
   23 |   .AbortFrame = { {.__jmpbuf = {0}, .__mask_was_saved = 0, .__saved_mask = {{0}} } }
      |   ^
unity/unity.c:23:3: note: (near initialization for 'Unity.AbortFrame[0].__ss[0]')
make[1]: *** [Makefile:40: unity/unity.o] Error 1
make[1]: Leaving directory '/tmp/libsml/test'
make: *** [Makefile:5: all] Error 2

Replicate:

docker run -it --rm alpine /bin/ash
apk add --no-cache  build-base git util-linux-dev
git clone https://github.com/volkszaehler/libsml.git
cd libsml
make

Thanks for any pointers...

let's build "parsesml" - rename sml_server

i never understood why the example prog being called "sml_server". it's not a "server" prog, imho. you cannot connect to that and there is no client.

can't/shouldn't we turn that into a flexible and minimalistic commandline parser utility and call that "parsesml" instead?

contributor agreement?

Since you're a fork from dailab, do you really want the contributor agreement still? Just curious.

Checksum issue on Itron OpenWay 3Hz

Hello and first of all thanks for your work!

We have Itron OpenWay 3.HZ in our house. I needed some hours to figure out why I can't get it working. It seems as this manufacturer is using a different CRC. After inspecting the code and disabling CRC checking, I see normal SML messages parsed. There are already to different checksum algorithms in sml_crc16.c.
Does anybody know which other CRC Itron is using? Or can somebody give me a hint, how to find out the CRC algorithm needed?
If I'm able to find the correct algorithm I will make a pull request.

warning: type of bit-field 'dzg_meter' is a GCC extension

src/sml_list.c:124:2: Warnung: Typ des Bitfeldes »dzg_meter« ist eine Erweiterung des GCC [-Wpedantic]
u8 dzg_meter:1;
^
src/sml_list.c:124:2: warning: type of bit-field 'dzg_meter' is a GCC extension [-Wpedantic]
u8 dzg_meter:1;
^

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.