Ankündigung

Einklappen
Keine Ankündigung bisher.

brauche Hilfe bei Datentypen

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • boxerfahrer
    antwortet
    Hallo Thoern,

    damit bin ich ein ganzes Stück weiter gekommen. Gibt es vielleicht eine Doku, damit ich hier nicht mit jeder Frage wieder aufkreuze ?

    Konkret hänge ich an einer socket-Verbindung, die ich zu WP aufbauen muss, um die auszulesen.
    Code:
    use IO::Socket;
    .
    .
    .
    sub open_heatpump_connection
    {
      my $socket;
      $socket = IO::Socket::INET->new (  PeerAddr => '192.168.178.4', PeerPort => 8888, Type => SOCK_STREAM  );
      die "Fehler: $!\n"
        unless defined $socket;
      $socket->autoflush(1);
    }
    Führt dann zu folgender Fehlermeldung:
    Code:
      16/02/11 11:16:42 AM: Not a HASH reference at (eval 271) line 10.
    Line 5:  use vars qw($WW_Temperatur);
    Line 6:
    Line 7:    $socket = IO::Socket::INET->new (  PeerAddr => '192.168.178.4', PeerPort => 8888, Type => SOCK_STREAM  );
    Line 8:         $WW_Temperatur =  new EIB5_Item('3/0/10', 'R|label=Celsius');
    Line 9:  $objects_by_object_name{'$socket'} = $socket;
    Line 10:  $socket->{category} = "wp_auslesen";
    Line 11:  $socket->{filename} = "wp_auslesen";
    Line 12:  $socket->{object_name} = '$socket';
    Line 13:  $objects_by_object_name{'$WW_Temperatur'} = $WW_Temperatur;
    Line 14:  $WW_Temperatur->{category} = "wp_auslesen";
    Line 15:  $WW_Temperatur->{filename} = "wp_auslesen";
    Offensichtlich baut mh da Strukturen auf, in die $socket nicht reinpasst.

    Einen Kommentar schreiben:


  • thoern
    antwortet
    Hi,

    zwei Möglichkeiten:

    1. Wenn dein Objekt bereits im *.mht-File vorhanden ist und es wurde bereits ein *.mhp-File daraus generiert, kannst du wie folgt aufrufen:

    /usr/local/misterhouse/bin/mh <filename>.mhp <usercode>.pl

    Dannn werden zuerst die Objekte aus dem mhp-File erzeugt und dann dein Skript ausgeführt.

    2. Wenn du es ohne das mhp-File aufrufst, musst du das Objekt in deinem Skript erzeugen. Also am Anfang vom Skript so etwas reinschreiben:

    $Kuechentemperatur = new EIB5_Item('5/2/1')

    Keine Sorge, auch wenn das Usercode-Skript in einer Schleife läuft, mh ist so schlau und erzeugt das Objekt nur einmal. Wenn du mit dem Testen fertig bist, musst du allerdings das Objekt wieder vom Usercode entfernen, da es beim normalen Start von misterEIB dann zweimal erzeugt würde (einmal aus dem mhp-File und einmal aus deinem Skript).

    Viel Spass,
    thoern

    Einen Kommentar schreiben:


  • boxerfahrer
    antwortet
    der Test lief auf Anhieb, Klasse!

    Jetzt wollte ich im nächsten Schritt natürlich direkt auf eine Gruppenadresse schreiben. Die habe ich im .mht File im Code Directory wie folgt definiert:

    Code:
    EIB5,               3/0/10,              Warmwasser_Temperatur,                 Zentral_Waermepumpe, unit=°C
    Also bin ich davon ausgegangen, dass ich die im perl UserCode nicht nochmals definieren darf. Ich habe dann versucht, direkt darauf zu schreiben:
    Code:
    sub write_eib_wvs_data
    {
      $Warmwasser_Temperatur->set(44);
    }
    Aber ich bekomme eine Fehlermeldung wegen fehlender Definition:
    Code:
    15/02/11 06:06:31 PM Evaluating user code
    
    Error in user code file /opt/mistereib/data/mh_temp.user_code
    
      15/02/11 06:06:31 PM: Global symbol "$Warmwasser_Temperatur" requires explicit package name at (eval 271) line 148.
    Line 143:  # subroutine write_eib_wvs_data:
    Line 144:  ##################################################################################
    Line 145:  #
    Line 146:  sub write_eib_wvs_data
    Line 147:  {
    Line 148:    $Warmwasser_Temperatur->set(44);
    Line 149:  }
    Line 150:  ##################################################################################
    Line 151:  print "Starting Heatpump LogData Extractor\n";
    Line 152:
    Line 153:  open_heatpump_connection;
    Wird der .mht File nicht zuerst ausgewertet?

    Gruß
    -boxerfahrer

    Einen Kommentar schreiben:


  • thoern
    antwortet
    hab jetzt keine Zeit deshalb nur kurz: nein.

    Einen Kommentar schreiben:


  • boxerfahrer
    antwortet
    danke!

    Fragen über Fragen - entsteht durch das zyklische Ausführen nicht eine hohe CPU Last ohne das "produktiv" gearbeitet wird?

    Gruß
    - boxerfahrer

    Einen Kommentar schreiben:


  • thoern
    antwortet
    Uses - gar keins.

    Was du noch wissen solltest, die Usercodeskripte werden werden zyklisch ausgeführt

    leg einfach mal ein Skript an namens

    humblpfrumbf.pl
    Code:
    print "humblpfrumpf wird ausgefuehrt\n"
    Dann mh_parms exportieren und folgendes aufrufen:

    /usr/local/misterhouse/bin/mh humblpfrumbf.pl

    Und dann schau mal was passiert. Achtung: ein "exit" im Skript beendet auch misterhouse

    Gruß,
    thoern

    Einen Kommentar schreiben:


  • boxerfahrer
    antwortet
    Herzlichen Dank!

    eine Frage noch - welche "uses" brauche ich denn um das time_cron() zu nutzen ??

    Einen Kommentar schreiben:


  • thoern
    antwortet
    Hi,

    das mit dem Usercode ist relativ einfach. Beispiel:

    waermepumpe.pl
    Code:
    if (time_cron('5 * * * *')) { 
    
       # hier steht der Code der die WP ausliest und im Anschluss
       # $MeinEIB5Objekt->set($wert) ausführt.
    };
    Das Skript legst du im code-Verzeichnis von mistereib ab. Mistereib restarten, Skript wird ausgeführt.

    Zum testen beim Programmieren gehst du wie folgt vor:
    Die Variable mh_parms von Mistereib exportieren, z.B.

    export mh_parms=/path_to_mistereib/mh.private.ini

    Dann Misterhouse nur mit dem Skript aufrufen:
    /usr/local/misterhouse/bin/mh waermepumpe.pl


    Hier noch ein Beispiel einer Heizungsautomatik als Usercode:

    heizungsautomatik.pl

    Code:
    if ($Heizungsautomatik->state eq 'on') {
    
    
       # Montag - Freitag Raumtemperaturen um 4:00 Uhr anheben:
       if (time_cron('0 4 * * 1-5')) { heizung_anheben() };
    
       # Samstag und Sonntag Raumtemperaturen um 6:30 Uhr anheben:
       if (time_cron('0 6 * * 6,0')) { heizung_anheben() };
    
       # Sonntag - Donnerstag Raumtemperaturen um 22:30 absenken:
       if (time_cron('30 22 * * 0-4')) { heizung_absenken() };
    
       # Freitag und Samstag Raumtemperaturen um 23:30 absenken:
       if (time_cron('30 23 * * 5-6')) { heizung_absenken() };
    
       # Montag, Dienstag, Donnerstag um 7:30 Uhr Raumtemperatur
       # absenken und um 11:30 Uhr wieder auf normal:
       if (time_cron('30 7 * * 1,2,4'))  { heizung_absenken() };
       if (time_cron('30 11 * * 1,2,4')) { heizung_normal() };
    
       # Mittwoch und Freitag Raumtemperatur um 08:30 auf normal:
       if (time_cron('30 8 * * 3,5')) { heizung_normal() };
    
    } elsif ($Heizungsautomatik->state_changed) {
       heizung_normal();
    }
    
    sub heizung_anheben {
       $EG_RCD_Kueche->set(23);
       $EG_RCD_Bad->set(24);
       $DG_RCD_Bad->set(24);
    }
    sub heizung_normal {
       $EG_RCD_Kueche->set(22);
       $EG_RCD_Bad->set(24);
       $DG_RCD_Bad->set(22);
    }
    sub heizung_absenken {
       $EG_RCD_Kueche->set(20);
       $EG_RCD_Bad->set(22);
       $DG_RCD_Bad->set(20);
    }
    Viel Erfolg,
    thoern

    Einen Kommentar schreiben:


  • boxerfahrer
    antwortet
    Hallo thoern,

    ... freue mich über Deine Antwort. ich bin mit dem mistereib weiterhin zugange und nutze auch die 0.84 alpha Version - den Thread habe ich nicht vergessen :-)

    ... weil ich keine Ahnung von UserCode habe :-)
    Ich habe ein perl script, das alle 5 Minuten Daten aus meiner Wärmepumpe ausliest und auf den Bus schreiben soll. Das mache ich derzeit über einen crontab-Eintrag. Wie wird den mistereib UserCode abgearbeitet? Muss ich in einer Endlosschleife mit sleep arbeiten? Ich würde das schon gerne umstellen, weil ich auch noch weitere Datentypen aus der WP bekomme, für die ich noch keine EIS Kodierung habe. Die könnte mir mistereib wohl abnehmen.

    Viele Grüße
    - boxerfahrer

    Einen Kommentar schreiben:


  • thoern
    antwortet
    Zitat von boxerfahrer Beitrag anzeigen
    Ich möchte das Thema EIS5 und perl nochmal aufwärmen. Ich habe verschiedene Temperaturen im float Format, die nicht aus dem EIB kommen, die ich aber auf den Bus schicken will.

    Ich nutze mistereib und habe daher die EIB5 Klasse in perl zu Verfügung, aber ich komme damit mangels tiefer perl Kenntnisse nicht zurecht. Kann mir vielleicht jemand Hilfestellung leisten, wie ich die encode (und vielleicht auch decode) Methoden in meinem perl code (der als deamon ausserhalb von mistereib arbeitet) nutzen kann? Ich bin auch für jeden Hinweis dankbar, wie das ohne die EIB5 Klasse funktioniert.

    Vielen Dank!
    Gruss Boxerfahrer
    Hallo boxerfahrer,

    wieso lässt du nicht mistereib das externe Skript als Usercode ausführen?
    Du kriegst die Sachen dann wie folgt auf den Bus:

    $MeinEIB5Objekt->set($externerWert)

    auslesen kannst du wieder so:

    $wert = $MeinEIB5Objekt->state();

    Gruß,
    thoern

    Einen Kommentar schreiben:


  • makki
    antwortet
    Na denn..
    Genau diese sch*****, das dann noch \@{ / $_[0] oder %{$}{hurz}[0] davor muss, versuche ich in den WG-Plugins übrigens zu vermeiden, weil es eh keiner - mir inkl. - versteht
    Perl hat in dem Bereich IMHO nicht gerade seine Stärke, weil man 2 Bytes aus einer Funktion eben auch in einen String schreiben kann..
    Ist zwar einfach und in der universitären Megarelationalen-OO-Welt bestimmt auch alles ganz wertvoll, führt aber nicht unbedingt zu dem was man als normaldenkender so erwartet

    Makki

    Einen Kommentar schreiben:


  • boxerfahrer
    antwortet
    Makki, ich hab's, dank Deiner Hilfe. Nachdem ich im Aufruf ein Feld genutzt habe
    Code:
    @byte_result = encode_dpt9($log_value_dec);
    und die 2 Bytes jeweils mit sprintf in Hex Werte umgewandelt habe klappte es endlich.
    Herzlichen Dank für Deine Hilfe!

    - boxerfahrer

    Einen Kommentar schreiben:


  • makki
    antwortet
    Poste bitte mal den ganzen Code vom Aufruf bis zum schreiben auf den KNX.
    Programmieren kann ich auch nicht, weiss aber das Perl für aussenstehende wie mich teils ziemlich braindead erscheint

    (Jemand der das wirklich kapiert könnte das mit den Skalars usw jetzt auch erklären aber ich vermute wo der Fehler liegt: encode_dpt9 liefert zwei Byte zurück, Du packst das in eine "Variable" [ich nenne es mal laienhaft so, weil das ist einer der Punkte die ich bei Perl nie verstehen werden - ref,skalar,array,...])

    Makki

    Einen Kommentar schreiben:


  • boxerfahrer
    antwortet
    Hallo Makki,

    dekodieren funktioniert prima, mit dem encodieren von floats habe ich aber Probleme - vermutlich wegen meiner beschränkten Programmierkenntnisse.

    Ich nutze die encode_dpt9 Routine aus Deinem Link. Wenn ich mit einem formatierten Float die Funktion aufrufe:

    Code:
    $log_value_dec = sprintf "%2.1F", $temperature;
    $log_value_hex = encode_dpt9($log_value_dec);
    dann kommt bei einer Temperatur von 7.5° aus der Routine eine "238" zurück statt der erwarteten "02EE" (tapko tools).
    Ich kann mir jetzt mit meinen beschränkten perl Kenntnissen nur vorstellen, dass ich keine 2 byte beim Aufruf übergebe.

    Ich wäre für jede Hilfe dankbar
    - boxerfahrer

    Einen Kommentar schreiben:


  • boxerfahrer
    antwortet
    Makki, herzlichen Dank. Werde ich ausprobieren.

    Ich habe mir den Link angeschaut - eine decode Funktion für EIS5/dpt9 habe ich nicht gefunden. Hast Du da noch was in der Schatztruhe ?

    EDIT - sorry, gefunden, hatte Tomaten vor den Augen

    - boxerfahrer

    Einen Kommentar schreiben:

Lädt...
X