Neues Modul: UpsPico

Begonnen von Sailor, 22 September 2017, 15:32:34

Vorheriges Thema - Nächstes Thema

Sailor

Ein herzerfrischendes "Moin" vom "Hintern Deich" vorweg!

Ich habe soeben ein neues Modul ins Repository gestellt: 73_UpsPico.pm
Es dürfte also per Update-Befehl yur Verfügung stehen.

Der UpsPIco ist eine unterbrechungsfreie Stromversorgung für den Raspberry Pi von PiModules.
Dieses Modul wurde für die Firmware ab Version 0x38 und höher geschrieben und wurde nur auf dem "UPS PIco HV3.0A Stack Plus" getestet und stellt alle internen Daten zur Verfügung, welche in die UpsPIco Register geschrieben und über den I2C - Bus ausgelesen werden.

Der set-Befehl ist zur Zeit noch nicht implementiert, auch wenn die Commandref dies bereits vortäuscht.  ;)
Ich arbeite daran!

Detailierte Informationen zu den einzelnen Registern stehen in den Register Spezifikationen in der letzten veröffentlichten Anleitung. (Siehe unten)

Referenzen:
UPS PIco HV3.0A Stack Plus: http://www.pimodulescart.com/shop/item.aspx?itemid=29
UPS PIco HV3.0A : Interne Register Spezification, Anleitung and Firmware Updates: http://www.forum.pimodules.com/viewforum.php?f=25

Wer auch so ein Gerät besitzt, der darf mir gerne Rückmeldung zu diesem Modul geben!  :)

Gruss
    Sailor
******************************
Man wird immer besser...

Dr. Boris Neubert

Hallo Sailor,

ich habe mich heute länger erfolglos mit dem Modul beschäftigt. Meine Versuche fanden statt auf einem Raspberry Pi2B mit Debian 8.0 (Raspbian). Die PICO UPS ist auf dem selben Raspberry installiert.

Zunächst ist problematisch, dass weder Net::SSH::Perl noch Math::Expression::Evaluator über die Paketverwaltung installiert werden können. Also habe ich cpan bemüht, wobei Net::SSH::Perl sich auch nur nach Installation von libmath-gmp-perl installieren ließ. Das ist eine wahre Compiler-Orgie.

Das Modul kann sich dennoch nicht per SSH verbinden. Die Meldung "SSH Login to RasPi with UPS-PIco could not be established due to wrong credentials." ist irreführend. Ich habe mir daher $@ ausgeben lassen. Das eigentliche Problem ist

mkdir /root/.ssh: Permission denied at /usr/local/lib/arm-linux-gnueabihf/perl/5.20.2/Net/SSH/Perl/Util/Hosts.pm line 120.

Ich verstehe nicht, warum auf das .ssh-Verzeichnis von root zugriffen werden soll, da FHEM unter dem User fhem läuft. Damit ist mein Test beendet.

Der Zugriff auf root ist vermutlich kein isoliertes Problem dieses Moduls. Bei mir tritt es auf einer anderen FHEM-Installation auch in Zusammenhang mit Mail auf.

Sonstige Anmerkungen:

  • Ich würde immer $@ ausgeben, wenn ein Fehler aufgetreten ist. FHEM-Standardkonform ist Log-Level 2 für Fehler.
  • Ich würde versuchen, ohne die beiden schwer erhältlichen Module auszukommen.
  • Automatisches Setzen von Attributen, insbesondere room, ist FHEM-untypisch.
  • Unklar, warum das Attribut DbLogExclude heißt.
  • Commandref sollte bezeugen, dass alle readingsFnAttributes unterstützt werden und nicht nur event-on-change-reading.
  • Base64 ist nicht wirklich eine Verschlüsselung. Ich würde die Credentials in eine separate Datei auslagern und von dort lesen oder ausschließlich Login per Public/Private-Key zulassen
  • Unklar, warum die IP-Adresse und nicht der Hostname angegeben werden kann.
  • Zugriff ohne SSH wäre wünschenswert, wenn PICO UPS und FHEM auf demselben Raspberry laufen.

