Code Monkey home page Code Monkey logo

Comments (7)

Krolken avatar Krolken commented on June 23, 2024

Hi.

Using the InformationFrame class and parsing one of the resoponse from your program I get the following results:

InformationFrame(
   destination_address=HdlcAddress(
       logical_address=1, 
       physical_address=None, 
       address_type='client', 
       extended_addressing=False), 
   source_address=HdlcAddress(l
      ogical_address=1, 
      physical_address=3768, 
      address_type='server', 
      extended_addressing=True), 
payload=b'\xe6\xe7\x00a)\xa1\t\x06\x07`\x85t\x05\x08\x01\x01\xa2\x03\x02\x01\x00\xa3\x05\xa1\x03\x02\x01\x00\xbe\x10\x04\x0e\x08\x00\x06_\x1f\x04\x00\x00\xfa\x1d\x00\xef\x00\x07', segmented=False, final=True, send_sequence_number=0, receive_sequence_number=1
)

So try with physical_server_address=3768

from dlms-cosem.

huebrick avatar huebrick commented on June 23, 2024

Probably should of mentioned I tried that too and used that in my original post. But for the sake of testing here is the test with phy adr set to 3768

2024-01-22 14:52:20 [debug    ] HDLC state transitioned        new_state=AWAITING_CONNECTION old_state=NOT_CONNECTED
2024-01-22 14:52:20 [debug    ] Sending data                   data=bytearray(b'~\xa0\t\x02:q\x03\x937\x9c~') transport=HdlcTransport(client_logical_address=1, server_logical_address=1, io=SerialIO(port_name='COM9', baud_rate=9600, timeout=10, serial_port=Serial<id=0x1ace99b8190, open=True>(port='COM9', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=10, xonxoff=False, rtscts=False, dsrdtr=False)), server_physical_address=3768, client_physical_address=None, extended_addressing=False, timeout=10, hdlc_connection=HdlcConnection(client_address=HdlcAddress(logical_address=1, physical_address=3768, address_type='server', extended_addressing=False), server_address=HdlcAddress(logical_address=1, physical_address=None, address_type='client', extended_addressing=False), client_ssn=0, client_rsn=0, server_ssn=0, server_rsn=0, max_data_size=128, state=HdlcConnectionState(current_state=AWAITING_CONNECTION), buffer=bytearray(b''), buffer_search_position=1), _send_buffer=[], out_buffer=bytearray(b''), in_buffer=bytearray(b''))
2024-01-22 14:52:30 [debug    ] Received data                  data=b'' transport=HdlcTransport(client_logical_address=1, server_logical_address=1, io=SerialIO(port_name='COM9', baud_rate=9600, timeout=10, serial_port=Serial<id=0x1ace99b8190, open=True>(port='COM9', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=10, xonxoff=False, rtscts=False, dsrdtr=False)), server_physical_address=3768, client_physical_address=None, extended_addressing=False, timeout=10, hdlc_connection=HdlcConnection(client_address=HdlcAddress(logical_address=1, physical_address=3768, address_type='server', extended_addressing=False), server_address=HdlcAddress(logical_address=1, physical_address=None, address_type='client', extended_addressing=False), client_ssn=0, client_rsn=0, server_ssn=0, server_rsn=0, max_data_size=128, state=HdlcConnectionState(current_state=AWAITING_CONNECTION), buffer=bytearray(b''), buffer_search_position=1), _send_buffer=[], out_buffer=bytearray(b''), in_buffer=bytearray(b''))
2024-01-22 14:52:40 [debug    ] Received data                  data=b'' transport=HdlcTransport(client_logical_address=1, server_logical_address=1, io=SerialIO(port_name='COM9', baud_rate=9600, timeout=10, serial_port=Serial<id=0x1ace99b8190, open=True>(port='COM9', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=10, xonxoff=False, rtscts=False, dsrdtr=False)), server_physical_address=3768, client_physical_address=None, extended_addressing=False, timeout=10, hdlc_connection=HdlcConnection(client_address=HdlcAddress(logical_address=1, physical_address=3768, address_type='server', extended_addressing=False), server_address=HdlcAddress(logical_address=1, physical_address=None, address_type='client', extended_addressing=False), client_ssn=0, client_rsn=0, server_ssn=0, server_rsn=0, max_data_size=128, state=HdlcConnectionState(current_state=AWAITING_CONNECTION), buffer=bytearray(b''), buffer_search_position=1), _send_buffer=[], out_buffer=bytearray(b''), in_buffer=bytearray(b''))

from dlms-cosem.

Krolken avatar Krolken commented on June 23, 2024

Try with extended_addressing=True too

from dlms-cosem.

huebrick avatar huebrick commented on June 23, 2024

Hey thanks! That worked and I am now able to read registers from the meter.

Now I have encountered another issue which is kind of strange, so basically I can read everything from the meter no problem and out of nowhere is starts giving me this error.

