Hello,
I am working with the Gurux.DLMS Python library to configure a meter and I'm having trouble successfully writing to the send_destination_and_method attribute (attribute 3) of the Push Setup object (Class ID 40, OBIS 0.0.25.9.0.255).
The Problem
When I execute a write command to update the IPv6 destination address, the operation returns a "Success" status from the meter. However, when I immediately read the attribute back, the value has not changed; it remains the old IP address. i have tried
1. def write_push_destination(self, obis_code, new_address):
reader, media = None, None
try:
reader, media = self._connect()
self.log(f"Writing Push Destination for {obis_code} with IP: {new_address}")
# 1. Use the CORRECT object type to ensure the right Class ID (40) is sent.
push_setup_obj = GXDLMSPushSetup(obis_code)
# 2. Manually construct the exact data payload to match the working Kalkitech log.
data = GXByteBuffer()
# The value is a single STRUCTURE, not an array.
data.setUInt8(DataType.STRUCTURE.value) # 0x02
data.setUInt8(3) # 3 elements
# Element 1: Service Type. Enum, value 1, to match the working Kalkitech log.
data.setUInt8(DataType.ENUM.value) # 0x16
data.setUInt8(0) # THE CRITICAL CHANGE IS HERE
# Element 2: Destination Address (OctetString)
dest_bytes = new_address.encode('ascii')
data.setUInt8(DataType.OCTET_STRING.value) # 0x09
_GXCommon.setObjectCount(len(dest_bytes), data) # Helper to write length prefix
# The correct method to append raw bytes to the buffer:
data.set(dest_bytes, 0, len(dest_bytes))
# Element 3: Message Type. Enum, value 0 (A-XDR)
data.setUInt8(DataType.ENUM.value) # 0x16
data.setUInt8(0)
# 3. Set the fully-encoded byte buffer as the value of our PushSetup object.
push_setup_obj.value = data
self.log(f"Writing cleartext hex data for send_destination_and_method: {bytes(data).hex().upper()}")
# 4. Call write with the object and attribute index.
reader.write(push_setup_obj, 3)
self.log(f"Successfully sent write command for push destination.")
finally:
if reader:
try: reader.close()
except Exception: pass
if media and media.isOpen():
try: media.close()
except Exception: pass
self.log(f"Connection for writing push destination closed.")
2. def write_push_destination(self, obis_code, new_address):
reader, media = None, None
try:
reader, media = self._connect()
self.log(f"Writing Push Destination for {obis_code} with IP: {new_address}")
push_setup = GXDLMSPushSetup(obis_code)
destination_struct = [
[1, 1], # Service: [transport_service=1 (TCP), destination_sap=1]
new_address.encode('ascii') # The destination IP as bytes
]
# The 'destinations' property expects a list of these structures.
push_setup.destinations = [destination_struct]
# Write the new value to attribute 3.
reader.write(push_setup, 3)
self.log(f"Successfully sent write command for push destination.")
finally:
if reader:
try: reader.close()
except Exception: pass
if media and media.isOpen():
try: media.close()
except Exception: pass
self.log(f"Connection for writing push destination closed.")
Hi, Your data should be…
Hi,
Your data should be correct if the meter returns success for the write.
You can also try this:
push_setup = GXDLMSPushSetup(obis_code)
push_setup.service = ServiceType.TCP
push_setup.destination = new_address.encode('ascii')
push_setup.message = MessageType.COSEM_APDU
reader.write(push_setup, 3)
BR,
Mikko