Ankündigung

Einklappen
Keine Ankündigung bisher.

- √ - Neues Plugin für Vbus Solarregler Resol

Einklappen
Dieses Thema ist geschlossen.
X
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    #61
    FEDBACK: Alle Test waren erfolglos. Auch debug 3 liefert keine zusätzlichen Outputs

    Kommentar


      #62
      Hallo Lio,

      bei mir gibt es auch mehr Geräte mit /dev/tty*, aber ich habe die Liste auf die wichtigen gekürzt. Das wollte ich mit dem "[...]" zwischen Befehl und Ausgabe ausdrücken.

      Interessant ist, daß "od" auf den Zähler mal funktioniert und dann wieder nicht.

      Kannst Du mal bitte Deine "Resol.conf" und das Log posten? Ich vermisse den Eintrag "Serielle Schnittstelle erfolgreich geöffnet: '%s'". Dieser muß bei $Debug=3 kommen.
      BTW: Du mußt $debug in der Resol.conf setzen. Der Wert im Plugin wird durch die Resol.conf überschrieben.

      Was hast Du für einen Solarregler? Du hast geschrieben, daß die Resol-Software die Daten liefert. Es kann sein, daß Dein Solarregler nur auf Anfrage die Daten liefert.
      Folgender Test:
      - nimm ein Terminal-Programm (ich benutze hterm: http://www.heise.de/download/hterm.html)
      - Paß die Werte oben an: Baud 9600 - Data 8 - Stop 1 - Parity 'none'
      - "Connect"
      Wenn Daten ankommen, redet der Soalrregler von allein.

      Wenn keine Daten kommen, aber die Resolsoftware was liefert, muß man die Daten wohl explizit anfordern...
      In dem Fall wird es kompliziert. Das einfachste wäre, wenn Du zwei COM-Ports per Null-Modemkabel verbindest. Den einen öffnet man mit dem Terminal und den anderen mit der Resol-Software. Im Terminal sieht man dann, was die Software sendet.
      Falls Du zwei Adapter hast, kannst Du auch gerade GND mit GND und jeweils TX mit RX verbinden.

      Nochmal das Plugin mit drei zusätzlichen Logzeilen:
      Code:
      return;
      #use strict;
      use Device::SerialPort;
      use Time::HiRes qw( usleep gettimeofday  tv_interval );
      my $crc;
      my $d;
      my $framecount;
      my $framecrc;
      my $i;
      my $packetsize;
      my $usedbytes;
      my $value;
      my $valuedata;
      my $valuedataf;
      my $valuedatastr;
      my $debug = 2;
      
      my $connectiontype;
      my $dfa;
      my $format;
      my $lang;
      my $serial;
      my $serialcount;
      my $serialdata;
      my $serialdev;
      my $solar;
      my $timeout;
      my %msgs;
      my @serialunpack;
      my @values;
      my $cycle;
      readConf();
      $plugin_info{$plugname.'_cycle'}  = $cycle;
      if($debug>=1){plugin_log("Oeffne SerialPort: $serialdev"))}  ;
      if ($connectiontype eq "serial"){
          $serial = Device::SerialPort->new($serialdev) || die "Can't open $serialdev ($!)\n";
          $serial->baudrate(9600);
          $serial->parity("none");
          $serial->databits(8);
          $serial->stopbits(1);
          $serial->handshake("none");
          $serial->write_settings;
          $serial->lookclear;
          if($debug>=1){plugin_log($plugname,sprintf($msgs{"log_serial_device_open_$lang"}, $serialdev))}  ;
      } else {
          die "Not supported connectiontype '$connectiontype'";
      }
      my @packet = ();        # will hold a complete received packet
      my @buffer = ();
      my $loop = 0;
      my $syncfound = 0;        # will be set to 1 if 0xAA is received
      my $t0 = [gettimeofday];# now
      my $res = 0;
      while ((tv_interval $t0, [gettimeofday]) < $timeout && $res == 0) {        # while timeout is not reached and no valid packet was analyzed
          ($serialcount, $serialdata) = $serial->read(255);
          if($serialcount > 0){
              @serialunpack = unpack "C*", $serialdata;                        # convert received chars to bytes
              if ($debug>2) {plugin_log($plugname,sprintf($msgs{"log_serial_data_$lang"}, sprintf((" %02X" x ($#serialunpack+1), @serialunpack))))};
              foreach (@serialunpack) {
                  if ($_ == 0xAA) {            # sync byte found
                      if ($syncfound == 0) {    # '0' means found first sync byte
                          @buffer = (0xAA);
                          $syncfound = 1;
                      } else {                # found a second sync byte -> we received a full packet
                          @packet = @buffer;    # @packet will be analyzed
                          if ($debug>2) {plugin_log($plugname,sprintf($msgs{"log_data_to_analyze_$lang"}, sprintf((" %02X" x ($#packet+1) ), @serialunpack)))};
                          $res = analyze_packet(); # result will be '0' if an error occurs and '1' if analysis was successful
                          @buffer = (0xAA);    # clear buffer and set first byte to the sync byte
                      }
                  } else {
                      if ($_ > 0x7F) {        # bytes greater than 0x7F (127) are not allowed (except for the sync byte 0xAA (170)
                          @buffer = ();        # clear buffer
                          $syncfound = 0;        # reset to skip all bytes until the next sync byte
                          if ($debug>2) {plugin_log($plugname,sprintf($msgs{"err_byte_gt_0x7f_$lang"}, $_))};
                      }
                      if ($syncfound == 1) {
                          push(@buffer, $_);    # add byte to buffer
                      }
                  }
              }
          }
          usleep 50000;                        # sleep for 50,000µs
          $loop++;                            # count iterations of the while-loop
      }
      
      my $t1 = [gettimeofday];                # now 2
      my $t0_t1 = tv_interval $t0, $t1;        # get timespan between start & end
      
      if($debug>=1){plugin_log("Time needed: $t0_t1"))};
      $serial->close();
      
      sub analyze_packet {
          my $source        = $packet[4] * 0x100 + $packet[3];        # source ID of this packet
          my $target        = $packet[2] * 0x100 + $packet[1];        # target ID of this packet
          my $protocol    = $packet[5];                            # protocol ID. Must be 0x10
          my $command        = $packet[7] * 0x100 + $packet[6];        # command. Must be 0x0100 = paket contains data for slave
          my $offset = 1;                                            # offset and length of header. Values directly used to check CRC of header
          my $length = 8;
          my @data;                                                # array for the data bytes as the data offset does not include septet and CRC
          if ($source   != $solar) {if ($debug >=2) {plugin_log($plugname, sprintf($msgs{"err_source_$lang"}, $source)) } ; return 0};
          if ($target   != $dfa  ) {if ($debug >=2) {plugin_log($plugname, sprintf($msgs{"err_target_$lang"}, $target)) } ; return 0};
          if ($protocol != 0x10  ) {if ($debug >=2) {plugin_log($plugname, sprintf($msgs{"err_protocol_$lang"}, $protocol)) } ; return 0};
          if ($command  != 0x0100) {if ($debug >=2) {plugin_log($plugname, sprintf($msgs{"err_command_$lang"}, $command)) } ; return 0};
          if ($debug >=1) {plugin_log($plugname, sprintf($msgs{"progress_crc_header_$lang"}))};
          $crc = vbus_crc($offset,$length);     # get CRC of header
          if ($crc != $packet[9]) {if ($debug >=2) {plugin_log($plugname, sprintf($msgs{"err_crc_header_$lang"}, $packet[9] , $crc)) } ; return 0};
          $framecount = $packet[8];        # number of data frames
          $packetsize = $#packet + 1;
          # every dataframe has six bytes
          if (($packetsize != (10 + $framecount * 6))) { if ($debug >=2) {plugin_log($plugname,sprintf($msgs{"err_packetsize_$lang"}, $packetsize, (10 + $framecount * 6) , $framecount))} ; return 0};
          # check crc of data frames
          if ($debug >=1) {plugin_log($plugname, sprintf($msgs{"progress_crc_frame_$lang"}))};
          $length = 5; # crc includes septet byte
          for ($i = 0; $i < $framecount; $i++) {
              $offset = 10 + $i * 6;
              $framecrc = $packet[10 + $i * 6 + 5];
              $crc = vbus_crc($offset,$length);
              if ($crc != $framecrc) {if ($debug >=2) {plugin_log($plugname, sprintf($msgs{"err_crc_frame_$lang"} , $i , $framecrc , $crc)) } ; return 0};
          }
          # Insert septets and add data bytes to @data
          if ($debug >=1) {plugin_log($plugname, sprintf($msgs{"progress_insert_septet_$lang"}))};
          $length = 4;
          for ($i = 0; $i < $framecount; $i++) {
              $offset = 10 + $i * 6;
              &vbus_injectSeptet($offset,$length);
              push(@data, @packet[$offset..($offset + $length -1)]);
          }
          if ($debug >= 2) {plugin_log($plugname, sprintf($msgs{"log_packetdata_$lang"} . (" %02X" x ($#data+1)), @data)) };
          if ($debug >=1) {plugin_log($plugname, sprintf($msgs{"progress_parse_data_$lang"}))};
          foreach $value (@values) {
              if ($debug >= 2) {plugin_log($plugname, sprintf($msgs{"log_valuename_$lang"}, $value->{"Name_$lang"}))};
              $usedbytes = int(($value->{bitsize} +7) / 8);
              $valuedatastr = "";
              $offset = $value->{Offset};
              foreach $d (@data[$offset..($offset+$usedbytes-1)]) {
                  $valuedatastr = sprintf("%02X", $d) . $valuedatastr;
              }
              if ($debug >= 2) {plugin_log($plugname, sprintf($msgs{"log_valuedatahex_$lang"}, $valuedatastr))};
              $valuedata = hex($valuedatastr) & ((2** $value->{bitsize})-1);
              if ($value->{signed} == 1) {
                  if ((hex($valuedatastr) & (2**($usedbytes*8-1))) > 0) {
                      $valuedata = -(2**($usedbytes*8) - hex($valuedatastr));
                  }
              }
              if ($debug >= 2) {plugin_log($plugname, sprintf($msgs{"log_valuedatadec_$lang"}, $valuedata))};
              if ($value->{Factor}) {
                      $valuedataf = $valuedata * $value->{Factor};
                      if ($debug >= 2) {plugin_log($plugname, sprintf($msgs{"log_valuedatadec_w_factor_$lang"}, $valuedata, $value->{Factor}, $valuedataf))};
                      $valuedata = $valuedataf;
              }
              if ($value->{bitsize} == 1) {
                  if ($valuedata > 0) {
                      $valuedata = 1;
                      print "bit 1\n";
                  } else {
                      $valuedata = 0;
                  }
              }
              if ($value->{GA} ne '') {
                  knx_write($value->{GA}, $valuedata , $value->{DPT});
              }
              if ($debug >= 1) {plugin_log($plugname, sprintf($msgs{"log_value_information_$lang"}, $value->{"Name_$lang"}, $valuedata, $value->{"Unit"})) ; print "-------\n"};
              
          }
          return 1;
      }
      
      ############### END #################
      sub vbus_crc {
          my ($offset, $length) = @_;
          my ($i);
          my ($crc) = 0x7f;
          for ($i = 0; $i < $length; $i++) {
              $crc = ($crc - $packet[$offset + $i]) & 0x7f;
          }
          return $crc
      }
      
      sub vbus_injectSeptet {
          my ($offset, $length) = @_;
          my ($i, $septet);
          $septet = $packet[$offset + $length];
          for ($i = 0; $i < $length; $i++) {
              if ($septet & (2 ** $i)) {
                  $packet[$offset + $i] |= 0x80;
              }
          }
      }
      
      
      sub readConf
      {
          my $confFile = '/etc/wiregate/plugin/generic/conf.d/'.basename($plugname,'.pl').'.conf';
          if (! -f $confFile)
          {
              plugin_log($plugname, " no conf file [$confFile] found!");
          }
          else
          {
              if($debug>=1){plugin_log($plugname, " reading conf file [$confFile].");}
              open(CONF, $confFile);
              my @lines = <CONF>;
              close($confFile);
              my $result = eval("@lines");
              ($result) and plugin_log($plugname, "conf file [$confFile] returned result[$result]");
              if ($@)
              {
                  if($debug>=1){plugin_log($plugname, " conf file [$confFile] returned:");}
                  my @parts = split(/\n/, $@);
                  if($debug>=2){plugin_log($plugname, " --> $_") foreach (@parts);}
              }
          }
      } # readConf
      Gruß, Carsten

      Kommentar


        #63
        Hallo,
        hier das Log:

        Code:
        2016-01-16 13:24:16.138,SolarResol II, reading conf file [/etc/wiregate/plugin/generic/conf.d/SolarResol II.conf].
        2016-01-16 13:24:16.163,SolarResol II,conf file [/etc/wiregate/plugin/generic/conf.d/SolarResol II.conf] returned result[20]
        2016-01-16 13:24:16.178,SolarResol II,Serielle Schnittstelle erfolgreich geöffnet: '/dev/usbserial-1-4.3'
        2016-01-16 13:24:19.202,SolarResol II,1,3.3s,
        Code:
        $debug = 3;
        $cycle = 60;
        $connectiontype = "serial";
        $serialdev = "/dev/usbserial-1-4.3";
        $timeout = 3;                                # maximum time in seconds to listen for a valid packet
        $solar = 0x4211;                            # ID of your own solar device
        $dfa   = 0x0010;                            # ID of "DFA". In german "Daten Fernanzeige". englisch ~ "remote data display"
                                                    # solar device broadcasts his state to this address
        $lang = "de";
        %msgs = (
            # english / englisch
                err_source_en                => "ERROR: Wrong source ID: 0x%04X",
                err_target_en                => "ERROR: Wrong target ID: 0x%04X",
                err_protocol_en              => "ERROR: Wrong protocol version: 0x%02X",
                err_command_en               => "ERROR: Wrong command 0x%04X",
                err_crc_header_en            => "ERROR: CRC of header is wrong. In packet: 0x%02X. Calculated: 0x%02X",
                err_packetsize_en            => "ERROR: Packetsize (%d) != calculated size (%d). Framecount = %d",
                err_crc_frame_en             => "ERROR: CRC of frame %d is wrong. In frame: 0x%02X. Calculated: 0x%02X",
                err_byte_gt_0x7f_en          => "ERROR: Byte greater than 0x7F received: 0x%02X",
                log_packetdata_en            => "Data bytes:",
                log_valuename_en             => "Value name: %s",
                log_valuedatahex_en          => "Value data hex: %s",
                log_valuedatadec_en          => "Value data dec: %d",
                log_valuedatadec_w_factor_en => "Value has factor: %d * %.2f = %.2f",
                log_value_information_en     => "Decoded data: %s: %.2f %s",
                log_serial_data_en           => "Received serial data: %s",
                log_packet_found_en          => "Packet found: %s",
                log_serial_device_open_en    => "Serial device successful openend: '%s'",
                progress_crc_header_en       => "Calc CRC header...",
                progress_crc_frame_en        => "Calc CRC frame...",
                progress_insert_septet_en    => "Insert septet...",
                progress_parse_data_en       => "Parse data...",
            # german / deutsch    
                err_source_de                => "ERROR: Falsche Quellen-ID: 0x%04X",
                err_target_de                => "ERROR: Falsche Ziel-ID: 0x%04X",
                err_protocol_de              => "ERROR: Falsche Protokollversion: 0x%02X",
                err_command_de               => "ERROR: Falsches Kommando 0x%04X",
                err_crc_header_de            => "ERROR: Pruefsumme des Headers falsch. Im Paket: 0x%02X. Berechnet: 0x%02X",
                err_packetsize_de            => "ERROR: Paketgroesse (%d) enstpricht nicht der berechneten (%d). Frameanzahl = %d",
                err_crc_frame_de             => "ERROR: Pruefsumme von Frame %d ist falsch. Im Frame: 0x%02X. Berechnet: 0x%02X",
                err_byte_gt_0x7f_de          => "ERROR: Byte groesser als 0x7F empfangen: 0x%02X",
                log_packetdata_de            => "Daten Bytes:",
                log_valuename_de             => "Wertname: %s",
                log_valuedatahex_de          => "Wert hex: %s",
                log_valuedatadec_de          => "Wert dec: %d",
                log_valuedatadec_w_factor_de => "Wert hat einen Faktor: %d * %.2f = %.2f",
                log_value_information_de     => "Decodierte Daten: %s: %.2f %s",
                log_serial_data_de           => "Empfangene serielle Daten: %s",
                log_packet_found_de          => "Packet gefunden: %s",
                log_serial_device_open_de    => "Serielle Schnittstelle erfolgreich geöffnet: '%s'",
                progress_crc_header_de       => "Berechne Pruefsumme Header...",
                progress_crc_frame_de        => "Berechne Pruefsumme Frame...",
                progress_insert_septet_de    => "Fuege Septett hinzu...",
                progress_parse_data_de       => "Parse Daten...",
        );                                        
        @values = (
                { Name_en=>'Temperature sensor 1'    , Name_de=>'Temperatur Sensor 1'     , Offset=> 0, bitsize=>15, bitpos=>undef, Factor=>0.1  , signed=>1, Unit=>'°C', RRD_Name=>'Solar_Temperatur_Sensor_1'     , GA=>'9/5/0' , DPT=>'9.001' },
                { Name_en=>'Temperature sensor 2'    , Name_de=>'Temperatur Sensor 2'     , Offset=> 2, bitsize=>15, bitpos=>undef, Factor=>0.1  , signed=>1, Unit=>'°C', RRD_Name=>'Solar_Temperatur_Sensor_2'     , GA=>'9/5/1' , DPT=>'9.001' },
                { Name_en=>'Temperature sensor 3'    , Name_de=>'Temperatur Sensor 3'     , Offset=> 4, bitsize=>15, bitpos=>undef, Factor=>0.1  , signed=>1, Unit=>'°C', RRD_Name=>''                              , GA=>''      , DPT=>'' },
                { Name_en=>'Temperature sensor 4'    , Name_de=>'Temperatur Sensor 4'     , Offset=> 6, bitsize=>15, bitpos=>undef, Factor=>0.1  , signed=>1, Unit=>'°C', RRD_Name=>''                              , GA=>''      , DPT=>'' },
                { Name_en=>'Pump speed 1'            , Name_de=>'Drehzahl Relais 1'       , Offset=> 8, bitsize=> 8, bitpos=>undef, Factor=>1    , signed=>0, Unit=>'%' , RRD_Name=>'Solar_Drehzahl_Relais_1'       , GA=>'9/5/4' , DPT=>'5'     },
                { Name_en=>'Pump speed 2'            , Name_de=>'Drehzahl Relais 2'       , Offset=>12, bitsize=> 8, bitpos=>undef, Factor=>1    , signed=>0, Unit=>'%' , RRD_Name=>''                              , GA=>''      , DPT=>''     },
                { Name_en=>'Operating hours relais 1', Name_de=>'Betriebsstunden Relais 1', Offset=>10, bitsize=>16, bitpos=>undef, Factor=>1    , signed=>0, Unit=>'h' , RRD_Name=>'Solar_Betriebsstunden_Relais_1', GA=>'9/5/6' , DPT=>'7.001' },
                { Name_en=>'Operating hours relais 2', Name_de=>'Betriebsstunden Relais 2', Offset=>14, bitsize=>16, bitpos=>undef, Factor=>1    , signed=>0, Unit=>'h' , RRD_Name=>''                              , GA=>''      , DPT=>''      },
                { Name_en=>'UnitType'                , Name_de=>'UnitType'                , Offset=>16, bitsize=> 8, bitpos=>undef, Factor=>undef, signed=>0, Unit=>''  , RRD_Name=>''                              , GA=>''      , DPT=>''      },
                { Name_en=>'System'                  , Name_de=>'System'                  , Offset=>17, bitsize=> 8, bitpos=>undef, Factor=>undef, signed=>0, Unit=>''  , RRD_Name=>''                              , GA=>''      , DPT=>''      },
                { Name_en=>'ErrorMask'               , Name_de=>'ErrorMask'               , Offset=>20, bitsize=>16, bitpos=>undef, Factor=>undef, signed=>0, Unit=>''  , RRD_Name=>''                              , GA=>''      , DPT=>''      },
                { Name_en=>'Systemzeit'              , Name_de=>'Systemzeit'              , Offset=>22, bitsize=>15, bitpos=>undef, Factor=>undef, signed=>0, Unit=>''  , RRD_Name=>''                              , GA=>''      , DPT=>''      },
                { Name_en=>'Sensor 1 failure'        , Name_de=>'Sensor 1 defekt'         , Offset=>20, bitsize=> 1, bitpos=>0    , Factor=>undef, signed=>0, Unit=>''  , RRD_Name=>'Solar_Sensor_1_defekt'         , GA=>'9/5/12', DPT=>'1.001' },
                { Name_en=>'Sensor 2 failure'        , Name_de=>'Sensor 2 defekt'         , Offset=>20, bitsize=> 1, bitpos=>1    , Factor=>undef, signed=>0, Unit=>''  , RRD_Name=>'Solar_Sensor_2_defekt'         , GA=>'9/5/13', DPT=>'1.001' },
                { Name_en=>'Sensor 3 failure'        , Name_de=>'Sensor 3 defekt'         , Offset=>20, bitsize=> 1, bitpos=>2    , Factor=>undef, signed=>0, Unit=>''  , RRD_Name=>'Solar_Sensor_3_defekt'         , GA=>'9/5/14', DPT=>'1.001' },
                { Name_en=>'Sensor 4 failure'        , Name_de=>'Sensor 4 defekt'         , Offset=>20, bitsize=> 1, bitpos=>3    , Factor=>undef, signed=>0, Unit=>''  , RRD_Name=>'Solar_Sensor_4_defekt'         , GA=>'9/5/15', DPT=>'1.001' },
                { Name_en=>'Statusmask'              , Name_de=>'Statusmask'              , Offset=>24, bitsize=>32, bitpos=>undef, Factor=>undef, signed=>0, Unit=>''  , RRD_Name=>''                              , GA=>''      , DPT=>''      },
                { Name_en=>'Heat amount'             , Name_de=>'Wärmemenge'              , Offset=>28, bitsize=>32, bitpos=>undef, Factor=>1    , signed=>0, Unit=>'Wh', RRD_Name=>'Solar_Waermemenge'             , GA=>'9/5/17', DPT=>'12.001'},
                { Name_en=>'SV Version'              , Name_de=>'SV Version'              , Offset=>32, bitsize=>16, bitpos=>undef, Factor=>0.01 , signed=>0, Unit=>''  , RRD_Name=>''                              , GA=>''      , DPT=>''      },
                { Name_en=>'Variante'                , Name_de=>'Variante'                , Offset=>34, bitsize=>16, bitpos=>undef, Factor=>undef, signed=>0, Unit=>''  , RRD_Name=>''                              , GA=>''      , DPT=>''      },
        );
        ########## conf #############

        Nach dem ich Deinen neuen CODE eingeben habe, hier das log:

        Code:
        2016-01-16 13:30:41.696,SolarResol,Warning: "my" variable $debug masks earlier declaration in same scope at (eval 81440) line 33.
        
        2016-01-16 13:30:41.711,SolarResol,Warning: Subroutine analyze_packet redefined at (eval 81440) line 92.
        
        2016-01-16 13:30:41.717,SolarResol,Warning: Subroutine vbus_crc redefined at (eval 81440) line 169.
        
        2016-01-16 13:30:41.718,SolarResol,Warning: Subroutine vbus_injectSeptet redefined at (eval 81440) line 179.
        
        2016-01-16 13:30:41.721,SolarResol,Warning: Subroutine readConf redefined at (eval 81440) line 195.
        
        2016-01-16 13:31:01.596,Zeitsteuerung Astro,Warning: Subroutine getWeekNumber redefined at (eval 81442) line 168.
        
        2016-01-16 13:31:01.597,Zeitsteuerung Astro,Warning: Subroutine checkWeekNumber redefined at (eval 81442) line 210.
        
        2016-01-16 13:31:15.057,SolarResol II,Warning: Subroutine analyze_packet redefined at (eval 81468) line 92.
        
        2016-01-16 13:31:15.061,SolarResol II,Warning: Subroutine vbus_crc redefined at (eval 81468) line 169.
        
        2016-01-16 13:31:15.064,SolarResol II,Warning: Subroutine vbus_injectSeptet redefined at (eval 81468) line 179.
        
        2016-01-16 13:31:15.068,SolarResol II,Warning: Subroutine readConf redefined at (eval 81468) line 192.
        
        2016-01-16 13:31:15.074,SolarResol II,Not enough arguments for main::plugin_log at (eval 81468) line 34, near ""Oeffne SerialPort: $serialdev")"
        syntax error at (eval 81468) line 34, near "))"
        Not enough arguments for main::plugin_log at (eval 81468) line 89, near ""Time needed: $t0_t1")"
        syntax error at (eval 81468) line 89, near "))"
        ,0s,Not enough arguments for main::plugin_log at (eval 81468) line 34, near ""Oeffne SerialPort: $serialdev")"
        syntax error at (eval 81468) line 34, near "))"
        Not enough arguments for main::plugin_log at (eval 81468) line 89, near ""Time needed: $t0_t1")"
        syntax error at (eval 81468) line 89, near "))"

        Über hterm hatte ich gaanz früher ohne Erfolg getestet und nur mit der RESOL SW eine erfolgreiche Verbindung. Probiere das aber auch noch mal mit Deinen Paramtern aus.

        Danke und GRuß,
        Lio

        Kommentar


          #64
          Hallo Lio,

          aus Deinem ersten Log-Auszug kann man ersehen, daß zumindesst die richtige Schnittstelle verwendet wird und geöffnet werden konnte. Die "3.3s" am Ende beudeten, daß der TimeOut von 3sec abgelaufen ist, ohne das Daten empfangen wurden.

          Du hast im September 2013 geschrieben, daß das Plugin lange funktionierte. Wenn es jetzt nicht mehr geht, liegt es irgendwo an der Schnittstelle.
          Wenn die Resol-Software Daten liefert, muß die Schnittstelle in Ordnung sein (VBUS-Adapter und TTL-RS232-Wandler). Daher gehe ich davon aus, daß auch Hterm was liefert, wenn Du die richtigen Parameter benutzt. Dann kann es nur noch am WG liegen.

          /dev/usbserial-1-4.3 deutet darauf hin, daß Du einen USB-Hub einsetzt. Hast Du es mal direkt am WG probiert? Natürlich wieder mit "dmesg" gucken, mit welchem Namen das Gerät erkannt wurde und entsprechend od -x starten, bzw in der Config eintragen.

          Gruß, Carsten

          Kommentar


            #65
            Hallo,

            hatte erst eben etwas zeit gefunden...
            Nun also:
            Ohne den USB-Hub wurde der Wandler als /dev/usbserial-2-4 erkannt. Das Config hatte ich entsprechend angepasst, jedoch verändert sich im log nichts.
            Ebenso gibt es auf od -x /dev/usbserial-2-4 keine Reaktion

            Mit hterm hatte ich diesmal Erfolg ABER ERST NACHDEM ich die DTR-Taste gedrückt hatte.
            Hat das was zu bedeuten?

            Northman, da hast Du richtg zurückgelesen:
            Deine erste Veröffentlichung hat auf Anhieb am 15.1.2013 funktioniert und ist bis 9.9.2013 durchgelaufen.

            Patrick (alias swiss) meinte:
            Du sagst, du hst das WG geupdatet? Ist dein VBus Plugin nicht vorkompiliert und braucht ein gepatchter wiregated? Könnte es sein, dass der Patch mit dem Update eventuell überbügelt wurde?

            Danke nochmals fr Deine Hilfe,
            Lio

            Kommentar


              #66
              Zitat von lio123 Beitrag anzeigen
              Mit hterm hatte ich diesmal Erfolg ABER ERST NACHDEM ich die DTR-Taste gedrückt hatte.
              Hat das was zu bedeuten?
              Das ist doch mal ein Hinweis. Ich habe ein "$serial->dtr_active(1);" in das Skript eingefügt (keine Ahnung, ob das was bringt).
              Das Skript mit korrigierten Loggingteilen:
              PHP-Code:
              use Device::SerialPort;
              use 
              Time::HiRes qwusleep gettimeofday  tv_interval );
              my $crc;
              my $d;
              my $framecount;
              my $framecrc;
              my $i;
              my $packetsize;
              my $usedbytes;
              my $value;
              my $valuedata;
              my $valuedataf;
              my $valuedatastr;
              my $debug 2;

              my $connectiontype;
              my $dfa;
              my $format;
              my $lang;
              my $serial;
              my $serialcount;
              my $serialdata;
              my $serialdev;
              my $solar;
              my $timeout;
              my %msgs;
              my @serialunpack;
              my @values;
              my $cycle;
              readConf();
              $plugin_info{$plugname.'_cycle'}  = $cycle;
              if(
              $debug>=1){plugin_log($plugname,"Oeffne SerialPort: $serialdev")}  ;
              if (
              $connectiontype eq "serial"){
                  
              $serial Device::SerialPort->new($serialdev) || die "Can't open $serialdev ($!)\n";
                  
              $serial->baudrate(9600);
                  
              $serial->parity("none");
                  
              $serial->databits(8);
                  
              $serial->stopbits(1);
                  
              $serial->handshake("none");
                  
              $serial->dtr_active(1);
                  
              $serial->write_settings;
                  
              $serial->lookclear;
                  if(
              $debug>=1){plugin_log($plugname,sprintf($msgs{"log_serial_device_open_$lang"}, $serialdev))}  ;
              } else {
                  die 
              "Not supported connectiontype '$connectiontype'";
              }
              my @packet = ();        # will hold a complete received packet
              my @buffer = ();
              my $loop 0;
              my $syncfound 0;        # will be set to 1 if 0xAA is received
              my $t0 = [gettimeofday];# now
              my $res 0;
              while ((
              tv_interval $t0, [gettimeofday]) < $timeout && $res == 0) {        # while timeout is not reached and no valid packet was analyzed
                  
              ($serialcount$serialdata) = $serial->read(255);
                  if(
              $serialcount 0){
                      @
              serialunpack unpack "C*"$serialdata;                        # convert received chars to bytes
                      
              if ($debug>2) {plugin_log($plugname,sprintf($msgs{"log_serial_data_$lang"}, sprintf((" %02X" ($#serialunpack+1), @serialunpack))))};
                      
              foreach (@serialunpack) {
                          if (
              $_ == 0xAA) {            # sync byte found
                              
              if ($syncfound == 0) {    # '0' means found first sync byte
                                  
              @buffer = (0xAA);
                                  
              $syncfound 1;
                              } else {                
              # found a second sync byte -> we received a full packet
                                  
              @packet = @buffer;    # @packet will be analyzed
                                  
              if ($debug>2) {plugin_log($plugname,sprintf($msgs{"log_data_to_analyze_$lang"}, sprintf((" %02X" ($#packet+1) ), @serialunpack)))};
                                  
              $res analyze_packet(); # result will be '0' if an error occurs and '1' if analysis was successful
                                  
              @buffer = (0xAA);    # clear buffer and set first byte to the sync byte
                              
              }
                          } else {
                              if (
              $_ 0x7F) {        # bytes greater than 0x7F (127) are not allowed (except for the sync byte 0xAA (170)
                                  
              @buffer = ();        # clear buffer
                                  
              $syncfound 0;        # reset to skip all bytes until the next sync byte
                                  
              if ($debug>2) {plugin_log($plugname,sprintf($msgs{"err_byte_gt_0x7f_$lang"}, $_))};
                              }
                              if (
              $syncfound == 1) {
                                  
              push(@buffer$_);    # add byte to buffer
                              
              }
                          }
                      }
                  }
                  
              usleep 50000;                        # sleep for 50,000µs
                  
              $loop++;                            # count iterations of the while-loop
              }

              my $t1 = [gettimeofday];                # now 2
              my $t0_t1 tv_interval $t0$t1;        # get timespan between start & end

              if($debug>=1){plugin_log($plugname,"Time needed: $t0_t1")};
              $serial->close();

              sub analyze_packet {
                  
              my $source        $packet[4] * 0x100 $packet[3];        # source ID of this packet
                  
              my $target        $packet[2] * 0x100 $packet[1];        # target ID of this packet
                  
              my $protocol    $packet[5];                            # protocol ID. Must be 0x10
                  
              my $command        $packet[7] * 0x100 $packet[6];        # command. Must be 0x0100 = paket contains data for slave
                  
              my $offset 1;                                            # offset and length of header. Values directly used to check CRC of header
                  
              my $length 8;
                  
              my @data;                                                # array for the data bytes as the data offset does not include septet and CRC
                  
              if ($source   != $solar) {if ($debug >=2) {plugin_log($plugnamesprintf($msgs{"err_source_$lang"}, $source)) } ; return 0};
                  if (
              $target   != $dfa  ) {if ($debug >=2) {plugin_log($plugnamesprintf($msgs{"err_target_$lang"}, $target)) } ; return 0};
                  if (
              $protocol != 0x10  ) {if ($debug >=2) {plugin_log($plugnamesprintf($msgs{"err_protocol_$lang"}, $protocol)) } ; return 0};
                  if (
              $command  != 0x0100) {if ($debug >=2) {plugin_log($plugnamesprintf($msgs{"err_command_$lang"}, $command)) } ; return 0};
                  if (
              $debug >=1) {plugin_log($plugnamesprintf($msgs{"progress_crc_header_$lang"}))};
                  
              $crc vbus_crc($offset,$length);     # get CRC of header
                  
              if ($crc != $packet[9]) {if ($debug >=2) {plugin_log($plugnamesprintf($msgs{"err_crc_header_$lang"}, $packet[9] , $crc)) } ; return 0};
                  
              $framecount $packet[8];        # number of data frames
                  
              $packetsize = $#packet + 1;
                  # every dataframe has six bytes
                  
              if (($packetsize != (10 $framecount 6))) { if ($debug >=2) {plugin_log($plugname,sprintf($msgs{"err_packetsize_$lang"}, $packetsize, (10 $framecount 6) , $framecount))} ; return 0};
                  
              # check crc of data frames
                  
              if ($debug >=1) {plugin_log($plugnamesprintf($msgs{"progress_crc_frame_$lang"}))};
                  
              $length 5# crc includes septet byte
                  
              for ($i 0$i $framecount$i++) {
                      
              $offset 10 $i 6;
                      
              $framecrc $packet[10 $i 5];
                      
              $crc vbus_crc($offset,$length);
                      if (
              $crc != $framecrc) {if ($debug >=2) {plugin_log($plugnamesprintf($msgs{"err_crc_frame_$lang"} , $i $framecrc $crc)) } ; return 0};
                  }
                  
              # Insert septets and add data bytes to @data
                  
              if ($debug >=1) {plugin_log($plugnamesprintf($msgs{"progress_insert_septet_$lang"}))};
                  
              $length 4;
                  for (
              $i 0$i $framecount$i++) {
                      
              $offset 10 $i 6;
                      &
              vbus_injectSeptet($offset,$length);
                      
              push(@data, @packet[$offset..($offset $length -1)]);
                  }
                  if (
              $debug >= 2) {plugin_log($plugnamesprintf($msgs{"log_packetdata_$lang"} . (" %02X" ($#data+1)), @data)) };
                  
              if ($debug >=1) {plugin_log($plugnamesprintf($msgs{"progress_parse_data_$lang"}))};
                  foreach 
              $value (@values) {
                      if (
              $debug >= 2) {plugin_log($plugnamesprintf($msgs{"log_valuename_$lang"}, $value->{"Name_$lang"}))};
                      
              $usedbytes int(($value->{bitsize} +7) / 8);
                      
              $valuedatastr "";
                      
              $offset $value->{Offset};
                      foreach 
              $d (@data[$offset..($offset+$usedbytes-1)]) {
                          
              $valuedatastr sprintf("%02X"$d) . $valuedatastr;
                      }
                      if (
              $debug >= 2) {plugin_log($plugnamesprintf($msgs{"log_valuedatahex_$lang"}, $valuedatastr))};
                      
              $valuedata hex($valuedatastr) & ((2** $value->{bitsize})-1);
                      if (
              $value->{signed} == 1) {
                          if ((
              hex($valuedatastr) & (2**($usedbytes*8-1))) > 0) {
                              
              $valuedata = -(2**($usedbytes*8) - hex($valuedatastr));
                          }
                      }
                      if (
              $debug >= 2) {plugin_log($plugnamesprintf($msgs{"log_valuedatadec_$lang"}, $valuedata))};
                      if (
              $value->{Factor}) {
                              
              $valuedataf $valuedata $value->{Factor};
                              if (
              $debug >= 2) {plugin_log($plugnamesprintf($msgs{"log_valuedatadec_w_factor_$lang"}, $valuedata$value->{Factor}, $valuedataf))};
                              
              $valuedata $valuedataf;
                      }
                      if (
              $value->{bitsize} == 1) {
                          if (
              $valuedata 0) {
                              
              $valuedata 1;
                              print 
              "bit 1\n";
                          } else {
                              
              $valuedata 0;
                          }
                      }
                      if (
              $value->{GAne '') {
                          
              knx_write($value->{GA}, $valuedata $value->{DPT});
                      }
                      if (
              $debug >= 1) {plugin_log($plugnamesprintf($msgs{"log_value_information_$lang"}, $value->{"Name_$lang"}, $valuedata$value->{"Unit"})) ; print "-------\n"};
                      
                  }
                  return 
              1;
              }

              ############### END #################
              sub vbus_crc {
                  
              my ($offset$length) = @_;
                  
              my ($i);
                  
              my ($crc) = 0x7f;
                  for (
              $i 0$i $length$i++) {
                      
              $crc = ($crc $packet[$offset $i]) & 0x7f;
                  }
                  return 
              $crc
              }

              sub vbus_injectSeptet {
                  
              my ($offset$length) = @_;
                  
              my ($i$septet);
                  
              $septet $packet[$offset $length];
                  for (
              $i 0$i $length$i++) {
                      if (
              $septet & (** $i)) {
                          
              $packet[$offset $i] |= 0x80;
                      }
                  }
              }


              sub readConf
              {
                  
              my $confFile '/etc/wiregate/plugin/generic/conf.d/'.basename($plugname,'.pl').'.conf';
                  if (! -
              f $confFile)
                  {
                      
              plugin_log($plugname" no conf file [$confFile] found!");
                  }
                  else
                  {
                      if(
              $debug>=1){plugin_log($plugname" reading conf file [$confFile].");}
                      
              open(CONF$confFile);
                      
              my @lines = <CONF>;
                      
              close($confFile);
                      
              my $result = eval("@lines");
                      (
              $result) and plugin_log($plugname"conf file [$confFile] returned result[$result]");
                      if ($@)
                      {
                          if(
              $debug>=1){plugin_log($plugname" conf file [$confFile] returned:");}
                          
              my @parts split(/\n/, $@);
                          if(
              $debug>=2){plugin_log($plugname" --> $_") foreach (@parts);}
                      }
                  }
              # readConf 
              PS: Das Skript ist nicht kompilierbar. Ich erinne mich nicht mehr an den genauen Grund, aber AFAIR hatte es was mit den Funktionen zu tun.
              Gruß, Carsten

              Kommentar


                #67
                Hallo!

                Neuer Code eingegeben.

                Vier mal hintereinander hatte ich nun: "Empfangene serielle Daten: 00"
                Code:
                2016-01-19 22:08:39.048,SolarResol II, reading conf file [/etc/wiregate/plugin/generic/conf.d/SolarResol II.conf].
                2016-01-19 22:08:39.105,SolarResol II,conf file [/etc/wiregate/plugin/generic/conf.d/SolarResol II.conf] returned result[20]
                2016-01-19 22:08:39.105,SolarResol II,Oeffne SerialPort: /dev/usbserial-1-4.3
                2016-01-19 22:08:39.164,SolarResol II,Serielle Schnittstelle erfolgreich geöffnet: '/dev/usbserial-1-4.3'
                [B]2016-01-19 22:08:39.669,SolarResol II,Empfangene serielle Daten:  00[/B]
                2016-01-19 22:08:42.191,SolarResol II,Time needed: 3.026426
                2016-01-19 22:08:42.195,SolarResol II,1,3.3s,

                kurze Zeit später aber nur noch ohne:
                Code:
                2016-01-19 22:13:57.544,SolarResol II, reading conf file [/etc/wiregate/plugin/generic/conf.d/SolarResol II.conf].
                2016-01-19 22:13:57.562,SolarResol II,conf file [/etc/wiregate/plugin/generic/conf.d/SolarResol II.conf] returned result[20]
                2016-01-19 22:13:57.575,SolarResol II,Oeffne SerialPort: /dev/usbserial-1-4.3
                2016-01-19 22:13:57.599,SolarResol II,Serielle Schnittstelle erfolgreich geöffnet: '/dev/usbserial-1-4.3'
                2016-01-19 22:14:00.623,SolarResol II,Time needed: 3.02391
                2016-01-19 22:14:00.628,SolarResol II,1,3s,
                Mit dem od Befehl kommt nur auf einem Seriellwandler ein log.
                Müssen die Plugins angehalten werden um via od ein log zu bekommen?

                Grüße,
                Lio

                Kommentar


                  #68
                  Hallo Lio,

                  wenn der Seriellwandler mit HTerm funktioniert, aber nicht am Wiregate, dann habe ich im Moment auch keine echten Ideen mehr.

                  Bei mir funktioniert od parallel zu einem Plugin (ebenso wie cat).

                  Ich wundere mich über Deine Aussage, daß es bei HTerm erst funktioniert hat, als Du DTR gedrückt hattest. Eigentlich ist das für die direkte Verbindung zwischen einem Computer und einem anderen Gerät via RS232:
                  Aus der Wikipedia:
                  Mit einem High-Pegel an diesem Ausgang signalisiert DTE seine Betriebsbereitschaft an die Gegenstelle. Damit kann die Gegenstelle, z. B. ein Modem, aktiviert oder auch zurückgesetzt werden. Üblicherweise antwortet die Gegenstelle mit einem High-Pegel auf DSR
                  Das sollte zum Betrieb des Seriellwandlers am PC nicht nötig sein. Mein Adapter hat gar keine DTR-Leitung (was verständlich ist, da er für TTL und nicht RS232 ist).
                  Vielleicht benötigt der Wandler trotzdem den High-Pegel?

                  Ändere das Skript bitte nochmal (die Zeile mit dtr_active hinter lookclear verschieben):
                  Neu:
                  PHP-Code:
                      $serial->write_settings;
                      
                  $serial->lookclear;
                      
                  $serial->dtr_active(1); 
                  Und noch ein bisschen im Nebel stochern:
                  "stty -F /dev/usbserial-1-4.3 -a" -> Was steht bei "speed"?
                  Wenn es was anderes als 9600 ist, setzt es mit "stty -F /dev/usbserial-1-4.3 9600".

                  "setserial -v /dev/usbserial-1-4.3"?


                  Gruß, Carsten

                  Kommentar


                    #69
                    Hallo Carsten,

                    danke für die Info. Werde das heute abend ausprobieren.
                    Ich habe ja auch auf dem Rasp.py smarthome.py laufen. Wäre es möglich das Plugin von dort zu starten?

                    GRüße Lio

                    Kommentar


                      #70
                      Hallo Lio,

                      Ich habe mich noch nie mit smarthome.py beschäftigt. Ich weiß nur, daß es auf Python basiert. Keine Ahnung, ob man dort Perl-Skripte starten kann. Auf jeden Fall müßtest Du es anpassen, da Wiregate-Funktionen zum Senden der Werte auf den Bus genutzt werden.

                      Gruß, Carsten
                      Gruß, Carsten

                      Kommentar


                        #71
                        Code:
                        > stty -F /dev/usbserial-1-4.3 -a
                        speed 9600 baud; rows 0; columns 0; line = 0;
                        intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
                        eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
                        werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
                        -parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
                        -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
                        -iuclc -ixany -imaxbel -iutf8
                        opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
                        isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
                        echoctl echoke

                        Code:
                        > setserial -v /dev/usbserial-1-4.3
                        /dev/usbserial-1-4.3, UART: unknown, Port: 0x0000, IRQ: 0, Flags: low_latency
                        > setserial -v /dev/usbserial-1-4.3
                        /dev/usbserial-1-4.3, UART: unknown, Port: 0x0000, IRQ: 0, Flags: low_latency
                        > setserial -v /dev/usbserial-FTAJO8TG
                        /dev/usbserial-FTAJO8TG, UART: unknown, Port: 0x0000, IRQ: 0, Flags: low_latency
                        > setserial -v /dev/usbserial-1-4.1
                        /dev/usbserial-1-4.1, UART: unknown, Port: 0x0000, IRQ: 0, Flags: low_latency
                        > setserial -v /dev/usbserial-1-4.2
                        /dev/usbserial-1-4.2, UART: unknown, Port: 0x0000, IRQ: 0, Flags: low_latency

                        Kommentar


                          #72
                          Hallo Carsten,

                          tut mir leid, dass ich mich erst jetzt melde. Ich war offline mit dem Wiregate Support am Suchen-jedoch erfolglos.
                          Trotzdem denke ich dass es am WG liegt, scheue mich aber es komplett neu aufzusetzen.

                          Du hattest geschrieben:
                          Code:
                          Zur Sicherheit nochmal meine Version des Plugins, welche bei mir bis zum Schluß lief. (Inzwischen habe ich einen Arduino Nano, der die Daten empfängt, decodiert und auf Anfrage den letzten Datensatz schickt. Damit läuft das neue Plugin nur noch knapp 90msec. Das Projekt werde ich bei Gelegenheit mal hier veröffentlichen):
                          Wäre toll wenn Du da ein paar Infos liefern könntest-Evtl ist diese Lösung plattformunabhängiger und könnte ggf auch mit dem Arduino Stack arbeiten.

                          Danke und Grüße,
                          Lio

                          Kommentar


                            #73
                            Guten Morgen,

                            Zitat von lio123 Beitrag anzeigen
                            Trotzdem denke ich dass es am WG liegt, scheue mich aber es komplett neu aufzusetzen.
                            Vorschlag: Du kaufst eine Garantie-Plus, damit ist das Neu-Aufsetzen (beliebig) oft enthalten und Du bekommst beim Upgrade auf ein WireGate "New Generation", also zum Beispiel auf ein Modell der Serie 2xxx, auch noch eine garantierte Inzahlungnahme für das alte WG.

                            Bei der Serie 2xxx wird Docker enthalten sein, so dass Du Plugins auch isoliert von einander laufen lassen kannst.

                            Wenn Du es nicht weiter sagst: In in so einem Docker Container würde auch ein Smarthome.py laufen oder andere Plattformen, so dass Du leicht die für Dich passende Lösung entwickeln kannst.

                            Mal abgesehen davon, dass wir bei ausreichendem Interesse auch gerne die Software für die Unterstützung des Solarreglers entwickeln und in unser Portfolio übernehmen (ab Mitte 2017).

                            lg

                            Stefan

                            Kommentar


                              #74
                              Hallo Stefan,
                              danke für das (die) Angebot(e). Dachte, dass ein Werksreset jederzeit out-of-the-box möglich ist?!?

                              Wenn der Resol hardwareseitig schon seine Daten als KNX, oder sonst was senden würde, könnte man sich bei den Geräten WG, Smarthome,..., auf die Logik beschränken und somit die Gesamtstabilität erhalten-zumindest aus meiner Sicht, mit eingeschränkten Linux, Perl,etc Kenntnissen.


                              Grüße,
                              Lio


                              Kommentar


                                #75
                                Hallo Lio,

                                Zitat von lio123 Beitrag anzeigen
                                Wäre toll wenn Du da ein paar Infos liefern könntest-Evtl ist diese Lösung plattformunabhängiger und könnte ggf auch mit dem Arduino Stack arbeiten.
                                Ich hoffe die Infos reichen Dir ;-) Neu: Vbus Solarregler Resol -> Arduino -> Klartext über USB-Seriell (inkl. WG Plugin)

                                Gruß, Carsten
                                Gruß, Carsten

                                Kommentar

                                Lädt...
                                X