Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1677 connectés 

 


 Mot :   Pseudo :  
 
 Page :   1  2  3  4  5  6  7
Auteur Sujet :

[Résolu] Export données en perl

n°2222113
clubber43
Posté le 12-03-2014 à 10:49:37  profilanswer
 

Reprise du message précédent :
BON !!
Les problèmes de connexions et d'erreurs sont OK, je compile le code et là, j'ai un message :
 
DBD::mysql::db do failed you have an error in your SQL synthax à line 37, check the manual . . .  
DBD::mysql::db do failed you have an error in your SQL synthax à line 37, check the manual . . .  
 
pourtant, le script parait juste :
 

Code :
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;
  4. use Encode;
  5. use utf8;
  6. use DBI;            # Charger le module DBI
  7.  
  8.  
  9. ActiverAccents();
  10.  
  11. # Paramètres de connection à la base de données
  12. my $bd        = 'Energie';
  13. my $serveur    = '127.0.0.1'; # @ IP IP
  14. my $identifiant = 'root';      # identifiant  
  15. my $motdepasse    = 'admin';
  16. my $port    = '3306';        #Si vous ne savez pas, ne rien mettre
  17.  
  18. # Connection à la base de données mysql
  19. print "Connexion a la base de donnees $bd\n";
  20. my $dbh = DBI->connect( "DBI:mysql:database=$bd;host=$serveur;port=$port",  
  21.    $identifiant, $motdepasse, {  
  22.     RaiseError => 1,
  23.    }  
  24. ) or die "Connection impossible a la base de donnees $bd !\n $! \n $@\n$DBI::errstr";
  25.  
  26. # Création des tables
  27. print "Creation de la table COMPTEUR\n";
  28. my $sql_creation_table_compteur = <<"SQL";
  29.  id_compteur    INT             NOT NULL PRIMARY KEY ,
  30.  emplacement      VARCHAR( 10 )   NOT NULL ,
  31.  batiment    VARCHAR( 10 )   NOT NULL ,
  32.  niveau     VARCHAR( 10 )   NOT NULL )
  33. COMMENT = 'COMPTEUR';
  34. SQL
  35.  
  36. $dbh->do('DROP TABLE IF EXISTS compteur;') or die "Impossible de supprimer la table compteur\n\n";
  37. $dbh->do($sql_creation_table_compteur) or die "Impossible de creer la table compteur\n\n";
  38.  
  39. print "Creation de la table Releves\n";
  40. my $sql_creation_table_releves = <<"SQL";
  41. CREATE TABLE releves (
  42.  id_compteur      INT               NOT NULL  AUTO_INCREMENT PRIMARY KEY COMMENT #Elle sera generee automatiquement,
  43.  puissance_p      INT          NOT NULL ,
  44.  puissance_q      INT          NOT NULL ,
  45.  courant_I      INT          NOT NULL )
  46. COMMENT = 'COMPTEUR';
  47. SQL
  48.  
  49. $dbh->do('DROP TABLE IF EXISTS releves;') or die "Impossible de supprimer la table releves\n\n";
  50. $dbh->do($sql_creation_table_releves) or die "Impossible de creer la table releves\n\n";
  51.  
  52.  
  53. # Insertion des données
  54. my $requete_sql_compteur = <<"SQL";
  55.  INSERT INTO rcompteur ( id_compteur, emplacement, batiment, niveau)
  56.  VALUES ( 1, TDD1, D, 1);
  57. SQL
  58.  
  59. # Deconnection de la base de donnees
  60. $dbh->disconnect();
  61.  
  62.  
  63. sub ActiverAccents {
  64.    my $encodage;
  65.    # Windows
  66.      if ( lc($^O ) eq 'mswin32') {
  67.     eval {
  68.         my ($codepage) = ( `chcp` =~ m/:\s+(\d+)/ );
  69.         $encodage = "cp$codepage";
  70.         foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) {
  71.         binmode $h, ":encoding($encodage)";
  72.         }
  73.     };
  74.    }
  75.    else {
  76.     $encodage = `locale charmap`;
  77.     eval {
  78.         foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) {
  79.         binmode $h, ":encoding($encodage)";
  80.         }
  81.     };
  82.    }
  83.  return $encodage;
  84. }


Message édité par gilou le 12-03-2014 à 12:08:28
mood
Publicité
Posté le 12-03-2014 à 10:49:37  profilanswer
 

n°2222120
clubber43
Posté le 12-03-2014 à 11:25:02  profilanswer
 

j'ai pourtant bien installé le module DBI, et je ne vois pas pourquoi ma requete pour créer le bdd ne marche pas.
 
Merci
 
+

n°2222124
gilou
Modérateur
Modzilla
Posté le 12-03-2014 à 12:23:03  profilanswer
 

Il faudrait peut être lire les messages d'erreur et tacher de les comprendre!
 
>> DBD::mysql::db do failed you have an error in your SQL synthax à line 37, check the manual . . .  
et ligne 37: $dbh->do($sql_creation_table_compteur) or die "Impossible de creer la table compteur\n\n";  
Error dans le contenu SQL, donc c'est le contenu de $sql_creation_table_compteur qui est une requête SQL invalide, et si on regarde son contenu, on voit tout de suite que vous avez zappé la ligne du début avec un CREATE TABLE (ça saute aux yeux si on regarde le parenthésage fermant " niveau     VARCHAR( 10 )   NOT NULL )" qui n'a pas de parenthésage ouvrant correspondant.
 
Moi je veux bien aider, mais si c'est sur ce type d'erreur qu'une simple relecture fait sauter aux yeux, je vais arrêter.
 
A+,


Message édité par gilou le 12-03-2014 à 12:24:26

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2222125
clubber43
Posté le 12-03-2014 à 13:09:24  profilanswer
 

C'est bon,  
j'ai compris le truc,
 
en recopiant mon script depuis mon brouillon, j'ai zappé de mettre le CREATE TABLE compteur( ....),  
Je passe pas mal de temps sur le code et du coup, je suis un peu perdu et je n'ai pas forcement fais gaffe aux parentheses.
 
A l'avenir, je regarde un peu plus et je post vraiment si j'ai tout relus, pas de soucis.
C'est noté.
 
 
Ma Bdd est créé, j'ai inseré des valeurs dedans et maintenant, à moi de voir comment l'afficher et comment la faie tourner.
 
Le prochain jalon, c'est d'inserer lse valeurs des requetes depuis le compteur que lon a vu ensemble en page1 et 2.
 
 
Merci et @+

n°2222129
clubber43
Posté le 12-03-2014 à 14:06:07  profilanswer
 