Traceback (most recent call last):
  File "C:\Users\Mikroelektronika\PycharmProjects\HDLC test\ReadFREQ.py", line 63, in <module>
    with management_client.session() as client:
  File "C:\Users\Mikroelektronika\AppData\Local\Programs\Python\Python312\Lib\contextlib.py", line 137, in __enter__
    return next(self.gen)
           ^^^^^^^^^^^^^^
  File "C:\Users\Mikroelektronika\PycharmProjects\HDLC test\.venv\Lib\site-packages\dlms_cosem\client.py", line 68, in session
    self.associate()
  File "C:\Users\Mikroelektronika\PycharmProjects\HDLC test\.venv\Lib\site-packages\dlms_cosem\client.py", line 167, in associate
    raise exceptions.DlmsClientException(
dlms_cosem.exceptions.DlmsClientException: DLMS Exception: <StateException.SERVICE_NOT_ALLOWED: 1>:<ServiceException.OPERATION_NOT_POSSIBLE: 1>

And it goes away by itself too after some time, I was trying to trace it to a specific issue like restarting the PC, USB - RS485 adapter, the meter, trying other versions of python and so on. The way I was able to solve it is by getting another meter :) and this works for some time but then the same problem strikes again. Now the evidence would probably point to the meter being the problem but when I try it with our internal tool it works without a problem.

Here is the code im using, so this works just at some point it fails without an obvious cause:

import logging
from functools import partial
from pprint import pprint

from dlms_cosem.protocol.xdlms.conformance import Conformance
from dlms_cosem.parsers import ProfileGenericBufferParser
from dlms_cosem.client import DlmsClient
from dlms_cosem import cosem, enumerations, utils, security
from dlms_cosem.io import SerialIO, HdlcTransport
from dlms_cosem.security import LowLevelSecurityAuthentication
from dlms_cosem import a_xdr, cosem, enumerations, utils
from dlms_cosem.a_xdr import AXdrDecoder
c = Conformance(
    general_protection=False,
    general_block_transfer=False,
    delta_value_encoding=False,
    attribute_0_supported_with_set=False,
    priority_management_supported=False,
    attribute_0_supported_with_get=False,
    block_transfer_with_get_or_read=True,
    block_transfer_with_set_or_write=True,
    block_transfer_with_action=True,
    multiple_references=True,
    data_notification=False,
    access=True,
    get=True,
    set=True,
    selective_access=True,
    event_notification=False,
    action=True,
)

usb_port: str = "COM4"


serial_io = SerialIO(
    port_name=usb_port,
    baud_rate=9600,
    timeout=500,
)



management_hdlc_transport = HdlcTransport(
    client_logical_address=1,
    server_logical_address=1,
    server_physical_address=2836,
    extended_addressing=True,
    io=serial_io,
)

management_client = DlmsClient(
    transport=management_hdlc_transport,
    authentication=LowLevelSecurityAuthentication(secret=b"12341234"),
)

CURRENT_ASSOCIATION_OBJECTS = cosem.CosemAttribute(
    interface=enumerations.CosemInterface.REGISTER,
    instance=cosem.Obis(1, 0, 1, 8, 0, 255),
    attribute=2,
)

with management_client.session() as client:
    profile = client.get(
        CURRENT_ASSOCIATION_OBJECTS,
    )
    result = utils.parse_as_dlms_data(profile)
print(result)

As you can see im using a different phy adrs then before, I have switched between few meters trying to get to the bottom of this :)

As I was writing this one of the meters decided to start working again so at this point I am very confused and am starting to suspect the meters being in some way the problem.

Also could you point me in the right direction on how would I go about writing to the registers?

from dlms-cosem.

Krolken avatar Krolken commented on June 23, 2024

You are getting an error on asscociate.

It is very manufacturer independant on how they handle this, but I think that it did not receive a previous release-request and
it still thinks it is associated. And when you send another associate-request it rejects it as it is already associated.

It might take a certain timeout for it to release the assocation on it self.

You could try if you already are associated by not using the .session() context manager and just call get() after connect()

from dlms-cosem.

huebrick avatar huebrick commented on June 23, 2024

I managed to get it working, but for the sake of those going down the same rabbit hole as me here is what was happening and how I solved it. This problem is caused when you have an error before the release_association() which causes the meter to think you are still associated and it doesn't allow new associations before the old one is closed.
So I solved this in a very hacky way, by basically sending this 7E A0 0A 00 02 FE FD 41 53 3C 94 7E over serial before callingconnect() which I think tells the meter to release all associations.

Thanks again for the help, just the fact that this is open source is amazing and is probably make learning DLMS HDLC a lot easier for me.

from dlms-cosem.

Krolken avatar Krolken commented on June 23, 2024

I think we could improve the session handling with a try-catch statement in the contextmanager.
So if we would get a DlmsClientError we would try to release the association.

something like:

 @contextlib.contextmanager
    def session(self) -> "DlmsClient":
        
        self.connect()
        self.associate()
        try:
             yield self
        catch DlmsClientError:
            if settings.release_association_on_error:
                self.release_association()
                self.disconnect()

        self.release_association()
        self.disconnect()

from dlms-cosem.

Related Issues (20)

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.