Viele Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

Sailor

Hallo Boris

Danke für deine detaillierte Rückmeldung. Solche empfinde ich immer als sehr hilfreich.


Zitat von: Dr. Boris Neubert am 21 Oktober 2017, 20:25:32
ich habe mich heute länger erfolglos mit dem Modul beschäftigt. Meine Versuche fanden statt auf einem Raspberry Pi2B mit Debian 8.0 (Raspbian). Die PICO UPS ist auf dem selben Raspberry installiert.

Das ist schade. Meine Umgebung war ein entfernter RasPi3 mit Jessi.

Zitat von: Dr. Boris Neubert am 21 Oktober 2017, 20:25:32

  • Ich würde immer $@ ausgeben, wenn ein Fehler aufgetreten ist. FHEM-Standardkonform ist Log-Level 2 für Fehler.
OK, das dürfte kein Problem sein zu implementieren

Zitat von: Dr. Boris Neubert am 21 Oktober 2017, 20:25:32

  • Ich würde versuchen, ohne die beiden schwer erhältlichen Module auszukommen.
Das ist schon eher eine Herausforderung. Woher bekomme ich ein Standard paketiertes SSH-Modul für Perl auf Debian her? Hast du eine Idee?

Zitat von: Dr. Boris Neubert am 21 Oktober 2017, 20:25:32

  • Automatisches Setzen von Attributen, insbesondere room, ist FHEM-untypisch.
Das mit dem room habe ich so von dem Homematic Modul übernommen. Es soll eigentlich nur beim ersten definieren verhindern, das das Device im Raum "Everything" verschwindet.
Die anderen Attribute brauche ich für den Betrieb und sollen den Benutzer aktiv ins Bewußtsein treten.

Zitat von: Dr. Boris Neubert am 21 Oktober 2017, 20:25:32

  • Unklar, warum das Attribut DbLogExclude heißt.
Das ist ein allgemeines Attribut vom DbLog-Modul. Das kommt nicht von mir. Es ergibt aber aus meiner Sicht keinen Sinn einen Watchdog-Counter ins Logfile zu schreiben.

Zitat von: Dr. Boris Neubert am 21 Oktober 2017, 20:25:32

  • Commandref sollte bezeugen, dass alle readingsFnAttributes unterstützt werden und nicht nur event-on-change-reading.
OK, das ist auch nicht weiter schwer zu implementieren.

Zitat von: Dr. Boris Neubert am 21 Oktober 2017, 20:25:32

  • Base64 ist nicht wirklich eine Verschlüsselung. Ich würde die Credentials in eine separate Datei auslagern und von dort lesen oder ausschließlich Login per Public/Private-Key zulassen
Hierzu fehlt mir ein generelles fhem-Feature mit den diversen Passwörter innerhalb von fhem umzugehen. Mein Favorit wäre eine db-Datenbank, welche nach devices sortiert die entsprechenden Credentials speichert.

Zitat von: Dr. Boris Neubert am 21 Oktober 2017, 20:25:32

  • Unklar, warum die IP-Adresse und nicht der Hostname angegeben werden kann.
OK, das ist wahr. Insbesondere bei DHCP vergebenen Adressbereichen macht der Hostname mehr Sinn...

Zitat von: Dr. Boris Neubert am 21 Oktober 2017, 20:25:32

  • Zugriff ohne SSH wäre wünschenswert, wenn PICO UPS und FHEM auf demselben Raspberry laufen.
DAS ist nach wie vor meine große Frage: Wie greife ich auf ein I2C-Bus eines entfernten RasPi zu? Wenn du da einen Tipp für mich hast, sind 4 der obigen Punkte mir einem Schlag erledigt!  ;)

Gruß
   Sailor