Après avoir créé la BDD et l'avoir incrémentée, j'ai codé le pgm pour lire les données en mémoire.
 
J'ai bien fait attention aux ( , } et autre
J'ai cependant un doute sur l'appel de obtenir_compteur(); qui appelle ma fonction et qui pint les valeurs en émoire de la BDD.
 
Mon erreur est la suivante :
can't call method "prepar" on undefinied value ligne 32.
 

Code :
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;
  4. use DBI;            # Charger le module DBI
  5.  
  6.  
  7. #ActiverAccents();
  8.  
  9. # Paramètres de connection à la base de données
  10. my $bd        = 'Energie';
  11. my $serveur    = '127.0.0.1'; # @ IP IP
  12. my $identifiant = 'root';      # identifiant  
  13. my $motdepasse    = 'admin';
  14. my $port    = '3306';        #Si vous ne savez pas, ne rien mettre
  15.  
  16. # Connection à la base de données mysql
  17. print "Connexion a la base de donnees $bd\n";
  18. my $dbh = DBI->connect( "DBI:mysql:database=$bd;host=$serveur;port=$port",  
  19.    $identifiant, $motdepasse, {  
  20.     RaiseError => 1,
  21.    }  
  22. ) or die "Connection impossible a la base de donnees $bd !\n $! \n $@\n$DBI::errstr";
  23.  
  24.  
  25. obtenir_compteur();
  26.  
  27. # Procédure pour obtenir toutes les compteurs - méthode fetchrow_array
  28. sub obtenir_compteur {
  29.  my $dbh = shift;
  30.  
  31.  my @compteur;
  32.  my $prep = $dbh->prepare('SELECT puissance_p FROM compteur ORDER BY') or die $dbh->errstr;
  33.  $prep->execute() or die "Echec requete\n";
  34.  while ( my ($compteur) = $prep->fetchrow_array ) {
  35.    push( @compteur, $compteur );
  36.  }
  37.  $prep->finish();
  38.  print "\n";
  39.  
  40.  return @compteur;
  41. }

 
 
merci


Message édité par gilou le 12-03-2014 à 21:29:42
n°2222180
gilou
Modérateur
Modzilla
Posté le 12-03-2014 à 21:37:23  profilanswer
 

> can't call method "prepare" on undefined value ligne 32.  
Allons voir la ligne 32
my $prep = $dbh->prepare('SELECT puissance_p FROM compteur ORDER BY') or die $dbh->errstr;  
donc le message d'erreur dit que $dbh est indéfini
Allons voir ou il est assigné une valeur
 
