Fehler in MeterCarloGavazziEm300Impl.java

Hallo,
in MeterCarloGavazziEm300Impl.java ist meiner Meinung nach die Abfrage von ElectricityMeter.ChannelId.CURRENT_L1, ElectricityMeter.ChannelId.CURRENT_L2 und ElectricityMeter.ChannelId.CURRENT_L3 falsch.
Als Faktor wird SCALE_FACTOR_2 verwendet, der Zähler liefert aber bereits mA (In der Dokumentation steht: Value weight: Ampere*1000).
Daher gehe ich davon aus, dass hier stattdessen DIRECT_1_TO_1 korrekt wäre.
Kann das jemand bestätigen?

Hallo,

ich habe das gerade auf ein paar Systemen gegengeprüft und du hast Recht. die Werte sind aktuell um den Faktor 1000 zu hoch.

Gruß,
Stefan

Hallo Stefan,

wirklich Faktor 1000? Bei mir (FEMS über REST/Json abgefragt), ist es Faktor 100. Das würde auch eher zum SCALE_FACTOR_2 passen.

{
 "address": "meter1/CurrentL1",
 "type": "INTEGER",
 "accessMode": "RO",
 "text": "",
 "unit": "mA",
 "value": 36500
}

Da müssten eigentlich 365 mA stehen.

Gruss

Stefan