******************************
Man wird immer besser...

Dr. Boris Neubert

Zitat von: Sailor am 24 Oktober 2017, 06:01:13
...

Weil verschachtelte Zitate nicht gehen, antworte ich ohne Bezug.


  • Du kannst das Paket Net::OpenSSH benutzen.
  • Statt Math::Expression::Evaluator sollte es doch auch ein normales eval {} tun?
  • Ich habe mich am Namen DbLogExclude gerieben. Es hat nichts mit DbLog zu tun. Du verhinderst, dass ein Event erzeugt wird. Ich würde das Reading als ein INTERNAL definieren oder als ein verstecktes Reading.
  • Am einfachsten speicherst Du Usernamen und Passwort in einer extra Datei, die Du dann mit ($username,$password)= <DATEI> ausliest. Ich würde es aber bevorzugen, SSH mit Private/Public Key Encryption verwenden zu können.
  • Meine Anmerkung zum Verzicht auf SSH war auf den Fall gemünzt, dass die UPS auf dem Raspberry installiert ist, wo FHEM läuft.

Viele Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

justme1968

warum brauchst du überhaupt ein paket für ssh?

es gibt schon diverse module die einen remote zugang per ssh nutzen und ohne zusätzliche perl module auskommen. schau doch mal wie die das machen.

SYSSTAT, XiaomiFlowerSens, HOMBOT und UnifiVideo zum beispiel.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Sailor

Hallo zusammen

ich schau mir das auf alle Fälle mal an, sobald ich wieder Luft habe...

Habe im Augenblick ne Liste an Kleinigkeiten, die ich am Haus reparieren muss. (Bild aufhängen hier, Abluftanlage dort, Duschtrennwand auch noch...)
Mann muss ja den allgemeinen WAF erhalten!  ;)

Gruß
    Sailor
******************************
Man wird immer besser...

Sailor

Hallo Boris

Zitat von: Dr. Boris Neubert am 29 Oktober 2017, 18:39:55

  • Du kannst das Paket Net::OpenSSH benutzen.
OK, OpenSSH zu verwenden war der einfachere Teil. Die Befehle sind scheinbar 100% kompatibel.


Zitat von: Dr. Boris Neubert am 29 Oktober 2017, 18:39:55

  • Statt Math::Expression::Evaluator sollte es doch auch ein normales eval {} tun?
Der "Math::Expression::Evaluator" soll aus einem abgespeicherten String eine mathematische Formel formen und ausführen.
Geht das wirklich mit "eval"? Ich habe hierzu keinerlei Hinweise in der Anleitung gefunden.
Die Codezeile (948) lautet:
my $TempCalcResult = $MathParsingObject->parse("RegisterValue = " . $RegisterValue . "; " . $MathExpression)->val();
Wobei in der Stringvariablen "$RegisterValue" und "$MathExpression" die eigentlichen Variablen und Operatoren abgespeichert sind.
Wenn das mit eval geht... Nur her damit - Wieder eine Bibliothek weniger!


Zitat von: Dr. Boris Neubert am 29 Oktober 2017, 18:39:55

  • Ich habe mich am Namen DbLogExclude gerieben. Es hat nichts mit DbLog zu tun. Du verhinderst, dass ein Event erzeugt wird. Ich würde das Reading als ein INTERNAL definieren oder als ein verstecktes Reading.
Der Hintergrund der Aktion ist: Man soll die sich verändernden Werte dieses einen Readings zwar ganz normal sehen können, aber da sie ständig durchlaufen, sollen sie nicht geloggt werden, damit das LogFile nicht mit dem WatchDog Zähler zugemüllt wird.
Gibt es da eine geschicktere Variante?


Zitat von: Dr. Boris Neubert am 29 Oktober 2017, 18:39:55

  • Am einfachsten speicherst Du Usernamen und Passwort in einer extra Datei, die Du dann mit ($username,$password)= <DATEI> ausliest.