sub obtenir_compteur {
 my $dbh = shift;  
 
Donc $dbh est le premier argument passé à la procédure.  
Allons voir l'appel
obtenir_compteur();
Tiens, il y a pas d'argument :sarcastic:  
 
Donc quand on fait
my $dbh = shift;  
$dbh est indéfini, et donc le message d'erreur est parfaitement justifié, et c'est encore une erreur que vous auriez pu trouver.
 
Il fallait bien sur passer la variable $dbh en paramètre à l'appel afin qu'il soit passé a la variable locale (de même nom) de la procédure: obtenir_compteur($dbh);
 
A+,


Message édité par gilou le 12-03-2014 à 22:26:22

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2223579
clubber43
Posté le 31-03-2014 à 15:28:38  profilanswer
 

Hello ^^
 
Du coup, j'ai bien travaillé le code et tout marche comme une montre suisse.
 
J'essaie doonc de l'ameliorer maintenant.
 
Je travaille sur un mini script à joindre à mon script général qui va lire les adresses IP dans un fichier txt et les renvoie au script principal.
En gros,  
 
Début programme :
     Lire adresse IP1.
     Faire programme
     Lire adresse IP2  
     ...
Fin programme.
 
Du coup, j'ai commencé le codage du script de lecture des adresses et il faut que je modifie le programme principal avec une boucle qui va pour chaque adresse IP executer son script.
 
Petite question, sur mes adresses IP, quand je les copie-colle dans mon fichier.txt, je peux laisser les . de 172.xxx.xxx.xxx et ainsi directement mettre la valeur lue dans mon script ?
 
 
En gros le pgm principal serait :

Code :
  1. #!/usr/bin/perl
  2. open(F,'c:/adresses_ip.txt') || die "impossible ";
  3. $i=0;
  4. while(<F> )
  5. {
  6. #Lire adresse
  7.      {
  8.      executer programme
  9.      ligne++;
  10.      }
  11. }


 
et le fichier des adresses IP ressemble à  :
 
172.17.14.1;
172.17.14.2;
172.17.14.3;
172.17.14.4;
172.17.14.5;
 
@+
 
julien

n°2223585
clubber43
Posté le 31-03-2014 à 16:10:03  profilanswer
 

J'ai commencé à code le script de lecture et d'extraction des adresses IP.
 
Est-ce que ma logique pour le début du cheminement est bonne, boucle, ouverture/fermeture fichier, ... ?  
 

Code :
  1. #!/usr/bin/perl
  2.   use strict;
  3.   use warnings;
  4.   use Socket;
  5. # Paramètres ModBus/TCP
  6.   my $MODBUS_PORT                                 = 502;
  7. # Codes des fonctions lecture, ecriture, ...
  8.   my $READ_COILS                                  = 0x01;
  9.   my $READ_DISCRETE_INPUTS                        = 0x02;
  10.   my $READ_HOLDING_REGISTERS                      = 0x03;
  11.   my $READ_INPUT_REGISTERS                        = 0x04;
  12.   my $WRITE_SINGLE_COIL                           = 0x05;
  13.   my $WRITE_SINGLE_REGISTER                       = 0x06;
  14. # Codes des exceptions erreurs, ...
  15.   my $EXP_ILLEGAL_FUNCTION                        = 0x01;
  16.   my $EXP_DATA_ADDRESS                            = 0x02;
  17.   my $EXP_DATA_VALUE                              = 0x03;
  18.   my $EXP_SLAVE_DEVICE_FAILURE                    = 0x04;
  19.   my $EXP_ACKNOWLEDGE                             = 0x05;
  20.   my $EXP_SLAVE_DEVICE_BUSY                       = 0x06;
  21.   my $EXP_MEMORY_PARITY_ERROR                     = 0x08;
  22.   my $EXP_GATEWAY_PATH_UNAVAILABLE                = 0x0A;
  23.   my $EXP_GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND = 0x0B;
  24. # Valeurs par défaut
  25.   my $opt_server                                  = 'localhost';
  26.   my $opt_server_port                             = $MODBUS_PORT;  #502
  27.   my $opt_timeout                                 = 1;   # temps max de 1 s
  28.   my $opt_unit_id                                 = 1;
  29.   my $opt_mb_ad;
  30.   my $opt_mb_fc                                   = $READ_HOLDING_REGISTERS;
  31.   my $opt_mb_nb                                   = 1;
  32.   my $opt_bit_value                               = 0;
  33.   my $opt_word_value                              = 0;
  34. {
  35.   my $ligne=0;
  36.   open(F,'c:/adresses_ip.txt') || die "impossible ";
  37.   for $ligne=<F>
  38.      {
  39.   # récupération des éléments
  40.   ($adresse) = split /;/,$ligne;
  41.   # et on insere dans le script
  42.   $opt_server = $adresse
  43.      }
  44.  
  45.   my $server_ip = inet_aton($opt_server);  # on donne l'@ IP à la variable
  46.   unless ($server_ip) { 
  47.   print STDERR 'unable to resolve "'.$opt_server.'"'."\n"; # et la, 
  48.   exit 1; 
  49.   } 
  50.   my $status = query_info();
  51.   until ($status) {
  52.   sleep(10);  # toutes les 10s, a adapter à ses besoins
  53.   $status = query_info();
  54.   }
  55. # boucle infinie, a stopper avec un kill
  56. sub query_info{
  57. # Gestion du dialogue reseau
  58. # Ouverture de la session TCP
  59.   socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
  60.   unless (connect(SERVER, sockaddr_in($MODBUS_PORT, $server_ip))) {
  61.     print STDERR 'connexion au serveur "'.$server_ip.':'.$MODBUS_PORT.'" impossible'."\n";
  62.     return 2;
  63.   }
  64.  
  65.   my @adresses = qw(109 265 305 15 27); #Liste des adresses à interroger puissance P, Q et I
  66.   my %result;
  67. #15 courant
  68. #27 coef dephasage
  69. #265 puissnace P
  70. #305 puissance Q
  71.   foreach (@adresses) { 
  72.   $opt_mb_ad = $_;     
  73. # Création de la requête 
  74.   my $tx_hd_tr_id   = int(rand 65535);
  75.   my $tx_hd_length  = 6;
  76.   my $tx_hd_pr_id   = 0;
  77.   my $tx_buffer = pack("nnnCCnn", $tx_hd_tr_id, $tx_hd_pr_id , $tx_hd_length, $opt_unit_id, $opt_mb_fc, $opt_mb_ad, $opt_mb_nb);
  78.  
  79. # Emission de la requête vers le serveur
  80.   send(SERVER, $tx_buffer, 0);
  81.  
  82. # Attente d'une réponse
  83.   unless (can_read('SERVER', $opt_timeout)) {
  84.     close SERVER;
  85.     print STDERR 'receive timeout'."\n"; # erreur si depassement du temps d'attente
  86.     return 1;
  87.   }
  88.  
  89. # Réception de l'entête depuis le serveur
  90.   my ($rx_frame, $rx_buffer);
  91.   recv(SERVER, $rx_buffer, 7, 0);
  92.   $rx_frame = $rx_buffer;
  93.  
  94. # Décodage de l'entête
  95.   my ($rx_hd_tr_id, $rx_hd_pr_id, $rx_hd_length, $rx_hd_unit_id) = unpack "nnnC", $rx_buffer;
  96.  
  97. # Vérifie la cohérence de l'entête
  98.   unless (($rx_hd_tr_id == $tx_hd_tr_id) &&
  99.       ($rx_hd_pr_id == 0) &&
  100.       ($rx_hd_length < 256) &&
  101.       ($rx_hd_unit_id == 1)) {
  102.     close SERVER;
  103.     print STDERR 'error in receive frame'."\n";
  104.     return 1;
  105.   }
  106.  
  107. # Réception du corps du message
  108.   recv(SERVER, $rx_buffer, $rx_hd_length-1, 0);
  109.   $rx_frame .= $rx_buffer;
  110.  
  111.  
  112. # Décodage du corps du message
  113.   my ($rx_bd_fc, $rx_body) = unpack "Ca*", $rx_buffer;
  114.  
  115. # Vérification du statut d'exception
  116.   if ($rx_bd_fc > 0x80) {
  117. # Affichage du code exception
  118.     my ($rx_except_code) = unpack "C", $rx_body;
  119.     print 'exception (code '.$rx_except_code.')'."\n";
  120.   } 
  121.   else {
  122. ## Lecture de mot
  123.     my ($rx_bd_bc, $rx_read_word_data) = unpack "Ca*", $rx_body;
  124. # Lecture d'entier de 16 bits
  125. # un seul registre a lire d'ou le 'n'
  126.     $result{$opt_mb_ad} = unpack 'n', $rx_read_word_data;
  127.     }
  128.     }
  129. close SERVER;
  130. # fin de la boucle foreach 
  131. # impression en console
  132.   foreach (sort {$a <=> $b} (keys %result)) {
  133.   print "<$_> : $result{$_} \t;"  # On utilise un hash pour passer les valeurs et avoir plusieurs valeurs par retour
  134.   #disp_data(%result);
  135. }
  136. print "\n";
  137. #attente $timeout
  138.   sub can_read{
  139. my ($sock_handle, $timeout) = @_;
  140. my $hdl_select="";
  141. vec($hdl_select, fileno($sock_handle),1)=1;
  142. return (select($hdl_select, undef, undef, $timeout)==1);
  143. }
  144. my $time = time; 
  145. my @months = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" );
  146. my ($sec, $min, $hour, $day,$month,$year) = (localtime($time))[0,1,2,3,4,5];
  147. print "timestamp : ".$time. " "
  148. }
  149. $ligne++;
  150. }


 
merci

n°2223586
clubber43
Posté le 31-03-2014 à 16:10:47  profilanswer
 

A partir d ela ligne 45 à 60

n°2223629
gilou
Modérateur
Modzilla
Posté le 31-03-2014 à 23:04:03  profilanswer
 

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Socket;
  5. # Paramètres ModBus/TCP
  6.  
  7. ..............................................................
  8.  
  9. my $opt_mb_ad;
  10. my $opt_mb_fc                                   = $READ_HOLDING_REGISTERS;
  11. my $opt_mb_nb                                   = 1;
  12. my $opt_bit_value                               = 0;
  13. my $opt_word_value                              = 0;
  14.  
  15.  
  16. open(F,'c:/adresses_ip.txt') || die "impossible ";
  17. # debut de la boucle ligne à ligne sur le fichier
  18. while (<F> ) {
  19.  # récupération des éléments
  20.  ($adresse) = split /;/,$ligne;
  21.  # et on insere dans le script
  22.  $opt_server = $adresse;
  23.  
  24.  my $server_ip = inet_aton($opt_server); # on donne l'@ IP à la variable
  25.  unless ($server_ip) {
  26.    print STDERR 'unable to resolve "'.$opt_server.'"'."\n"; # et la,
  27.    exit 1;
  28.  }
  29.  
  30. .........
  31.  
  32.    sub can_read{
  33.      my ($sock_handle, $timeout) = @_;
  34.      my $hdl_select="";
  35.      vec($hdl_select, fileno($sock_handle),1)=1;
  36.      return (select($hdl_select, undef, undef, $timeout)==1);
  37.    }
  38.    my $time = time;
  39.    my @months = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" );
  40.    my ($sec, $min, $hour, $day,$month,$year) = (localtime($time))[0,1,2,3,4,5];
  41.    print "timestamp : ".$time. " "
  42.  }
  43. # fin de la boucle ligne à ligne sur le fichier
  44. }


 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
