Ankündigung

Einklappen
Keine Ankündigung bisher.

- √ - Frage an die Programmier Profis

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

    - √ - Frage an die Programmier Profis

    hallo,

    mein Problem ist folgendes ich verwende für meine Haussteuerung LinuxMCE und möchte stündlich die Zeit auf den BUS schicken. Ich kann zwar alles mögliche senden aber das Format stimmt nicht, denn die Zeit die mir der BI.Q anzeigt ist einfach falsch.
    Was hab ich bis jetzt gemacht bzw. herausgefunden?

    ich hab das perl-skript von RaK genommen und ausgeführt (kann natürlich nicht funktionieren da ich eibd nicht habe) um zu sehen wie das Zeitsignal aussieht.
    Code:
    #!/usr/bin/perl
     
    use Math::BaseCnv;
     
    # right $len chars
    sub rstr{
      my $s = shift;
      my $len = shift;
      # printf("DEBUG %s %i\n",$s,$len);
      return substr($s, length($s) - $len, $len);
    }
     
    # read local time
    ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime(time);
     
    # Mon is KNX 001 and Sun is 111 in Linux is Sun 1 und Sat 7
    @weekDays = qw(111 001 010 011 100 101 110);
     
    # calc $hour in bin with exact 5 digits
    $bin_hour = rstr("000000".cnv( $hour, 10, 2) ,5);
     
    @args = ("/usr/bin/groupwrite", "ip:127.0.0.1", "0/6/6",                  # change protocoll to your needs
             sprintf("%02X", cnv( $weekDays[$dayOfWeek] . $bin_hour, 2, 10)), # calc weekday and hour in hex
             sprintf("%02X", $minute),                                        # same for minute and second
             sprintf("%02X", $second));
     
    # execute command
    system(@args) == 0 or die "system @args failed: $?";
    Soweit so gut. Ich erhalte das Signal in einem HEX-Format. Danach gleich mal versucht mit LinuxMCE diesen Teil auf den bus zu senden. Ergebnis: Zeit ist irgendwie eingestellt...
    Nachdem ich den SourceCode für den EIB Teil in LMCE durchsucht habe fand ich heraus dass er einen int erwartet.
    Hier der Teil für das senden:
    Code:
            /** @brief COMMAND: #273 - EIB_Write */
    617             /** Peforms a WRITE request on the bus */
    618                     /** @param #108 Address */
    619                             /** EIB Group Address */
    620                     /** @param #109 Data String */
    621                             /** EIB Data */
    622                     /** @param #110 DataType */
    623                             /** EIB Data Type:
    624     [1]-switch (1b)
    625     [2]-dimming-control (4b)
    626     [3]-time (3B)
    627     [4]-date (4B)
    628     [5]-value (2B)
    629     [6]-scaling (1B)
    630     [7]-drive control
    631     [9]-float
    632     [10]-16bit counter
    633     [11]-32bit counter
    634     [13]-ASCII character
    635     [14]-8bit counter
    636     [15]-character string */
    637     
    638     void EIB::CMD_EIB_Write(string sAddress,string sData_String,int iDataType,string &sCMD_Result,Message *pMessage)
    639     //<-dceag-c273-e->
    640     {
    641             LoggerWrapper::GetInstance()->Write(LV_STATUS, "Received a Write request: (To= %s, Data Type=%d, Data=%s) ",
    642                                                                                                     sAddress.c_str(), iDataType, sData_String.c_str());
    643            
    644             if(sAddress.length() == 0) {
    645                     LoggerWrapper::GetInstance()->Write(LV_STATUS, "Empty Group Address passed as parameter");
    646                     return;
    647             }
    648                                                                                                    
    649             TelegramMessage tlmsg;
    650             tlmsg.setGroupAddress(sAddress.c_str());
    651            
    652             switch(iDataType) {
    653             case DT_SWITCH:
    654             case DT_DIMMING_CONTROL:
    655             case DT_DRIVE_CONTROL:
    656             case 8:
    657                     tlmsg.setShortUserData(atoi(sData_String.c_str()));
    658                     break;
    659                    
    660             case DT_SCALING:
    661             case DT_ASCIICHAR:
    662             case DT_COUNTER8: {
    663                     unsigned char data = atoi(sData_String.c_str());
    664                     tlmsg.setUserData(&data, 1);
    665                     } break;
    666                    
    667             case DT_VALUE:
    668             case DT_COUNTER16: {
    669                     unsigned short data = atoi(sData_String.c_str());
    670                     tlmsg.setUserData((unsigned char*)&data, 2);
    671                     } break;
    672            
    673             case DT_TIME:
    674             case DT_DATE: {
    675                     unsigned int data = atoi(sData_String.c_str());
    676                     tlmsg.setUserData((unsigned char*)&data, 3);
    677                     } break;
    678            
    679             case DT_FLOAT:
    680             case DT_COUNTER32:
    681             case 12: {
    682                     unsigned int data = atoi(sData_String.c_str());
    683                     tlmsg.setUserData((unsigned char*)&data, 4);
    684                     } break;
    685            
    686             case DT_STRING: {
    687                     tlmsg.setUserData((unsigned char*)sData_String.c_str(), sData_String.length());
    688                     } break;
    689            
    690             default:
    691                     LoggerWrapper::GetInstance()->Write(LV_WARNING, "Unknown TYPE specified for Write request");
    692                     return;
    693             }
    694            
    695             m_msgPool.sendTelegram(&tlmsg);
    696     }
    In Zeile 675 sieht man dass er in int umwandelt.
    Nun meine konkrete Frage: wie muss ich das HEX umwandeln dass ich das richtige Format bekomme???

    lg und danke
    avajon

    #2
    Hi,

    The Perl script is printing values in hexadecimal format (%02X), while linuxMCE interprets the input string as a decimal number.
    In LinuxMCE, I think you must use a number corresponding to (seconds) + (256 * minutes) + (65536 * hours) + (2097152 * weekday)

    Kind regards,

    Jean-François

    P.S.: Wenn du kein Engels werstehst kann ich auch auf Deutsch probieren, aber es ist schwerer fur mich.

    Kommentar


      #3
      Also ich bin nun nicht wirklich fit in Perl. Aber ich kann mir nicht vorstellen, daß es INT sein kann. Ein int hat ja nur zwei Byte. Das Zeitsignal hat aber 4 Byte.

      00 53 20 00 = 19:32:00 Zentrale Uhrzeit
      00 1e 0a 07 = 30.10.2007 Zentrales Datum

      Das atoi konvertiert einen String in eine Zahl. Wie sieht denn der String aus, der da rein geht? Kann ja wohl keine Zeit sein.

      Gruß eiche

      Kommentar


        #4
        Du musst das HEX reingeben, dann gehts.
        Habe da mein ein VB-Script veröffentlicht.
        19.00 Uhr ist zb. 76C
        never fummel a running system...

        Kommentar


          #5
          Auf modernen rechner hat ein int 4 bytes.

          Ich verstehe nicht warum das eerste skript so komplex ist, der folgende skript gibt genau das selbe resultat:

          ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek) = localtime(time);
          $dayOfWeek = 7 if ($dayOfWeek==0);
          printf("&#37;06X\n", ($second) | ($minute << 8) | ($hour << 16) | ($dayOfWeek << 21));

          Und wenn du "%06X" durch "%d" ersetzt, kriegst du den gewünschten nummer für LinuxMCE.

          Pass auf dass das LinuxMCE code nicht "portable" ist. Ob das rechner "little endian" oder "big endian" ist, kriegst du nicht das selbe.
          In diesem fal ist es villeicht:
          printf("%06X\n", ($second << 16) | ( $minute << 8) | ($hour) | ($dayOfWeek << 5));

          Kommentar


            #6
            super. danke für die vielen Antworten und Lösungstipps. ich werde heute abend zuhause mal alle probieren und danach schreiben wie und ob es funktioniert hat.

            lg
            avajon

            Kommentar


              #7
              hallo,

              jef2000, dein Tip hat funktioniert!
              Genauer gesagt diese Zeile:
              printf("%06X\n", ($second << 16) | ( $minute << 8) | ($hour) | ($dayOfWeek << 5));

              VIELEN DANK!!!

              lg
              avajon

              Kommentar

              Lädt...
              X