Hierbei gebe ich dir Recht. Eine "User:Password" - Datei wäre sehr interessant. Besser noch: Eine globales Passwort - Archive auf Basis einer Datenbank (Credentials.db) mit der Zuordnung zu den device-Namen.
Ich mache mir hierzu mal ein paar Gedanken, aber bis dahin lasse ich die erstmal so.


Zitat von: Dr. Boris Neubert am 29 Oktober 2017, 18:39:55

  • Ich würde es aber bevorzugen, SSH mit Private/Public Key Encryption verwenden zu können.
SSH mit Private/Public Key Encryption ist auf alle Fälle interessant und von der Sicherheit her am Stärksten. Aber dazu muss ich mich in die Thematik erst einlesen.

Zitat von: Dr. Boris Neubert am 29 Oktober 2017, 18:39:55

  • Meine Anmerkung zum Verzicht auf SSH war auf den Fall gemünzt, dass die UPS auf dem Raspberry installiert ist, wo FHEM läuft.
Ich könnte durchaus eine Fallabfrage machen für den Fall, dass der User statt Username Passwort das Schlüsselwort "LOCALHOST" eingibt.
Dann müsste ich nur noch die Perl-Pakete herausfinden, mit denen man den lokalen I2C - Bus auslesen kann...

Gruss
   Sailor
******************************
Man wird immer besser...

justme1968

zur password hinterlegung/verschlüsselung: es gibt in fhem die setKeyValue und getKeyValue routinen um passwörter abzulegen. zusätzliche extra dateien sind nicht nötig.

um sie unkenntlich zu machen verwenden einige module eine verschleierung mit der uniqueId.

ein so verschleiertes password kann man auch in einem reading oder attribut ablegen. readings und attribute die mit einem . anfangen sind im frontend und per list nicht sichtbar.

die module FB_CALLMONITOR, plex, netatmo oder alexa verwenden das einzeln oder in kombination um passwörter zu schützen.


aber: ssh sollte immer mit einem key paar verwendet werden. niemals mit user/password. erst recht nicht wenn diese irgendwo hinterlegt werden müssen.

bei ssh zugriff kann man auch die komplette ssh konfiguration auf ssh seite (ssh_config oder ssh/config) machen und im modul nur z.b. ssh_host vorsehen. wenn gesetzt wird ssh verwendet, sonst ist es lokal. das hat den vorteil das man was die konfiguration angeht alle möglichkeiten die ssh bietet ausschöpfen kann und nicht auf den im modul implementierten subset beschränkt ist. und wie gesagt: für ssh mit key authentifizierung ist kein extra modul nötig. es ist unterm strich wirklich einfacher.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Dr. Boris Neubert

Hallo,

Andre hat schon einen Teil vorweggenommen.

Zitat von: Sailor am 05 November 2017, 16:21:07
Der "Math::Expression::Evaluator" soll aus einem abgespeicherten String eine mathematische Formel formen und ausführen.
Geht das wirklich mit "eval"? Ich habe hierzu keinerlei Hinweise in der Anleitung gefunden.

Klar. Von welcher Anleitung redest Du? perldoc ist Dein Freund.

Zitat
Der Hintergrund der Aktion ist: Man soll die sich verändernden Werte dieses einen Readings zwar ganz normal sehen können, aber da sie ständig durchlaufen, sollen sie nicht geloggt werden, damit das LogFile nicht mit dem WatchDog Zähler zugemüllt wird.
Gibt es da eine geschicktere Variante?

Mach ein INTERNAL statt einem Reading daraus.

Zitat
Dann müsste ich nur noch die Perl-Pakete herausfinden, mit denen man den lokalen I2C - Bus auslesen kann...

Na, Du nimmst i2cget, nur nicht via ssh sondern eben direkt.

Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

justme1968

zu den readings und events:
du kannst die readings update routinen mit einem letzen optionalen parameter 0 anrufen. dann wird kein eint erzeugt.

oder du überlässt die entscheidung dem endanwender der wie bei allen anderen modulen die event-on- attribute einsetzen kann.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Sailor

#10
Hallo Boris

Zitat von: Dr. Boris Neubert am 05 November 2017, 16:40:33
Na, Du nimmst i2cget, nur nicht via ssh sondern eben direkt.

Ich habe mich mal an den internen i2c Zugang gemacht.
Das ist insoweit schwierig fuer mich, da ich das nicht testen kann da ich keinen UpsPico auf dem fhem Serer sitzen habe.
Kannst du mal das angehaengte file mal testen und wie folgt definieren:


define myUpsPico UpsPico
attr myUpsPico verbose 5


Ach ja: sudo cpanm RPi::I2C ist leider von Noeten.

Kannst du mir den entsprechende Logfile - Auszug schicken?
Mich wuerde interessieren, wie weit er kommt.

Danke

Gruss
    Sailor

******************************
Man wird immer besser...

Dr. Boris Neubert

Hallo Sailor,

nach Installation von

cpan -i RPi:I2C
apt-get install libnet-openssh-perl


als root lässt sich das Modul starten und läuft durch.

Die Fehlermeldung im Reading fullResponse lautet

Error internal I2C-connection failed. Check internal i2c-device and re-define device.

Nähere Untersuchung mit angefügtem Programm zeigt, dass check_device() das Problem verursacht. Dies kann mit beigefügtem Programm nachgestellt werden. Nachinstallation weiterer Pakete gemäß CPAN-Doku hilft nicht.

Du verwendest in der aktuellen Version i2cget mit sudo über ssh für remote hosts und einen Zugriff direkt aus Perl für lokalen Zugriff. Eine Variante wäre ein extra Sondenprogramm zu schreiben (python, perl), das auf dem Raspi mit der UPS läuft, und die Werte so aufbereitet, dass das FHEM-Modul diese nur abgreifen muss.

Oder Du verwendest i2cget in beiden Fällen, einmal lokal und das andere Mal über eine bestehende SSH-Verbindung.

Viele Grüße
Boris



Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

Sailor

Hallo Boris

Zitat von: Dr. Boris Neubert am 26 November 2017, 10:23:26
nach Installation von

cpan -i RPi:I2C
apt-get install libnet-openssh-perl


als root lässt sich das Modul starten und läuft durch.