mood
Publicité
Posté le 31-03-2014 à 23:04:03  profilanswer
 

n°2223637
clubber43
Posté le 01-04-2014 à 08:51:20  profilanswer
 

Merci pour le code, j'ai juste 2 questions,
 
à la ligne 27,  
Car dans le code, je touve des return 1 et des exit 1. Du coup, je ne comprend pas pourquoi il y a ces 2 synthaxes.
c'est un equivalent au return 1 en cpp ? Le exit est -il la pour nous permettre de sortir de la boucle ?  
 
Derniere question, dans le code, il y a un bout sur le codage en 16bits. Cependant, le codage de mes données est en 48 bits.
Je dois modifier ma requete du coup ? car si j'ai tout bien relu, pour un codage 16bits, on a un ran (65536) qui correspond à 2^16.
Donc dans cette logique, j'aurais un 2^48 dans le ran si mon codage est dur 48bits
 
Merci pour le coup de main;

n°2223661
gilou
Modérateur
Modzilla
Posté le 01-04-2014 à 12:57:31  profilanswer
 

return, c'est d'une subroutine, tu reviens à l'appelante avec la valeur.
exit, ça fait finir le programme (avec la valeur donnée, exploitable éventuellement par le shell qui a lancé le programme perl)

 

> Derniere question, dans le code, il y a un bout sur le codage en 16bits. Cependant, le codage de mes données est en 48 bits.
D'ou sais tu que tu as des données sur 48 bits? Le protocole Modbus ne supporte pas plus que des entier sur 32 bits (deux mots de 16 consécutifs) à priori.

 

A+,


Message édité par gilou le 01-04-2014 à 13:06:12

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2223667
clubber43
Posté le 01-04-2014 à 13:21:47  profilanswer
 

Autant pour moi,  
 
la variable est exprimée toujours en 16 bits mais codée sur 3 mots donc je suis allé un peu vite en faisant 16*3 = 48 donc oui, 3 mots mais codés en 16 bits.  
Du coup, que je sois en 1,2 ou 3 mots, le programme marche quand même?
 
 
Merci pour l'infos du exit-return, c'est beaucoup plus clair ^^
 
merci

n°2223668
clubber43
Posté le 01-04-2014 à 13:23:22  profilanswer
 

 [cpp]

n°2223683
gilou
Modérateur
Modzilla
Posté le 01-04-2014 à 14:30:54  profilanswer
 

C'est incohérent avec la requête, ton histoire:
 
