Incorrect current values for Landis Gyr E570 meter
Hi,
I wrote a function that should return current values, but instead of correct values I get incorrect values, e.g. 0 values, or negative values.
What am I doing wrong?
Here is the function:
@app.route('/read/<int:meter_id>/<string:obis>', methods=["GET"])
def read_value(meter_id, obis):
print(f"DEBUG: Proba odczytu OBIS {obis} dla licznika {meter_id}")
reader = None
connection_key = None
for key in connection_manager.connections:
if meter_id in connection_manager.connections[key]:
reader = connection_manager.connections[key][meter_id]
connection_key = key
break
if not reader:
print(f"DEBUG: Brak polaczenia z licznikiem {meter_id}")
return jsonify({"error": "Brak aktywnego polaczenia"})
media_key = connection_manager.get_media_key_for_meter(meter_id)
if not media_key:
print(f"DEBUG: Nie mozna znalezc medium dla licznika {meter_id}")
return jsonify({"error": "Nie znaleziono medium komunikacyjnego"})
def perform_read_operation():
try:
reader.settings.client.contextId = meter_id
if hasattr(reader.settings.media, 'isOpen'):
if not reader.settings.media.isOpen():
print(f"DEBUG: Medium dla licznika {meter_id} jest zamkniete - proba ponownego otwarcia")
reader.settings.media.open()
time.sleep(0.5)
print(f"DEBUG: Sprawdzam polaczenie z licznikiem {meter_id}")
for attempt in range(2):
try:
reader.settings.client.contextId = meter_id
clock_object = next((obj for obj in reader.client.objects if obj.logicalName == "0.0.1.0.0.255"), None)
if clock_object:
reader.read(clock_object, 2)
print(f"DEBUG: Polaczenie z licznikiem {meter_id} jest aktywne")
break
else:
print(f"DEBUG: Brak obiektu zegara dla licznika {meter_id}")
if attempt == 1:
return {"error": "Brak obiektu zegara w liczniku"}
except Exception as e:
print(f"DEBUG: Blad sprawdzania polaczenia (proba {attempt+1}/2): {e}")
if attempt == 1:
try:
print(f"DEBUG: Proba reinicjalizacji polaczenia")
reader.initializeConnection()
print(f"DEBUG: Pomyslnie zresetowano polaczenie")
except Exception as reinit_err:
print(f"DEBUG: Blad reinicjalizacji: {reinit_err}")
return {"error": f"Nie mozna ustanowic stabilnego polaczenia: {reinit_err}"}
obj = None
try:
reader.settings.client.contextId = meter_id
obj = next((o for o in reader.client.objects if o.logicalName == obis), None)
if not obj:
return {"error": "Nie znaleziono OBIS"}
except Exception as e:
print(f"DEBUG: Blad podczas szukania obiektu OBIS: {e}")
return {"error": f"Blad podczas szukania obiektu: {e}"}
try:
reader.settings.client.contextId = meter_id
value = reader.read(obj, 2)
original_raw_value = value
serializable_raw_value = original_raw_value
if isinstance(original_raw_value, GXDateTime):
serializable_raw_value = gxdatetime_to_str(original_raw_value)
elif isinstance(original_raw_value, bytes):
serializable_raw_value = original_raw_value.hex()
elif hasattr(original_raw_value, '__dict__'):
serializable_raw_value = str(original_raw_value)
if isinstance(value, GXDateTime):
value = gxdatetime_to_str(value)
print(f"DEBUG: Przekonwertowano GXDateTime na string: {value}")
elif isinstance(value, bytes):
value = value.hex()
print(f"DEBUG: Przekonwertowano bytes na hex string: {value}")
is_voltage = False
is_current = False
is_power = False
is_energy = False
voltage_obis_codes = [
"1.0.32.7.0.255", "1.0.52.7.0.255", "1.0.72.7.0.255", # Napięcia wtórne
"1.4.32.7.0.255", "1.4.52.7.0.255", "1.4.72.7.0.255", # Napięcia pierwotne
"1-0:32.7.0", "1-0:52.7.0", "1-0:72.7.0"
]
current_obis_codes = [
"1.0.31.7.0.255", "1.0.51.7.0.255", "1.0.71.7.0.255", # Prądy wtórne
"1.4.31.7.0.255", "1.4.51.7.0.255", "1.4.71.7.0.255", # Prądy pierwotne
"1-0:31.7.0", "1-0:51.7.0", "1-0:71.7.0"
]
power_obis_codes = [
"1.0.1.7.0.255", "1.0.1.6.0.255", # Moc czynna wtórna
"1.4.1.7.0.255", "1.4.2.7.0.255", # Moc czynna pierwotna
"1.4.3.7.0.255", "1.4.4.7.0.255", # Moc bierna pierwotna
"1.4.5.7.0.255", "1.4.6.7.0.255", "1.4.7.7.0.255", "1.4.8.7.0.255",
"1.4.91.7.0.255"
]
energy_obis_codes = [
"1.0.1.8.0.255", "1.0.1.8.1.255", "1.0.1.8.2.255", # Energia czynna pobrana
"1.0.2.8.0.255", "1.0.2.8.1.255", "1.0.2.8.2.255", # Energia czynna oddana
"1.0.3.8.0.255", "1.0.4.8.0.255" # Energia bierna
]
if obis in voltage_obis_codes or any(obis.startswith(code) for code in voltage_obis_codes):
is_voltage = True
print(f"DEBUG: Wykryto OBIS napiecia: {obis}")
elif obis in current_obis_codes or any(obis.startswith(code) for code in current_obis_codes):
is_current = True
print(f"DEBUG: Wykryto OBIS pradu: {obis}")
elif obis in power_obis_codes or any(obis.startswith(code) for code in power_obis_codes):
is_power = True
print(f"DEBUG: Wykryto OBIS mocy: {obis}")
elif obis in energy_obis_codes or any(obis.startswith(code) for code in energy_obis_codes):
is_energy = True
print(f"DEBUG: Wykryto OBIS energii: {obis}")
scalar = getattr(obj, 'scaler', 0)
unit = getattr(obj, 'unit', 0)
scalar_source = "XML"
if is_voltage or is_current:
print(f"DEBUG: Odczytuje skalar bezposrednio z licznika dla {'napiecia' if is_voltage else 'pradu'}")
try:
attr_index = 3
if hasattr(obj, 'objectType') and obj.objectType == ObjectType.DEMAND_REGISTER:
attr_index = 4
reader.settings.client.contextId = meter_id
scaler_result = reader.read(obj, attr_index)
print(f"DEBUG: Surowa odpowiedz odczytu skalara: {scaler_result}")
print(f"DEBUG: Typ odpowiedzi: {type(scaler_result)}")
if isinstance(scaler_result, tuple) and len(scaler_result) >= 2:
if hasattr(scaler_result[0], 'value'):
scalar = scaler_result[0].value
elif isinstance(scaler_result[0], (int, float)):
scalar = int(scaler_result[0])
else:
print(f"DEBUG: Nieznany typ skalara: {type(scaler_result[0])}")
if hasattr(scaler_result[1], 'value'):
unit = scaler_result[1].value
elif isinstance(scaler_result[1], (int, float)):
unit = int(scaler_result[1])
else:
print(f"DEBUG: Nieznany typ jednostki: {type(scaler_result[1])}")
scalar_source = "LICZNIK"
print(f"DEBUG: Odczytano z licznika - skalar: {scalar}, jednostka: {unit}")
elif isinstance(scaler_result, list) and len(scaler_result) >= 2:
scalar = int(scaler_result[0]) if isinstance(scaler_result[0], (int, float)) else scalar
unit = int(scaler_result[1]) if isinstance(scaler_result[1], (int, float)) else unit
scalar_source = "LICZNIK"
print(f"DEBUG: Odczytano z licznika (lista) - skalar: {scalar}, jednostka: {unit}")
elif hasattr(scaler_result, 'scaler') and hasattr(scaler_result, 'unit'):
scalar = scaler_result.scaler
unit = scaler_result.unit
scalar_source = "LICZNIK"
print(f"DEBUG: Odczytano z licznika (obiekt) - skalar: {scalar}, jednostka: {unit}")
else:
print(f"DEBUG: Nieoczekiwany format odpowiedzi, uzywam wartosci z XML")
except Exception as e:
print(f"DEBUG: Nie udalo sie odczytac skalara z licznika: {e}")
print(f"DEBUG: Fallback - uzywam wartosci z XML")
print(f"DEBUG: OBIS {obis}:")
print(f" - Surowa wartosc z licznika: {original_raw_value}")
print(f" - Typ wartosci: {type(original_raw_value)}")
print(f" - Skalar ({scalar_source}): {scalar}")
print(f" - Jednostka ({scalar_source}): {unit} ({get_unit_name(unit)})")
print(f" - Czy to napiecie: {is_voltage}")
print(f" - Czy to prad: {is_current}")
print(f" - Czy to moc: {is_power}")
print(f" - Czy to energia: {is_energy}")
scaled_value = value
if isinstance(value, (int, float)) and scalar is not None:
scaled_value = apply_scaler_to_value(value, scalar, unit)
print(f"DEBUG: Zastosowano skalar {scalar} z jednostka {unit}: wynik = {scaled_value}")
if unit in [30, 31, 32] and is_energy: # kWh, kVAh, kvarh
if scaled_value > 1000:
scaled_value = scaled_value / 1000.0
scaled_value = round(scaled_value, 3)
print(f"DEBUG: Dodatkowo podzielono energie przez 1000: {scaled_value}")
elif unit in [27, 28, 29] and is_power: # kW, kVA, kvar
if scaled_value > 1000:
scaled_value = scaled_value / 1000.0
scaled_value = round(scaled_value, 3)
print(f"DEBUG: Dodatkowo podzielono moc przez 1000: {scaled_value}")
unit_name = ""
if unit is not None:
unit_name = get_unit_name(unit)
if isinstance(scaled_value, (int, float)):
scaled_value = round(scaled_value, 3)
print(f"DEBUG: Koncowa wartosc: {scaled_value}")
return {
"obis": obis,
"value": scaled_value,
"scalar": scalar,
"unit": unit,
"unit_name": unit_name,
"raw_value": serializable_raw_value,
"scalar_source": scalar_source,
"is_voltage": is_voltage,
"is_current": is_current,
"is_power": is_power,
"is_energy": is_energy
}
except Exception as e:
print(f"DEBUG: Blad odczytu wartosci: {e}")
import traceback
traceback.print_exc()
return {"error": f"Blad odczytu: {e}"}
except Exception as e:
print(f"DEBUG: Nieoczekiwany blad: {e}")
import traceback
traceback.print_exc()
return {"error": f"Nieoczekiwany blad: {e}"}
try:
future = operation_queue.enqueue_operation(media_key, perform_read_operation)
result = future.result(timeout=30)
return jsonify(result)
except Exception as e:
print(f"DEBUG: Blad podczas wykonywania operacji w kolejce: {e}")
import traceback
traceback.print_exc()
return jsonify({"error": f"Operacja zakonczyla sie niepowodzeniem: {e}"})
Thanks in advance for your help