-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Gas meter value always '0' #51
Comments
Ah thats too bad. I dont actively work on this project, but could you post the full telegram here? Maybe i or someone else can look at it some time. Thanks! |
Hi, thanks for your reply! This is the full telegram:
Thanks! |
I had a look, the problem seems to be the line: This also matches the signature for HOURLY_GAS_METER_READING. Like does the true entry for the gas meter: I think this is a consequence of how the specification treats connected M-Bus devices: Which uses 0-n:24.2.1.255 obis reference for any connected gas meter, water meter, temperature meter etc. Therefore from the signature alone one can not determine how to parse the value. (Currently the parser works on the assumption that the signatures are uniquely identifying certain information elements.) Apparently the parser needs to know which device is which, this could maybe be done on the basis of the preceding DEVICE_TYPE value. But I could not at first glance determine the logic used here.
The telegram you provided, shows that the DEVICE-TYPE for both connected devices is both 003.
I do not have access to the EN 13757-3 specification which apparently specifies the codes, but I found this: http://read.pudn.com/downloads677/ebook/2739011/ocr%20pdf/3.pdf. See chapter "5.8 Device type identification". Device Type 3 appears to be a gas meter. Which obviously is not correct for the entry "0-1:24.2.1(700101010000W)(00000000)". Maybe this helps in finding a solution to the problem, some possible alternatives:
Here is the raw dump of the code i used to analyse the issue: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun May 3 12:27:42 2020
@author: lowdef
"""
from dsmr_parser import telegram_specifications
from dsmr_parser.objects import Telegram
from dsmr_parser.parsers import TelegramParser
from dsmr_parser.parsers import MBusParser
from dsmr_parser.parsers import ValueParser
from dsmr_parser import obis_references
from dsmr_parser.value_types import timestamp
from decimal import Decimal
telegram_cjandrasits = r"""/ISK5\2M550T-1012
1-3:0.2.8(50)
0-0:1.0.0(200426223325S)
0-0:96.1.1(4530303434303037333832323436303139)
1-0:1.8.1(002130.115*kWh)
1-0:1.8.2(000245.467*kWh)
1-0:2.8.1(000000.000*kWh)
1-0:2.8.2(000000.000*kWh)
0-0:96.14.0(0001)
1-0:1.7.0(00.111*kW)
1-0:2.7.0(00.000*kW)
0-0:96.7.21(00005)
0-0:96.7.9(00003)
1-0:99.97.0(1)(0-0:96.7.19)(190326095015W)(0000002014*s)
1-0:32.32.0(00001)
1-0:52.32.0(00001)
1-0:72.32.0(00192)
1-0:32.36.0(00001)
1-0:52.36.0(00001)
1-0:72.36.0(00001)
0-0:96.13.0()
1-0:32.7.0(229.9*V)
1-0:52.7.0(229.2*V)
1-0:72.7.0(222.9*V)
1-0:31.7.0(000*A)
1-0:51.7.0(000*A)
1-0:71.7.0(001*A)
1-0:21.7.0(00.056*kW)
1-0:41.7.0(00.000*kW)
1-0:61.7.0(00.055*kW)
1-0:22.7.0(00.000*kW)
1-0:42.7.0(00.000*kW)
1-0:62.7.0(00.000*kW)
0-1:24.1.0(003)
0-1:96.1.0()
0-1:24.2.1(700101010000W)(00000000)
0-2:24.1.0(003)
0-2:96.1.0(4730303339303031393336393930363139)
0-2:24.2.1(200426223001S)(00246.138*m3)
!56DD
"""
sample = telegram_cjandrasits.replace('\n', '\r\n')
parser = TelegramParser(telegram_specifications.V5)
telegram = Telegram(sample, parser, telegram_specifications.V5)
print(telegram)
print(obis_references.HOURLY_GAS_METER_READING)
# \d-\d:24\.2\.1.+?\r\n
print(telegram.HOURLY_GAS_METER_READING.values)
# matching is correct, both for working version and not working version
# working 0-1:24.2.1(200501130000S)(10618.003*m3)
# https://pythex.org/?regex=%5Cd-%5Cd%3A24%5C.2%5C.1.%2B%3F&test_string=0-1%3A24.2.1(200501130000S)(10618.003*m3)&ignorecase=0&multiline=0&dotall=0&verbose=0
# not working 0-2:24.2.1(200426223001S)(00246.138*m3)
# https://pythex.org/?regex=%5Cd-%5Cd%3A24%5C.2%5C.1.%2B%3F&test_string=0-2%3A24.2.1(200426223001S)(00246.138*m3)&ignorecase=0&multiline=0&dotall=0&verbose=0
# so it must be in the parsing itself
# obis.HOURLY_GAS_METER_READING: MBusParser(
# ValueParser(timestamp),
# ValueParser(Decimal)
#The MBusParser itself works correctly:
hgm1 = MBusParser(ValueParser(timestamp), ValueParser(Decimal)).parse(r"0-1:24.2.1(200501130000S)(10618.003*m3)\r\n")
print("reference")
print(hgm1.values)
print("gas meter line")
hgm2 = MBusParser(ValueParser(timestamp), ValueParser(Decimal)).parse(r"0-2:24.2.1(200426223001S)(00246.138*m3)\r\n")
print(hgm2.values)
print("offending line")
hgm3 = MBusParser(ValueParser(timestamp), ValueParser(Decimal)).parse(r"0-1:24.2.1(700101010000W)(00000000)\r\n")
print(hgm3.values)
# if we remove the offending line from the telegram
# 0-1:24.2.1(700101010000W)(00000000)
telegram_adapted = r"""/ISK5\2M550T-1012
1-3:0.2.8(50)
0-0:1.0.0(200426223325S)
0-0:96.1.1(4530303434303037333832323436303139)
1-0:1.8.1(002130.115*kWh)
1-0:1.8.2(000245.467*kWh)
1-0:2.8.1(000000.000*kWh)
1-0:2.8.2(000000.000*kWh)
0-0:96.14.0(0001)
1-0:1.7.0(00.111*kW)
1-0:2.7.0(00.000*kW)
0-0:96.7.21(00005)
0-0:96.7.9(00003)
1-0:99.97.0(1)(0-0:96.7.19)(190326095015W)(0000002014*s)
1-0:32.32.0(00001)
1-0:52.32.0(00001)
1-0:72.32.0(00192)
1-0:32.36.0(00001)
1-0:52.36.0(00001)
1-0:72.36.0(00001)
0-0:96.13.0()
1-0:32.7.0(229.9*V)
1-0:52.7.0(229.2*V)
1-0:72.7.0(222.9*V)
1-0:31.7.0(000*A)
1-0:51.7.0(000*A)
1-0:71.7.0(001*A)
1-0:21.7.0(00.056*kW)
1-0:41.7.0(00.000*kW)
1-0:61.7.0(00.055*kW)
1-0:22.7.0(00.000*kW)
1-0:42.7.0(00.000*kW)
1-0:62.7.0(00.000*kW)
0-1:24.1.0(003)
0-1:96.1.0()
0-2:24.1.0(003)
0-2:96.1.0(4730303339303031393336393930363139)
0-2:24.2.1(200426223001S)(00246.138*m3)
!56DD
"""
sample2 = telegram_adapted.replace('\n', '\r\n')
telegram_specification = telegram_specifications.V5
telegram_specification['checksum_support']=False
telegram2 = Telegram(sample2, parser, telegram_specification)
print("remove the offending line and switch of CRC check")
print(telegram2.HOURLY_GAS_METER_READING.values) |
I have exactly the same problem; in Domoticz there was an option to set an uservariable 'P1GasMeterChannel' to, in my case, 2. That worked like a charm for 2 years now. |
Hi, thank you for taking the time to look into this in such great detail! I can not fix any Mbus-Setup, I actually bought a cable and just plugged it in the P1-Meter and this is what it is sending... That's why I really appreciate @Quarco's comment - in cases as ours we can set the channels ourselves. Also in my case the channel would be 2, I guess?
An explanation for that is also listed as a 'Known Issue' here: |
...As i don't see a solution in the very-near future i called my electicity company and explained the problem. They will now send an engineer to clear the meter/channels and install my gas meter to channel#1. (best of all: no charges. Thank you Liander!) but.... a configuration/variable would be a much better solution of course. |
hello! Any known workaround for this issue?
|
I have had the same problem. I guess the issue lies within the parser.py In the code below the parser looks for the first object (signature) hit. In the example of @gilgamezh there are two channels in use, only the first channel returns the value 0. In my case they network operator replaced the gas meter because it had some issues. And the new meter was connected to the second channel. Below my part of the telegram data with two read outs of gas meters, 0-1 is the old meter and 0-2 is the new one: As you can see in the telegram specification it is possible to have up to four gas meters connected to the energy meter. In my opinion it goes wrong in the parser code, because it doesn't read all lines in the telegram and matches those to the objects (signatures). But it does it the other-way around, try to find the first hit of an object. So when 0-1:24:2.1 is found it doesn't look further if there are more lines matching the signatures. A quick solution if you only want to read out one gas reading is to change the signature in obis_references.py So for me and for @gilgamezh this should be OURLY_GAS_METER_READING = r'\d-2:24.2.1.+?\r\n' for me this works as a charm at the moment also in combination with home assistant. |
Same problem here. Can't use the workaround like @subNiels because i use HA inside docker. |
Hi @ariekraakjr I also run HA inside a docker, I made a small script to run within docker to copy the adjusted file after an update of my container. Important are the steps to follow then:
I copied the adjusted obis_references file to the HA config folder, so after a update this files still exists. After logging in trough console I run the following command (i put this in a script as well) from the location where the adjusted obis_references.py file is located: This will copy the adjusted obis_refference file to the file location of the used file by HA. After a restart of the container everting works well for me. I hope this will help you. |
It's possible, use portainer: Ofcourse this all is just a temporary workaround, dsrm_parser needs some improvement.. |
I like the idea of a P1_METER_GAS_CHANNEL setting (that defaults to channel 1 i guess). Which in turn determines what HOURLY_GAS_METER_READING will return The main question is when and where this setting can be set |
Same issue here... |
Has there been any progress on this? |
I was thinking that maybe we can do more with the Telegram object. Like indicating what the active gas meter reading is. Either by doing it intelligently or manual passing the channel number. So to start i think i want the parser to return a Telegram object. We already had one, but it was wrapping the parser. I refactored that a bit: Then i'm thinking we can for now (optionally) pass the gas meter channel number via TelegramParser(.., gas_meter_channel=1). This thengets passed to the Telegram object which can use it to return the correct gas reading. Anyone got thoughts on this? |
Why should the Telegram object know anything about gas at all.
If we make sure that there is either a " gasmeter" object that has the
values for all channels. Then the Telegram."gasmeter" user can obtain the
correct value from that object.
Or, Telegram and the parser will become channel aware and we can ask
Telegram for specific object in a specific channel. For existing
implementations the behaviour will remain unchanged they would get objects
from the default channel.
I prefer the latter, because it is a more generic & backward compatible
approach.
Nigel Dokter ***@***.***> schrieb am Sa., 14. Jan. 2023,
13:48:
… I was thinking that maybe we can do more with the Telegram object. Like
indicating what the active gas meter reading is. Either by doing it
intelligently or manual passing the channel number.
So to start i think i want the parser to return a Telegram object. We
already had one, but it was wrapping the parser. I refactored that a bit:
#121 <#121>
Then i'm thinking we can for now (optionally) pass the gas meter channel
number via TelegramParser(.., gas_meter_channel=1). This thengets passed to
the Telegram object which can use it to return the correct gas reading.
Anyone got thoughts on this?
—
Reply to this email directly, view it on GitHub
<#51 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACCJDWDSTMUCWP7AQIQZTI3WSKOBHANCNFSM4MRMVTLQ>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Thanks. I've pushed some WIP. So if i'm on the same page:
|
Hi Nigel, I read through the code changes. In general I like very much where it is going. Some questions / remarks:
A little brainstorm how it could be: DEVICE_TYPE_GAS_METER = 003
# Telegram new methods
def get_mbus_devices --> return list of MBUSDeviceObject
def get_mbus_device(device_type, channel) --> MBUSDeviceObject containing a list of the relevant MBusObject
# then i can retrieve all values for the gas meter as
get_mbus_device(DEVICE_TYPE_GAS_METER)
# and if there is multiple of them
gas_meter_reading = get_mbus_device(DEVICE_TYPE_GAS_METER, channel)
# how it could be used
print(gas_meter_reading) # print all values for the device
print(gas_meter_reading.DEVICE_TYPE) # address specific values for the device
print(gas_meter_reading.EQUIPMENT_IDENTIFIER) # address specific values for the device
print(gas_meter_reading.VALVE_POSITION) # address specific values for the device
print(gas_meter_reading.GAS_METER_READING) # address specific values for the device BR, |
My initial idea was the following
I noticed that all lines have an ID part before the
So the idea was to group all of '0-n:24.2.x' and allow selecting using the 'n'. This seems more simple, but using the device lines seems more correct. So using your approach that would also mean that in general you would stop using HOURLY_GAS_METER_READING and GAS_METER_READING right? Ill try to give your idea a go somewhere this week :) Update: im looking into a new laptop after which i can continue developing |
How where you going to group them?
Maybe we would offer them still as to not break all existing usages, and say it is deprecated. Then in some future major release you could drop them? Not sure what is wisdom here. |
@ndokter : Or we could go the way like we did with the belgian meter. Just report type and values of all mbus devices connected, and let the software using the dmsr_parser then decide what to do with it. Cause there might be situations where you have 2 gas meters connected for ex? |
The latter was just reported this week in dsmrreader/dsmr-reader#1794. Two gas meters connected, although one of them reports zero usage. However, the datetime of that one seems to keep being bumped nonetheless, for some reason.
|
Ah see :) Personally I would do the same like the Belgian DSMR meter. Just report the values/type of each mbus, and then let the application which uses dsmr_parser to decide what to do with it. |
Update: found out that water meters, gas meters and thermal/heat/cold meters all use the same OBIS id's. So im working on something that lowdef suggested. Something like I did push something earlier today when i was still thinking i could go for a more simple solution, but that doesn't work |
I currently have made the following changes:
The 0-1 and 0-2 would be added to separate
If anyone has time, please let me know what you think PR: #121 |
I like the changes and it seems a good addition for clients having multiple mbus devices. |
However, please note that I do not directly use the latest (unaltered) version of DSMR-parser (or its low-level features) in DSMR-reader, so opinions of others should be taken more seriously for sure. |
the telegram logic does not work and can be simplified i think. Have to admit that I do not understand the current get_mbus_devices code. What shows me there is something wrong here, just using some arbitrary code without mbus devices: PyDev console: starting.
Python 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] on linux
runfile('/home/hanserik/projects/donderstraal/develop/issue92_Q3D_with_COM-1.py', wdir='/home/hanserik/projects/donderstraal/develop')
Q3D_EQUIPMENT_IDENTIFIER: 0272031312565 [None]
ELECTRICITY_IMPORTED_TOTAL: 52185.7825309 [kWh]
ELECTRICITY_EXPORTED_TOTAL: 19949.3221493 [kWh]
INSTANTANEOUS_ACTIVE_POWER_L1_POSITIVE: 747.85 [W]
INSTANTANEOUS_ACTIVE_POWER_L2_POSITIVE: 737.28 [W]
INSTANTANEOUS_ACTIVE_POWER_L3_POSITIVE: 639.73 [W]
CURRENT_ELECTRICITY_USAGE: 2124.86 [W]
Q3D_EQUIPMENT_STATE: 80 [None]
Q3D_EQUIPMENT_SERIALNUMBER: 1ESY1313002565 [None]
telegram.get_mbus_devices()
[]
telegram.get_mbus_device_by_channel(1)
<dsmr_parser.objects.MbusDevice object at 0x7f67f502d660>
telegram.get_mbus_devices()
[<dsmr_parser.objects.MbusDevice object at 0x7f67f502d660>]
telegram.get_mbus_device_by_channel(1)
<dsmr_parser.objects.MbusDevice object at 0x7f67f502d660>
telegram.get_mbus_devices()
[<dsmr_parser.objects.MbusDevice object at 0x7f67f502d660>]
telegram.get_mbus_device_by_channel(2)
<dsmr_parser.objects.MbusDevice object at 0x7f67f502dc30>
telegram.get_mbus_devices()
[<dsmr_parser.objects.MbusDevice object at 0x7f67f502d660>, <dsmr_parser.objects.MbusDevice object at 0x7f67f502dc30>]
Whats more executing again |
Thank you @lowdef that is a serious bug! It was caused by incorrect use of 'defaultdict' by me. It would instantiate a new MbusDevice for channels that did not exist. I have pushed the fix. The code currently groups all records that start with '0-<channel_id>' together in the MbusDevice object and exposes it via get_mbus_devices and get_mbus_device_by_channel. Do you mean by simplify, that you would merge them together? |
No, I must admit that I do not understand code like: I wonder if this can be expressed in a more intuitive manner. How does the sorting help? If there are for example channels 1 and 3, you would still always need to inspect the elements. |
I have added the channel ID to the MbusDevice itself and rewritten the sorting to be more intuitive:
The sorting might not be needed indeed. I thought it would be nice if you want to list them somewhere and the order would be 1, 2, 3 guaranteed |
you are quick ;-) What is nagging me: is there something against adding |
Oh wow that actually makes a lot of sense! I will try to incorporate that change and your other changes about the str and json method missing a bit later this week. Thanks a lot for your time and effort so far |
Somewhat late to the party :) But my comments:
I think we should have something more generic here. So this can be used for any kind of device. Can you also print the mbus_device channel-nr? mbus_device.CHANNEL_ID for example? |
@dupondje good point. Sounds like a good followup. It should probably be done using the DEVICE_ID (24.1.0), but i'm not sure how it works. In the following telegram (dsmr v5) i see the gas meter as device type 007:
And in this one (dsmr v4) it's 003:
|
@ndokter : Device types are described here: Electricity meter 02h So a Gas meter is 003, a water meter is 007. And in Belgium the gas meter value is on 24.2.3 because: |
It would be also nice to parse these device_types in to meaningful names as well... :-) |
I placed a thread here: home-assistant/core#101342 It seems to me that the meter should work as expected. My gas meter is currently at 27 m3, so I have lost a lot of data by now. I am seeing no data at all, it is not getting extracted to H.A. Recently I updated H.A. to a more current core version (2023.10.3), but I see no improvement. I do not know where, but I found somewhere that the current parser does not support DSMR 5.0 in my (newly placed) meter Landis+Gyr E360, and that it only went up to 4.2 (I can't find the page anymore). I hope this message is placed correctly and that it may lead to an improvement in the H.A. integration of the gas values. |
@fromNL :
Do you have any other 24.2.1 codes in your telegram? Otherwise the issue is something else. 24.2.1 should get parsed correctly on V4 or V5 |
I do see 0-1:24.2.1 is present, and just only one time. I took these lines from the debug info, it should be the complete telegram. |
@fromNL: Checked parsing of that telegram, and it seems to be correct. So it's not a dsmr_parser issue. |
Thanks for checking. I thought the same to be honest, and you directed me to this project (ndokter/dsmr_parser). Does this mean my previous thread at hassio was placed correct? |
After a while, we found out I had integration 5B installed. As soon as I updated this to version 5 and restarted H.A. all was looking well. I did have one entity that I had to delete afterwards, but that was it. For me it is case closed. |
Hi,
I am using the homeassistant integration with your dsmr_parser module.
My smartmeter is a version 5 smartmeter with standard settings (115200 8N1).
The readout with the parsed MBusObject always has value '0' for the HOURLY_GAS_METER_READING.
This readout is also used in the homeassistant integration.
When I look at the raw telegram_data of the TelegramObject I see that the gas meter reading is not 0 (truncated telegram with header and relevant line):
So there seems to be a problem with the parsing :(
The text was updated successfully, but these errors were encountered: