# SmlLib
[![Tests Status](https://github.com/spacemanspiff2007/SmlLib/workflows/Tests/badge.svg)](https://github.com/spacemanspiff2007/SmlLib/actions?query=workflow%3ATests)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/SmlLib)](https://pypi.org/project/smllib/)
[![PyPI](https://img.shields.io/pypi/v/SmlLib)](https://pypi.org/project/smllib/)
[![Downloads](https://static.pepy.tech/badge/SmlLib/month)](https://pepy.tech/project/SmlLib)
_A SML (Smart Message Language) library_
## About
This library can be used to parse SML byte streams.
It does not read from external devices.
## Usage
The [sml2mqtt](https://pypi.org/project/sml2mqtt/) program makes use of this library.
Example:
```python
from smllib import SmlStreamReader
stream = SmlStreamReader()
stream.add(b'BytesFromSerialPort')
sml_frame = stream.get_frame()
if sml_frame is None:
print('Bytes missing')
# Add more bytes, once it's a complete frame the SmlStreamReader will
# return the frame instead of None
stream.add(b'BytesFromSerialPort')
sml_frame = stream.get_frame()
# A quick Shortcut to extract all values without parsing the whole frame
# In rare cases this might raise an InvalidBufferPos exception, then you have to use sml_frame.parse_frame()
obis_values = sml_frame.get_obis()
# return all values but slower
parsed_msgs = sml_frame.parse_frame()
for msg in parsed_msgs:
# prints a nice overview over the received values
print(msg.format_msg())
# In the parsed message the obis values are typically found like this
obis_values = parsed_msgs[1].message_body.val_list
# The obis attribute of the SmlListEntry carries different obis representations as attributes
list_entry = obis_values[0]
print(list_entry.obis) # 0100010800ff
print(list_entry.obis.obis_code) # 1-0:1.8.0*255
print(list_entry.obis.obis_short) # 1.8.0
```
```text
SmlMessage
transaction_id: 17c77d6b
group_no : 0
abort_on_error: 0
message_body <SmlOpenResponse>
codepage : None
client_id : None
req_file_id: 07ed29cd
server_id : 11111111111111111111
ref_time : None
sml_version: None
crc16 : 25375
SmlMessage
transaction_id: 17c77d6c
group_no : 0
abort_on_error: 0
message_body <SmlGetListResponse>
client_id : None
sever_id : 11111111111111111111
list_name : 0100620affff
act_sensor_time : 226361515
val_list: list
<SmlListEntry>
obis : 8181c78203ff (129-129:199.130.3*255)
status : None
val_time : None
unit : None
scaler : None
value : ISK
value_signature: None
-> (Hersteller-Identifikation)
<SmlListEntry>
obis : 0100000009ff (1-0:0.0.9*255)
status : None
val_time : None
unit : None
scaler : None
value : 11111111111111111111
value_signature: None
-> (Geräteeinzelidentifikation)
<SmlListEntry>
obis : 0100010800ff (1-0:1.8.0*255)
status : 386
val_time : None
unit : 30
scaler : -1
value : 123456789
value_signature: None
-> 12345678.9Wh (Zählerstand Total)
<SmlListEntry>
obis : 0100010801ff (1-0:1.8.1*255)
status : None
val_time : None
unit : 30
scaler : -1
value : 123456789
value_signature: None
-> 12345678.9Wh (Zählerstand Tarif 1)
<SmlListEntry>
obis : 0100010802ff (1-0:1.8.2*255)
status : None
val_time : None
unit : 30
scaler : -1
value : 0
value_signature: None
-> 0.0Wh (Zählerstand Tarif 2)
<SmlListEntry>
obis : 0100100700ff (1-0:16.7.0*255)
status : None
val_time : None
unit : 27
scaler : 0
value : 555
value_signature: None
-> 555W (aktuelle Wirkleistung)
<SmlListEntry>
obis : 8181c78205ff (129-129:199.130.5*255)
status : None
val_time : None
unit : None
scaler : None
value : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
value_signature: None
-> (Öffentlicher Schlüssel)
list_signature : None
act_gateway_time: None
crc16 : 22117
SmlMessage
transaction_id: 17c77d6d
group_no : 0
abort_on_error: 0
message_body <SmlCloseResponse>
global_signature: None
crc16 : 56696
```
## Different CRC functions
Some meters e.g. the Holley DTZ541 via RS485 require a different crc function.
You can set the crc function when creating the StreamReader.
Example:
```python
from smllib import SmlStreamReader
stream = SmlStreamReader(crc='kermit') # <-- use kermit for Holley DTZ541
stream.add(b'BytesFromSerialPort')
sml_frame = stream.get_frame()
```
Raw data
{
"_id": null,
"home_page": "https://github.com/spacemanspiff2007/SmlLib",
"name": "smllib",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "sml, obis, smart message language, energy meter",
"author": "spaceman_spiff",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/ad/98/9897af937c3361cf612166da9012ddc5e9c787deee8e16412acc185a6913/smllib-1.5.tar.gz",
"platform": null,
"description": "# SmlLib\n[![Tests Status](https://github.com/spacemanspiff2007/SmlLib/workflows/Tests/badge.svg)](https://github.com/spacemanspiff2007/SmlLib/actions?query=workflow%3ATests)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/SmlLib)](https://pypi.org/project/smllib/)\n[![PyPI](https://img.shields.io/pypi/v/SmlLib)](https://pypi.org/project/smllib/)\n[![Downloads](https://static.pepy.tech/badge/SmlLib/month)](https://pepy.tech/project/SmlLib)\n\n\n_A SML (Smart Message Language) library_\n\n## About\nThis library can be used to parse SML byte streams.\nIt does not read from external devices.\n\n## Usage\nThe [sml2mqtt](https://pypi.org/project/sml2mqtt/) program makes use of this library.\n\n\nExample:\n```python\nfrom smllib import SmlStreamReader\n\nstream = SmlStreamReader()\nstream.add(b'BytesFromSerialPort')\nsml_frame = stream.get_frame()\nif sml_frame is None:\n print('Bytes missing')\n\n# Add more bytes, once it's a complete frame the SmlStreamReader will\n# return the frame instead of None\nstream.add(b'BytesFromSerialPort')\nsml_frame = stream.get_frame()\n\n# A quick Shortcut to extract all values without parsing the whole frame\n# In rare cases this might raise an InvalidBufferPos exception, then you have to use sml_frame.parse_frame()\nobis_values = sml_frame.get_obis()\n\n# return all values but slower\nparsed_msgs = sml_frame.parse_frame()\nfor msg in parsed_msgs:\n # prints a nice overview over the received values\n print(msg.format_msg())\n\n# In the parsed message the obis values are typically found like this\nobis_values = parsed_msgs[1].message_body.val_list\n\n# The obis attribute of the SmlListEntry carries different obis representations as attributes\nlist_entry = obis_values[0]\nprint(list_entry.obis) # 0100010800ff\nprint(list_entry.obis.obis_code) # 1-0:1.8.0*255\nprint(list_entry.obis.obis_short) # 1.8.0\n```\n\n```text\nSmlMessage\n transaction_id: 17c77d6b\n group_no : 0\n abort_on_error: 0\n message_body <SmlOpenResponse>\n codepage : None\n client_id : None\n req_file_id: 07ed29cd\n server_id : 11111111111111111111\n ref_time : None\n sml_version: None\n crc16 : 25375\nSmlMessage\n transaction_id: 17c77d6c\n group_no : 0\n abort_on_error: 0\n message_body <SmlGetListResponse>\n client_id : None\n sever_id : 11111111111111111111\n list_name : 0100620affff\n act_sensor_time : 226361515\n val_list: list\n <SmlListEntry>\n obis : 8181c78203ff (129-129:199.130.3*255)\n status : None\n val_time : None\n unit : None\n scaler : None\n value : ISK\n value_signature: None\n -> (Hersteller-Identifikation)\n <SmlListEntry>\n obis : 0100000009ff (1-0:0.0.9*255)\n status : None\n val_time : None\n unit : None\n scaler : None\n value : 11111111111111111111\n value_signature: None\n -> (Ger\u00e4teeinzelidentifikation)\n <SmlListEntry>\n obis : 0100010800ff (1-0:1.8.0*255)\n status : 386\n val_time : None\n unit : 30\n scaler : -1\n value : 123456789\n value_signature: None\n -> 12345678.9Wh (Z\u00e4hlerstand Total)\n <SmlListEntry>\n obis : 0100010801ff (1-0:1.8.1*255)\n status : None\n val_time : None\n unit : 30\n scaler : -1\n value : 123456789\n value_signature: None\n -> 12345678.9Wh (Z\u00e4hlerstand Tarif 1)\n <SmlListEntry>\n obis : 0100010802ff (1-0:1.8.2*255)\n status : None\n val_time : None\n unit : 30\n scaler : -1\n value : 0\n value_signature: None\n -> 0.0Wh (Z\u00e4hlerstand Tarif 2)\n <SmlListEntry>\n obis : 0100100700ff (1-0:16.7.0*255)\n status : None\n val_time : None\n unit : 27\n scaler : 0\n value : 555\n value_signature: None\n -> 555W (aktuelle Wirkleistung)\n <SmlListEntry>\n obis : 8181c78205ff (129-129:199.130.5*255)\n status : None\n val_time : None\n unit : None\n scaler : None\n value : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n value_signature: None\n -> (\u00d6ffentlicher Schl\u00fcssel)\n list_signature : None\n act_gateway_time: None\n crc16 : 22117\nSmlMessage\n transaction_id: 17c77d6d\n group_no : 0\n abort_on_error: 0\n message_body <SmlCloseResponse>\n global_signature: None\n crc16 : 56696\n```\n\n\n## Different CRC functions\n\nSome meters e.g. the Holley DTZ541 via RS485 require a different crc function.\nYou can set the crc function when creating the StreamReader.\n\n\nExample:\n```python\nfrom smllib import SmlStreamReader\n\nstream = SmlStreamReader(crc='kermit') # <-- use kermit for Holley DTZ541\nstream.add(b'BytesFromSerialPort')\nsml_frame = stream.get_frame()\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "A library for the SML (Smart Message Language) protocol",
"version": "1.5",
"project_urls": {
"GitHub": "https://github.com/spacemanspiff2007/SmlLib",
"Homepage": "https://github.com/spacemanspiff2007/SmlLib"
},
"split_keywords": [
"sml",
" obis",
" smart message language",
" energy meter"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "621b3feb551357c66e77ab66895593df068e00ec68f7be4d56d0c27102cc0959",
"md5": "18a56c2d398bdc0ce38f45b56ff42d08",
"sha256": "2c7d436d366bd7a64b4bea7a9ce42c8b2cc697f38f125b212228c2c0bdac0330"
},
"downloads": -1,
"filename": "smllib-1.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "18a56c2d398bdc0ce38f45b56ff42d08",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 32876,
"upload_time": "2024-11-04T06:18:41",
"upload_time_iso_8601": "2024-11-04T06:18:41.685077Z",
"url": "https://files.pythonhosted.org/packages/62/1b/3feb551357c66e77ab66895593df068e00ec68f7be4d56d0c27102cc0959/smllib-1.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "ad989897af937c3361cf612166da9012ddc5e9c787deee8e16412acc185a6913",
"md5": "f8835ce95403dfb8260167dda137c8a0",
"sha256": "465a16c1b4cbf524eea25735ad9d1c97aab9f98399a5a75c13ccb3e57a10cb2d"
},
"downloads": -1,
"filename": "smllib-1.5.tar.gz",
"has_sig": false,
"md5_digest": "f8835ce95403dfb8260167dda137c8a0",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 32472,
"upload_time": "2024-11-04T06:18:43",
"upload_time_iso_8601": "2024-11-04T06:18:43.412615Z",
"url": "https://files.pythonhosted.org/packages/ad/98/9897af937c3361cf612166da9012ddc5e9c787deee8e16412acc185a6913/smllib-1.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-04 06:18:43",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "spacemanspiff2007",
"github_project": "SmlLib",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"tox": true,
"lcname": "smllib"
}