Stimmt, es ist ca. um den Faktor 100 falsch. Tatsächlich sollte man wohl auch die beiden Read-Blöcke zu einem zusammenfassen, damit Strom, Spannung und Leistung besser zusammenpassen bzw. zeitgleich gelesen werden. (https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.meter.carlo.gavazzi.em300/src/io/openems/edge/meter/carlo/gavazzi/em300/MeterCarloGavazziEm300Impl.java#L106)

Darf ich auf einen Pull-Request hoffen oder soll ich das intern bei FENECON auf die (lange) ToDo-Liste nehmen?

Gruß,
Stefan

Einige Anmerkungen zum Thema EM300.
Bezogen auf den EM300 gibt es bereits einen älteren PR #1991 der aus der einen EM300 Komponente eine EM300 und eine EM24 Komponente macht. Der PR kompiliert nicht mehr und hatte einige andere Problemem, weshalb wir ihn schließen werden.

Der EM300 und der EM24 ähneln sich sehr (bis auf jeweils andere Register für die Energiewerte).
Der EM24 hat noch eine Eigenart. Die Hardware ist sehr limitiert und man kann immer nur bis zu (ich glaube) 24 Modbus-Register am Stück auslesen. Daher haben wir in unserer Basis-Implementierung den Lesevorgang in 6 Read Tasks untergliedert.

Ein weiteres Problem: In der Praxis kommt es immer wieder vor, dass Installateure EM24 einkonfigurieren, aber einen EM300 verbaut haben. Das führt zu unnötigen Support-Overhead.
Ich habe gerade gesehen, das beide Carlo Gavazzi Modbus-Tabellen ein Control Identification Code Register haben (300012). Anhand dessen kann man das Model unterscheiden.
Damit werden wir unsere Implementierung aktualisieren, umbauen und einen neuen PR stellen. Dabei können wir dann auch die Skalierung korrigieren.

Frage an @stefan.feilmeier: Wenn wir das Bundle erweitern, so daß es auch mit EM24 umgehen kann, so würde ich sowohl den Bundle-Namen carlo.gavazzi.em300 als auch die Factory-ID Meter.CarloGavazzi.EM300 der Komponente abändern in eine generische Form, z.B. in

  • Bundle carlo.gavazzi
  • Factory-ID Meter.CarloGavazzi oder Meter.CarloGavazzi.EM-series

Wenn wir das tun, bricht das sowohl eure als auch unsere Konfigurationen. Das EM300 im Namen zu belassen erscheint mir allerdings auch nicht richtig. Wie seit ihr bisher mit dieser Art Probleme umgegangen? Wie gehen wir in Zukunft damit um?

Hallo Christian,

danke für den wertvollen Input! Der Unterschied war mir nicht bewusst. Das Problem mit falsch konfigurierten Komponenten hatten wir früher bei den SOCOMEC-Zählern regelmäßig - bis wir es dann ebenfalls generisch gelöst haben. Ich glaube die dortige Implementierung taugt sehr gut als Vorlage für eine überarbeitete Carlo-Gavazzi-Komponente: https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.meter.socomec/src/io/openems/edge/meter/socomec/threephase/MeterSocomecThreephaseImpl.java

Das Problem mit der Factory-ID haben wir damals über den DefaultConfigurationWorker gelöst. Dafür haben wir in unserem internen Repo folgenden Code:

Code aufklappen
/**
 * Migrate to OpenEMS version 2020.11.5.
 * 
 * @param existingConfigs     the existing {@link Config}s
 * @param configurationFailed the result of the configuration, updated on error
 */
private void migrateConfigurationOnVersion_2020_11_5(List<Config> existingConfigs,
		AtomicBoolean configurationFailed) {
	/*
	 * Upgrade to generic SOCOMEC implementation.
	 */
	// Threephase
	existingConfigs.stream().filter(c -> c.componentId.isPresent() && (//
	"Meter.SOCOMEC.DirisA10".equals(c.factoryPid) //
			|| "Meter.SOCOMEC.DirisA14".equals(c.factoryPid) //
			|| "Meter.SOCOMEC.DirisB30".equals(c.factoryPid) //
			|| "Meter.SOCOMEC.DirisE24".equals(c.factoryPid) //
	)).forEach(c -> {
		String alias = DictionaryUtils.getAsOptionalString(c.properties, "alias").orElse("");
		boolean enabled = DictionaryUtils.getAsOptionalBoolean(c.properties, "enabled").orElse(true);
		String modbusId = DictionaryUtils.getAsString(c.properties, "modbus.id");
		int modbusUnitId = DictionaryUtils.getAsInteger(c.properties, "modbusUnitId"); // can cause NPE
		boolean invert = DictionaryUtils.getAsOptionalBoolean(c.properties, "invert").orElse(false);
		String type = DictionaryUtils.getAsString(c.properties, "type");

		this.deleteConfiguration(configurationFailed, c.componentId.get());

		this.createConfiguration(configurationFailed, "Meter.Socomec.Threephase", Arrays.asList(//
				new Property("id", c.componentId.get()), //
				new Property("alias", alias), //
				new Property("enabled", enabled), //
				new Property("modbus.id", modbusId), //
				new Property("modbusUnitId", modbusUnitId), //
				new Property("invert", invert), //
				new Property("type", type) //
		));
	});
	// Singlephase
	existingConfigs.stream().filter(c -> c.componentId.isPresent() //
			&& "Meter.SOCOMEC.CountisE24".equals(c.factoryPid)//
	).forEach(c -> {
		String alias = DictionaryUtils.getAsOptionalString(c.properties, "alias").orElse("");
		boolean enabled = DictionaryUtils.getAsOptionalBoolean(c.properties, "enabled").orElse(true);
		String modbusId = DictionaryUtils.getAsString(c.properties, "modbus.id");
		int modbusUnitId = DictionaryUtils.getAsInteger(c.properties, "modbusUnitId"); // can cause NPE
		boolean invert = DictionaryUtils.getAsOptionalBoolean(c.properties, "invert").orElse(false);
		String type = DictionaryUtils.getAsString(c.properties, "type");

		this.deleteConfiguration(configurationFailed, c.componentId.get());

		this.createConfiguration(configurationFailed, "Meter.Socomec.Singlephase", Arrays.asList(//
				new Property("id", c.componentId.get()), //
				new Property("alias", alias), //
				new Property("enabled", enabled), //
				new Property("modbus.id", modbusId), //
				new Property("modbusUnitId", modbusUnitId), //
				new Property("invert", invert), //
				new Property("type", type) //
		));
	});
}

Tatsächlich muss ich aber sagen, dass ich auch damit leben könnte, die Factory-ID einfach als carlo.gavazzi.em300 zu lassen - sie ist ja schließlich nicht falsch sondern nur unvollständig. Den Namen und die README sollten wir natürlich anpassen.

Sollen wir daran gemeinsam arbeiten? Oder macht ihr erstmal einen Vorschlag auf Basis der SOCOMEC-Implementierung?

Gruß,
Stefan

Ist gerade geschehen.

Gruss

Stefan

Hallo Stefan,
vielen Dank für den super Hinweis auf den DefaultConfigurationWorker. Eine einfache und elegante Lösung für einen Softwareupdate mit Konfigurationsänderung. Da haben sich gerade einige gedankliche Stolpersteine in meinem Kopf in Luft aufgelöst :wink: .

@tsicking wird sich zeitnah an die Abänderung des Bundles setzen (angelehnt an SOCOMEC), es auf beiden Zählertypen austesten und einen Vorschlag machen.
Die Factory-ID lassen wir bestehen. Damit können wir im Hinblick auf die höhere Gesamtsystemstabilität auch gut leben.

2 Likes