Das mit root ist ein Problem.
Ich bin mit dem SSH Modul nicht weitergekommen. Da stockt alles auf ganzer Länge. Ich komme einfach nicht weiter.
OpenSSH mag nämlich keine SSH session starten, wenn das entsprechende SSH-Arbeitsverzeichnis nicht ausschließlich von dem gegenwärtigen User plus root zugraifbar ist.
Mir ist das OpenSSH - Modul langsam zu kompliziert. >:(

Nebenbei gefragt: Unter welchem User läuft fhem. Unter "pi" oder "fhem".

Zitat von: Dr. Boris Neubert am 26 November 2017, 10:23:26
Du verwendest in der aktuellen Version i2cget mit sudo über ssh für remote hosts und einen Zugriff direkt aus Perl für lokalen Zugriff. Eine Variante wäre ein extra Sondenprogramm zu schreiben (python, perl), das auf dem Raspi mit der UPS läuft, und die Werte so aufbereitet, dass das FHEM-Modul diese nur abgreifen muss.
Oder Du verwendest i2cget in beiden Fällen, einmal lokal und das andere Mal über eine bestehende SSH-Verbindung.

Sowohl als auch...
Wenn in der Definition kein HOST USER PASSWORD angegeben ist, verwendet er kein SSH sondern die RPi:I2C Bibliothek.
Andernfalls nimmt er SSH als Verbindungs-Grundlage.
Habe ich in der X_Define mit ner Fallabfrage gesteuert


Heißt das, das dein pl-Programm bis zur Zeile 10 funktioniert?
Dann schmeiß ich das check_device wieder raus.

Was spukt denn das Verbinden mit einer bekannten und unbekannten Adresse raus?

#!/usr/bin/perl -w

use strict;
use RPi::I2C;

my $device_addr = 0x45;
#my $device_addr = 0x69;
my $device = RPi::I2C->new($device_addr);
if (defined ($device)) {printf("Connection     successfull");}
else                   {printf("Connection NOT successfull");}

my $pcbversion = $device->read_byte(0x24);
printf("PCB Version= %02x\n", $pcbversion);


Ich brauche zunächst eine Abfrage, ob das Gerät überhaupt existiert, bevor ich es versuche auszulesen.
Ansonsten ist man sich nicht sicher, ober nur das Register (0x24) oder das komplette i2c Gerät (0x69) nicht existiert...

Danke

Gruss
   Sailor
******************************
Man wird immer besser...

Dr. Boris Neubert

Hallo,

das liefert leider beides successfull als Ergebnis. Es funktioniert aber wie folgt:

#!/usr/bin/perl -w

use strict;
use RPi::I2C;
my $d= RPi::I2C->new(0);
my $c62 = $d->check_device(0x62);
printf("%d\n", $c62);
my $c69 = $d->check_device(0x69);
printf("%d\n", $c69);


Ergebnis:
0
1


Am besten wäre es also

my $device= RPi::I2C->new($device_addr);
Fehlermeldung unless $device->checkdevice($device_addr);


zu verwenden und die Bus-Adresse explizit (mit Default 0x69) zu setzen, da das durchprobieren von anderen Adressen dort wohnende Devices verstören könnte.

Viele Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

Sailor

#14
Hallo Boris

Zitat von: Dr. Boris Neubert am 27 November 2017, 20:17:50
Es funktioniert aber wie folgt:

OK, das habe ich eingearbeitet.
Allerdings bekomme ich aufgrund der Zeile
my $I2CDevice  = RPi::I2C->new(0);
oder
my $I2CDevice  = RPi::I2C->new(0x00);
Die Fehlermeldung "Can't bless non-reference value at /usr/local/lib/arm-linux-gnueabihf/perl/5.20.2/RPi/I2C.pm line 30."

Laut CPAN docu sollte das so lauten:
my $I2CCheck69 = RPi::I2C->check_device(0x69);


Was sagt denn folgender Code?


#!/usr/bin/perl -w

use strict;
use RPi::I2C;
use constant false => 0;
use constant true  => 1;

### Predefine variables
my $I2CCheck69 = false;
my $I2CCheck6A = false;
my $I2CCheck59 = false;

### Make first contact with default address 0x69
$I2CCheck69 = RPi::I2C->check_device(0x69);

### If tryout of 0x69 was successfull
if ($I2CCheck69 eq true)
{
### Try to make contact with RTC address 0x6A
$I2CCheck6A = RPi::I2C->check_device(0x6A);
}
### If tryout of 0x69 was NOT successfull
else
{
### Try to make contact with alternate address 0x59
$I2CCheck59 = RPi::I2C->check_device(0x59);
}

printf("Check69 = %d\n", $I2CCheck69);
printf("Check6A = %d\n", $I2CCheck6A);
printf("Check59 = %d\n", $I2CCheck59);



Als naechstes ginge es  in dem unteren Code-Block um das Auslesen aller 255 Register:


### Open i2c connection
my $I2CDevice = RPi::I2C->new($RegisterI2CBlock);

### Download block
@RegisterBlock = $I2CDevice->read_block(255);

### Close i2c connection
undef $I2CDevice;

Es sollen alle 255 Register des i2c - Device hinter der Adresse "$RegisterI2CBlock" (0x69) als einzelne Array-Elemente eingelesen werden.


Danke nochmal fuer deine Hilfe!!!

Gruss
    Sailor
******************************
Man wird immer besser...