Si tu veux le contenu des 3 mots (de 16 bits) a partir de l'adresse $opt_mb_ad, il faut l'indiquer dans la requête en positionnant la valeur de $opt_mb_nb à 3 et non a 1 (comme c'était fait par défaut dans le programme) avant de construire la requête (pack("nnnCCnn", $tx_hd_tr_id, $tx_hd_pr_id , $tx_hd_length, $opt_unit_id, $opt_mb_fc, $opt_mb_ad, $opt_mb_nb);)
 
Et au décodage, au lieu de faire
my $val = unpack 'n', $rx_read_word_data;
il va falloir faire
my ($val1, $val2, $val3) = unpack 'nnn', $rx_read_word_data;
 
A+,


Message édité par gilou le 01-04-2014 à 14:31:38

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2223684
clubber43
Posté le 01-04-2014 à 14:33:18  profilanswer
 

A oui,  
Du coup tout l'algo est à revoir, parsque mon souci est qu'il y a des variables à 1,2 ou 3 mots donc chaud quand même ^^
 
Je regarde tout ça et posterais ce soir si jamais j'y arrive.
 
Merci
 
@+

n°2223728
clubber43
Posté le 01-04-2014 à 16:31:07  profilanswer
 

Après quelques modifications,
J'ai refaits le code, et je voulais savoir si les corrections apportées été bonnes,  
car le pogramme se lance et j'ai comme valeur remontée <0003> au lieu de 12650, je pense que j'ai du louper un truc à modifier....
 

Code :
  1. #!/usr/bin/perl
  2.   use strict;
  3.   use warnings;
  4.   use Socket;
  5. # Paramètres ModBus/TCP
  6.   my $MODBUS_PORT                                 = 502;
  7. # Codes des fonctions lecture, ecriture, ...
  8.   my $READ_COILS                                  = 0x01;
  9.   my $READ_DISCRETE_INPUTS                        = 0x02;
  10.   my $READ_HOLDING_REGISTERS                      = 0x03;
  11.   my $READ_INPUT_REGISTERS                        = 0x04;
  12.   my $WRITE_SINGLE_COIL                           = 0x05;
  13.   my $WRITE_SINGLE_REGISTER                       = 0x06;
  14. # Codes des exceptions erreurs, ...
  15.   my $EXP_ILLEGAL_FUNCTION                        = 0x01;
  16.   my $EXP_DATA_ADDRESS                            = 0x02;
  17.   my $EXP_DATA_VALUE                              = 0x03;
  18.   my $EXP_SLAVE_DEVICE_FAILURE                    = 0x04;
  19.   my $EXP_ACKNOWLEDGE                             = 0x05;
  20.   my $EXP_SLAVE_DEVICE_BUSY                       = 0x06;
  21.   my $EXP_MEMORY_PARITY_ERROR                     = 0x08;
  22.   my $EXP_GATEWAY_PATH_UNAVAILABLE                = 0x0A;
  23.   my $EXP_GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND = 0x0B;
  24. # Valeurs par défaut
  25.   my $opt_server                                  = 'localhost';
  26.   my $opt_server_port                           = $MODBUS_PORT; #502 par defaut
  27.   my $opt_timeout                                = 1;    # temps max de 1 s
  28.   my $opt_unit_id                                 = 1;
  29.   my $opt_mb_ad;
  30.   my $opt_mb_fc                                   = $READ_HOLDING_REGISTERS;
  31.   my $opt_mb_nb                                  = 1;
  32.   my $opt_bit_value                               = 0;
  33.   my $opt_word_value                            = 0;
  34.   $opt_server = '172.17.14.4';       # @ IP du serveur TCP
  35.   my $server_ip = inet_aton($opt_server);      # on donne l'@ IP à la variable
  36.   unless ($server_ip) { 
  37.   print STDERR 'unable to resolve "'.$opt_server.'"'."\n"; # et la, 
  38.   exit 1; 
  39.   } 
  40.   my $status = query_info();
  41.   until ($status) {
  42.   sleep(10);  # toutes les 10s, a adapter à ses besoins
  43.   $status = query_info();
  44.   }
  45. # boucle infinie, a stopper avec un kill
  46. sub query_info{
  47. # Gestion du dialogue reseau
  48. # Ouverture de la session TCP
  49.   socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
  50.   unless (connect(SERVER, sockaddr_in($MODBUS_PORT, $server_ip))) {
  51.     print STDERR 'connexion au serveur "'.$server_ip.':'.$MODBUS_PORT.'" impossible'."\n";
  52.     return 2;
  53.   }
  54.  
  55.   my @adresses = qw (304 305 306);
  56.   my %result;
  57. #Liste des adresses à interroger puissance P, Q et I
  58.  
  59. #15 17 19 courant I1àI3 et moyen
  60. #24 25 26 27 coef dephasage par phase et moyen
  61. #267 Puissance
  62. #305 Puissance
  63.   foreach (@adresses) { 
  64.   $opt_mb_ad = $_;     
  65. # Création de la requête 
  66.   my $tx_hd_tr_id   = int(rand 65536);
  67.   my $tx_hd_length  = 6;
  68.   my $tx_hd_pr_id   = 0;
  69.   my $opt_mb_nb = 3;                          ####################################################
  70.   my $tx_buffer = pack("nnnCCnn", $tx_hd_tr_id, $tx_hd_pr_id , $tx_hd_length, $opt_unit_id, $opt_mb_fc, $opt_mb_ad, $opt_mb_nb);
  71.  
  72. # Emission de la requête vers le serveur
  73.   send(SERVER, $tx_buffer, 0);
  74.  
  75. # Attente d'une réponse
  76.   unless (can_read('SERVER', $opt_timeout)) {
  77.     close SERVER;
  78.     print STDERR 'receive timeout'."\n"; # erreur si depassement du temps d'attente
  79.     return 1;
  80.   }
  81.  
  82. # Réception de l'entête depuis le serveur
  83.   my ($rx_frame, $rx_buffer);
  84.   recv(SERVER, $rx_buffer, 7, 0);
  85.   $rx_frame = $rx_buffer;
  86.  
  87. # Décodage de l'entête
  88.   my ($rx_hd_tr_id, $rx_hd_pr_id, $rx_hd_length, $rx_hd_unit_id) = unpack "nnnC", $rx_buffer;
  89.  
  90. # Vérifie la cohérence de l'entête
  91.   unless (($rx_hd_tr_id == $tx_hd_tr_id) &&
  92.       ($rx_hd_pr_id == 0) &&
  93.       ($rx_hd_length < 256) &&
  94.       ($rx_hd_unit_id == 1)) {
  95.     close SERVER;
  96.     print STDERR 'error in receive frame'."\n";
  97.     return 1;
  98.   }
  99.  
  100. # Réception du corps du message
  101.   recv(SERVER, $rx_buffer, $rx_hd_length-1, 0);
  102.   $rx_frame .= $rx_buffer;
  103.  
  104.  
  105. # Décodage du corps du message
  106.   my ($rx_bd_fc, $rx_body) = unpack "Ca*", $rx_buffer;
  107.  
  108. # Vérification du statut d'exception
  109.   if ($rx_bd_fc > 0x80) {
  110. # Affichage du code exception
  111.     my ($rx_except_code) = unpack "C", $rx_body;
  112.     print 'exception (code '.$rx_except_code.')'."\n";
  113.   } 
  114.   else {
  115. ## Lecture de mot
  116.     my ($rx_bd_bc, $rx_read_word_data) = unpack "Ca*", $rx_body;
  117. # Lecture d'entier de 16 bits
  118. # 3 registres à lire d'ou le nnn
  119.     $result{$opt_mb_ad} = unpack 'nnn', $rx_read_word_data;  ####################################################
  120.     }
  121.     }
  122. close SERVER;
  123. # fin de la boucle foreach 
  124. # impression en console
  125.   foreach (sort {$a <=> $b} (keys %result)) {
  126.   print "<$_> : $result{$_} \t;"  # On utilise un hash pour passer les valeurs et avoir plusieurs valeurs par retour
  127.   #disp_data(%result);
  128. }
  129. print "\n";
  130. #attente $timeout
  131.   sub can_read{
  132. my ($sock_handle, $timeout) = @_;
  133. my $hdl_select="";
  134. vec($hdl_select, fileno($sock_handle),1)=1;
  135. return (select($hdl_select, undef, undef, $timeout)==1);
  136. }
  137. my $time = time; 
  138. my @months = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" );
  139. my ($sec, $min, $hour, $day,$month,$year) = (localtime($time))[0,1,2,3,4,5];
  140. print "timestamp : ".$time. " ";
  141. print "timestamp : ".$time. " "
  142. }


 

n°2223735
gilou
Modérateur
Modzilla
Posté le 01-04-2014 à 17:10:25  profilanswer
 

Ben non, si j'avais pas écrit ceci:
$result{$opt_mb_ad} = unpack 'nnn', $rx_read_word_data;
Mais 3 variables de 16 bits, il y avait peut être des raisons.
Vous récupérerez 3 valeurs numériques de 16 bits, c'est a vous d'en faire qque chose (et je ne sais toujours pas pourquoi vous avez des données sur 3 mots, mais passons... tant que c'est pas pour des valeurs en virgule flottante, ce que ne supporte pas le protocole modbus, au vu de la spec)
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2223792
clubber43
Posté le 02-04-2014 à 08:31:34  profilanswer
 

En fait, je vais cherhcer des varaibale dans le module Ethernet (doc ci-dessous)
http://www.compteur-electrique.ene [...] S_ed01.pdf
 
Que je veux intégrer dans une base de données SQL.
Ceratines valeurs sont exprimées en 1 ou 3 mots de 16bits. COmme par exemple la variable :
 

Code :
  1. Parameter F.                               code (Hex) .     Words M.U.


Code :
  1. Total imported active energy .      03 / 04. 0109.     3

 
qui corespond au champs Hexa 0109 (265 en base dec.) écrit en 3 mots de 16bits.
 
Du coup, je dois prendre en compte ce type de 3 mots, car sinon, le script ne me renvoie pas les bonnes valeurs.
 
Je relis le script et le remodifie.
 
J'espere que j'ai été clair dans mon explication, car je découvre le probleme et j'avance à mon allure,  
Mais toutes les informations ne sont pas encore à ma portée (novice mais motivé) ^^
 
Merci gilou
 

n°2223796
clubber43
Posté le 02-04-2014 à 09:17:29  profilanswer
 

Code :
  1. my ($val1, $val2, $val3) = unpack 'nnn', $rx_read_word_data;


 
Même si j'ai qu'une seule valeur codée en 3 mots, je dois quand même créé"my ($val1, $val2, $val3)" du coup ?  
car là si je comprend le code, on créé 3 variables val1,2,3 qui vont prendre la valeur de chaque mots.
 
La variable en 3 mots, car on peut exprimer des valeurs très grande (999 999 999 WH) à mon avis.
Mais celle ci ne peut etre à virgule mais en entier.

n°2223817
gilou
Modérateur
Modzilla
Posté le 02-04-2014 à 12:01:25  profilanswer
 

Le problème n'est pas la.
Le protocole Modbus ne connait que des valeurs numériques sur 16 bits, point barre.
Il n'a pas été concu pour échanger des valeurs plus grandes.
 
Après, on peut toujours avoir des extensions propriétaires, mais se posent alors les problème d'indianness (qui ne se poseraient pas si le protocole avait prévu un ordre déterminé pour encoder/décoder les nombres sur 32 ou 64 bits):

Citation :

These three options (Little-endian, Word-registers, and Word-count) allow 8 possible variations of 32/64-bit value handling. At least 5 of these variations have actually been used in devices, so you may need to carefully read documentation, or to experiment, to determine which variation a particular device uses.


http://wingpath.co.uk/modbus/modbus_extensions.php
 
Bref, on risque rapidement d'avoir du code qui marche ou pas selon l'implémentation particulière du protocole du device...
 
A+,


Message édité par gilou le 02-04-2014 à 12:01:43

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2223827
clubber43
Posté le 02-04-2014 à 13:08:38  profilanswer
 

A daccord;
 
Du coup, si j'ai bien compris, à part les valeur codées en 16bits (1 mot), il ne sera pas possible d'extraire les données codées en 3mots du coup?
 
Après recherche ce matin, j'ai trouvé un boitier qui se place sur un switch au même niveau que les module Modbus (RJ45) et qui va décodé les bonnes valeurs
Il permet entre autre, de décoder les datas et de les enregistrer sur une mini database interne.
http://www.compteur-electrique.ene [...] ogger.aspx
 
Seulement, il vaut 900€ht donc, je ne peux pas l'acheter ^^
C'est pour sa, que je cherchais un script capable d'interfacer avec les modules Ethernet.
 
Donc en gros, il me reste à acheter le boitier pour pouvoir accéder aux données.
 

n°2223832
gilou
Modérateur
Modzilla
Posté le 02-04-2014 à 13:54:44  profilanswer
 

clubber43 a écrit :

A daccord;
 
Du coup, si j'ai bien compris, à part les valeur codées en 16bits (1 mot), il ne sera pas possible d'extraire les données codées en 3mots du coup?
 

On peut extraire les 3 mots, mais c'est à toi de savoir comment on recombine les morceaux pour obtenir ce que l'on veut.
 
Si tu n'utilises ce programme que pour un device unique, et que tu sais comment a partir de ce qui est dans les 3 mots, tu reconstitues le nombre de départ, à priori pas de problème.
 
A+,

n°2223833
clubber43
Posté le 02-04-2014 à 13:59:12  profilanswer
 

A ok,  
 
Donc, en recombinant les morceaux des 3 mots, pour une seule variable, je peux quand même avoir acces à ma variable?
j'ai comme info, la valeur de la variable actuelle (<267>=012640> ) qui ne change pas.
 
 
De toute façon, l'adresse  restera la même, c'est juste la valeur qui va varie dnas le temps.
 
Et il faudra du coup modifier le script pour avoir l'acces aux datas ?

n°2223834
clubber43
Posté le 02-04-2014 à 13:59:41  profilanswer
 

Merci,
@+

n°2223836
gilou
Modérateur
Modzilla
Posté le 02-04-2014 à 14:04:26  profilanswer
 

Déjà, comment sais tu que la valeur va être stockée dans les 2 ou 3 mots suivants l'adresse ou tu récupères tes données? Tu as une doc la dessus? ou c'est du pifomètre?
Parce que normalement la taille de la donnée devrait être fixe, et ta requête ne pas varier en fonction de la grandeur du chiffre.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2223838
clubber43
Posté le 02-04-2014 à 14:09:07  profilanswer
 

J'ai la doc sur la table de tous les registres présents dans mon module :
 
http://www.compteur-electrique.ene [...] S_ed01.pdf
 
Ensuite, c'est bien marqué page 19 vers la fin de la page,
+KWH Total . . . . Registre Hexa = 109 . . . . words = 3 . . . . unit 0.1 WH
 
Donc là, c'est certain que mon information est codée sur 3 mots, enfin je pense qu'elle est sur 3 mots, car les valeurs peuvent être grande.
Vu que c'est un compteur electrique.

n°2223839
clubber43
Posté le 02-04-2014 à 14:09:30  profilanswer
 

j'avais pas la doc avant, mais là, je suis sur de mon truc lol
 
merci

n°2223856
gilou
Modérateur
Modzilla
Posté le 02-04-2014 à 14:53:22  profilanswer
 

Dans tous les cas elle est sur trois mots.
Donc actuellement, quand tu fais ta requête, que valent ces 3 mots?
 
On peut supposer que si tu as comme valeurs ($a1, $a2, $a3) X, 0 et 0, alors il faudra convertir en $a1 + ($a2 * 2^16) + ($a3 * 2^32) pour obtenir la valeur
C'est pas documenté dans la doc, mais on peut supposer/espérer qu'ils utilisent des entiers signés sur 64 bits, et q'ils n'en envoient que les trois premiers mots (sinon, fuck them!)
Ce qui donne comme range de valeurs 0-281474976710655 et donc de 0 à 28 147 497 671 065.5 Wh et d'ici qu'un client ait consommé 26 TWh...
On voit bien dans la doc qu'ils sont justement coincés parce que modbus/tcp ne permet pas de faire passer des nombres a décimale alors qu'ils peuvent le faire en modbus/rtu et donc que l'unité doit alors être décimale en TCP, pour compenser
 
 
A+,


Message édité par gilou le 02-04-2014 à 14:54:02

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2223859
clubber43
Posté le 02-04-2014 à 15:00:46  profilanswer
 


Lorsque je fais ma requete, actuellement,  
la console me renvoie <267 = 20542 > alors que normalement, je devrais avoir environ : 2 623 479 WH soit 2623.479KWH consommés.
Attention, car en plus, la consommation est expirmée en 0.1 WH donc il faudra diviser par 10 la valeur trouvée mais sa, c'est pas le souci.
 
Ps:  
Lorsque que vous dites $a1 + ($a2 * 2^16) + ($a3 * 2^32), cela revien à faire ($a1*2^0) + ($a2 * 2^16) + ($a3 * 2^32), pour avoir nos 48 bits ?  
0+16+32 ? non ?

n°2223865
gilou
Modérateur
Modzilla
Posté le 02-04-2014 à 15:10:43  profilanswer
 

> Lorsque je fais ma requete, actuellement,  
> la console me renvoie <267 = 20542 >  
 
Ce que je voudrais, c'est les 3 valeurs que renvoie le programme (avec le code que je vous ai donné pour demander et récupérer 3 valeurs)
 
et oui pour le reste.
 
> la consommation est expirmée en 0.1 WH
C'est ce que je vous ai dit dans ma dernière phrase.  
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2223868
clubber43
Posté le 02-04-2014 à 15:11:39  profilanswer
 

a désolé,  
je refais la manip de suite.

n°2223880
clubber43
Posté le 02-04-2014 à 15:25:12  profilanswer
 

Pour afficher les data, c'est bien comme ça la commande  ? je n'arrive pas a compiler  
 

Code :
  1. # Lecture d'entier de 16 bits
  2. # 3 registres à lire d'ou le nnn
  3.     my ($val1,$val2,$val3) = unpack 'nnn', $rx_read_word_data;
  4.     }
  5.     }
  6. close SERVER;
  7. # fin de la boucle foreach 
  8. # impression en console
  9.   foreach (sort {$a <=> $b} {
  10.   print "\n $val1 : , $val2 : , $val3 : ;\n"  # On utilise un hash pour passer les valeurs et avoir plusieurs valeurs par retour
  11.   #disp_data(%result);
  12. }
  13. print "\n";


 
meri

n°2223886
clubber43
Posté le 02-04-2014 à 15:44:08  profilanswer
 

Voila, ce que j'ai codé, mais il ne compile pas :
 

Code :
  1. #!/usr/bin/perl
  2.   use strict;
  3.   use warnings;
  4.   use Socket;
  5. # Paramètres ModBus/TCP
  6.   my $MODBUS_PORT                                 = 502;
  7. # Codes des fonctions lecture, ecriture, ...
  8.   my $READ_COILS                                  = 0x01;
  9.   my $READ_DISCRETE_INPUTS                        = 0x02;
  10.   my $READ_HOLDING_REGISTERS                      = 0x03;
  11.   my $READ_INPUT_REGISTERS                        = 0x04;
  12.   my $WRITE_SINGLE_COIL                           = 0x05;
  13.   my $WRITE_SINGLE_REGISTER                       = 0x06;
  14. # Codes des exceptions erreurs, ...
  15.   my $EXP_ILLEGAL_FUNCTION                        = 0x01;
  16.   my $EXP_DATA_ADDRESS                            = 0x02;
  17.   my $EXP_DATA_VALUE                              = 0x03;
  18.   my $EXP_SLAVE_DEVICE_FAILURE                    = 0x04;
  19.   my $EXP_ACKNOWLEDGE                             = 0x05;
  20.   my $EXP_SLAVE_DEVICE_BUSY                       = 0x06;
  21.   my $EXP_MEMORY_PARITY_ERROR                     = 0x08;
  22.   my $EXP_GATEWAY_PATH_UNAVAILABLE                = 0x0A;
  23.   my $EXP_GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND = 0x0B;
  24. # Valeurs par défaut
  25.   my $opt_server                                  = 'localhost';
  26.   my $opt_server_port                             = $MODBUS_PORT; #502
  27.   my $opt_timeout                                 = 1;    # temps max de 1 s
  28.   my $opt_unit_id                                 = 1;
  29.   my $opt_mb_ad;
  30.   my $opt_mb_fc                                   = $READ_HOLDING_REGISTERS;
  31.   my $opt_mb_nb                                   = 1;
  32.   my $opt_bit_value                               = 0;
  33.   my $opt_word_value                              = 0;
  34.   $opt_server = '172.17.14.3';       # @ IP du serveur TCP
  35.   my $server_ip = inet_aton($opt_server);      # on donne l'@ IP à la variable
  36.   unless ($server_ip) { 
  37.   print STDERR 'unable to resolve "'.$opt_server.'"'."\n"; # et la, 
  38.   exit 1; 
  39.   } 
  40.   my $status = query_info();
  41.   until ($status) {
  42.   sleep(10);  # toutes les 10s, a adapter à ses besoins
  43.   $status = query_info();
  44.   }
  45. # boucle infinie, a stopper avec un kill
  46. sub query_info{
  47. # Gestion du dialogue reseau
  48. # Ouverture de la session TCP
  49.   socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
  50.   unless (connect(SERVER, sockaddr_in($MODBUS_PORT, $server_ip))) {
  51.     print STDERR 'connexion au serveur "'.$server_ip.':'.$MODBUS_PORT.'" impossible'."\n";
  52.     return 2;
  53.   }
  54.  
  55.   my @adresses = qw (267); #Liste des adresses à interroger puissance P, Q et I
  56.   my %result;
  57. #15 17 19 courant I1àI3 et moyen
  58. #24 25 26 27 coef dephasage par phase et moyen
  59. #267 Puissance
  60. #305 Puissance
  61.   foreach (@adresses) { 
  62.   $opt_mb_ad = $_;     
  63. # Création de la requête 
  64.   my $tx_hd_tr_id   = int(rand 65536);
  65.   my $tx_hd_length  = 6;
  66.   my $tx_hd_pr_id   = 0;
  67.   my $opt_mb_nb = 3;
  68.   my $tx_buffer = pack("nnnCCnn", $tx_hd_tr_id, $tx_hd_pr_id , $tx_hd_length, $opt_unit_id, $opt_mb_fc, $opt_mb_ad, $opt_mb_nb);
  69.  
  70. # Emission de la requête vers le serveur
  71.   send(SERVER, $tx_buffer, 0);
  72.  
  73. # Attente d'une réponse
  74.   unless (can_read('SERVER', $opt_timeout)) {
  75.     close SERVER;
  76.     print STDERR 'receive timeout'."\n"; # erreur si depassement du temps d'attente
  77.     return 1;
  78.   }
  79.  
  80. # Réception de l'entête depuis le serveur
  81.   my ($rx_frame, $rx_buffer);
  82.   recv(SERVER, $rx_buffer, 7, 0);
  83.   $rx_frame = $rx_buffer;
  84.  
  85. # Décodage de l'entête
  86.   my ($rx_hd_tr_id, $rx_hd_pr_id, $rx_hd_length, $rx_hd_unit_id) = unpack "nnnC", $rx_buffer;
  87.  
  88. # Vérifie la cohérence de l'entête
  89.   unless (($rx_hd_tr_id == $tx_hd_tr_id) &&
  90.       ($rx_hd_pr_id == 0) &&
  91.       ($rx_hd_length < 256) &&
  92.       ($rx_hd_unit_id == 1)) {
  93.     close SERVER;
  94.     print STDERR 'error in receive frame'."\n";
  95.     return 1;
  96.   }
  97.  
  98. # Réception du corps du message
  99.   recv(SERVER, $rx_buffer, $rx_hd_length-1, 0);
  100.   $rx_frame .= $rx_buffer;
  101.  
  102.  
  103. # Décodage du corps du message
  104.   my ($rx_bd_fc, $rx_body) = unpack "Ca*", $rx_buffer;
  105.  
  106. # Vérification du statut d'exception
  107.   if ($rx_bd_fc > 0x80) {
  108. # Affichage du code exception
  109.     my ($rx_except_code) = unpack "C", $rx_body;
  110.     print 'exception (code '.$rx_except_code.')'."\n";
  111.   } 
  112.   else {
  113. ## Lecture de mot
  114.     my ($rx_bd_bc, $rx_read_word_data) = unpack "Ca*", $rx_body;
  115. # Lecture d'entier de 16 bits
  116. # 3 registres à lire d'ou le nnn
  117.     my ($val1,$val2,$val3) = unpack 'nnn', $rx_read_word_data;
  118.     }
  119.     }
  120. close SERVER;
  121. # fin de la boucle foreach 
  122. # impression en console
  123.   foreach (sort {$a <=> $b} (keys %result)) {
  124.   print "\n<$_> : $result{$_} ;\n"  # On utilise un hash pour passer les valeurs et avoir plusieurs valeurs par retour
  125.   #disp_data(%result);
  126. }
  127. print "\n";
  128. #attente $timeout
  129.   sub can_read{
  130. my ($sock_handle, $timeout) = @_;
  131. my $hdl_select="";
  132. vec($hdl_select, fileno($sock_handle),1)=1;
  133. return (select($hdl_select, undef, undef, $timeout)==1);
  134. }
  135. my $time = time; 
  136. my @months = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" );
  137. my ($sec, $min, $hour, $day,$month,$year) = (localtime($time))[0,1,2,3,4,5];
  138. print "timestamp : ".$time. " \n";
  139. }


 
merci

n°2223887
gilou
Modérateur
Modzilla
Posté le 02-04-2014 à 15:45:31  profilanswer
 

Vu que c'est juste un one shot, fais plutôt le  
print "\n $val1 : , $val2 : , $val3 : ;\n"
juste après le  
my ($val1,$val2,$val3) = unpack 'nnn', $rx_read_word_data;
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2223888
clubber43
Posté le 02-04-2014 à 15:46:01  profilanswer
 

a ok.
 
sa roule

n°2223889
clubber43
Posté le 02-04-2014 à 15:47:50  profilanswer
 

Valeure retournée :
 
43446, 0, 0 ;

n°2223890
clubber43
Posté le 02-04-2014 à 15:50:01  profilanswer
 

Du coup, sur les 3 mots, seulement le mot 1 à une valeur si j'ai bien tout compris, il faut maintenant la "transformer" pour avoir la bonne valeur de consommation.
 
ju

n°2223893
gilou
Modérateur
Modzilla
Posté le 02-04-2014 à 15:54:30  profilanswer
 

donc ce qu'on récupère correspond à 4344.6 Wh  (c'est ce à quoi tu t'attends?)
Comme les autres sont a 0 pas de pb, mais il faudra coder pour tenir compte des 3 mots (je regarderais cela ce soir histoire de faire du code un peu plus propre)


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2223896
clubber43
Posté le 02-04-2014 à 16:01:19  profilanswer
 

S'a y est, j'ai trouvé le truc,  
j'ai mis le bon champ à exporter (adresse 265) et là, il me retourne 0,401,57644.
 
Si je suis la logique de calcul vu plus haut, je trouve :
0*2^32+401*2^16+57644*2^0 je trouve bien 26337580 ce qui correspond à 2633,758 KWH consommé.
C'est pile poil la valeur à 1KWH près qu'il fallait trouvé.
 
Je continue de cherché un peu sur le script pour essayer de trouver le bon prog et le comprendre.
 
Je dis respect, et Merci en tout cas !!

n°2223899
gilou
Modérateur
Modzilla
Posté le 02-04-2014 à 16:12:16  profilanswer
 

Ah ben j'allais justement te le dire: tu avais fait la mauvaise conversion hexa <--> décimal pour l'adresse, mais tu t'en es aperçu.
 
Comme perl comprends directement les nombres en hexadecimal, tu aurais aussi pu faire:
my @adresses = (265, ...);  (sans qw devant, mais liste séparée par des virgules)
ou
my @adresses = (0x0109, ...); (surtout sans quotes autour, ni qw pour que ça soit pas pris pour une chaine de texte)
 
 
A+,


Message édité par gilou le 02-04-2014 à 16:12:34

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2  3  4  5  6  7

Aller à :
Ajouter une réponse
 

Sujets relatifs
Copier données en ligne par colonneComment génerer un fichier csv à partir d'une base de données?
perl + xml[Perl] Créer un graph RRD avec RRDTool::OO
[Résolu][Perl] XML::DOM Comment avoir une belle indentation?Programmation Java lecture base de données
[VBA-Excel] Comment appeler un fichier pour récupérer des données ?extraction de donnees
Récupération données d'un site PHPRécupérer des données d'un fichier xml
Plus de sujets relatifs à : [Résolu] Export données en perl


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR