Export vers Bdd

Fermé
clubber43 Messages postés 6 Date d'inscription mardi 11 mars 2014 Statut Membre Dernière intervention 11 mars 2014 - 11 mars 2014 à 11:33
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 - 14 mars 2014 à 11:27
Bonjour,
je suis nouveau sur ce forum, et je debute aussi en PERL.

Pour les besoins d'un projet , je dois exporter des valeurs depuis un compteur electrique et les inscrire dans une base de donneés sous un serveur. Le problème, c'est que je ne vois pas trop par quel bout y aller. J'ai deja commence à code un script qui va lire les données dans le compteur et maintenant, je m'attaque à la partie SQL/PERL. J'ai lu ici et ailleurs, qu'il fallait utiliser le module DBI, mais apres cela . . . c'est le trou noir.

Si quelqu'un peut me donner un coup de main (ou un bout de code ^^)

Je deposerais mon travail, tel qu'il est aujourd'hui.

Je vous remercie tous!

ju

6 réponses

clubber43 Messages postés 6 Date d'inscription mardi 11 mars 2014 Statut Membre Dernière intervention 11 mars 2014
11 mars 2014 à 11:35
Voila deja, le script qui va lire les datas dans le compteurs :

#!/usr/bin/perl

use strict;
use warnings;
use Socket;

# Paramètres ModBus/TCP
my $MODBUS_PORT = 502;

# Codes des fonctions lecture, ecriture, ...
my $READ_COILS = 0x01;
my $READ_DISCRETE_INPUTS = 0x02;
my $READ_HOLDING_REGISTERS = 0x03;
my $READ_INPUT_REGISTERS = 0x04;
my $WRITE_SINGLE_COIL = 0x05;
my $WRITE_SINGLE_REGISTER = 0x06;

# Codes des exceptions erreurs, ...
my $EXP_ILLEGAL_FUNCTION = 0x01;
my $EXP_DATA_ADDRESS = 0x02;
my $EXP_DATA_VALUE = 0x03;
my $EXP_SLAVE_DEVICE_FAILURE = 0x04;
my $EXP_ACKNOWLEDGE = 0x05;
my $EXP_SLAVE_DEVICE_BUSY = 0x06;
my $EXP_MEMORY_PARITY_ERROR = 0x08;
my $EXP_GATEWAY_PATH_UNAVAILABLE = 0x0A;
my $EXP_GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND = 0x0B;

# Valeurs par défaut
my $opt_server = 'localhost';
my $opt_server_port = $MODBUS_PORT; #502
my $opt_timeout = 1; # temps max de 1 s
my $opt_unit_id = 1;
my $opt_mb_ad;
my $opt_mb_fc = $READ_HOLDING_REGISTERS;
my $opt_mb_nb = 1;
my $opt_bit_value = 0;
my $opt_word_value = 0;




$opt_server = '192.168.1.253'; # @ IP du serveur TCP
my $server_ip = inet_aton($opt_server); # on donne l'@ IP à la variable
unless ($server_ip) {
print STDERR 'unable to resolve "'.$opt_server.'"'."\n"; # et la,
exit 1;
}

my $status = query_info();
until ($status) {
sleep(1); # toutes les 1s, a adapter à ses besoins
$status = query_info();
}
# boucle infinie, a stopper avec un kill



sub query_info {

# Gestion du dialogue reseau
# Ouverture de la session TCP

socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
unless (connect(SERVER, sockaddr_in($MODBUS_PORT, $server_ip))) {
print STDERR 'connexion au serveur "'.$server_ip.':'.$MODBUS_PORT.'" impossible'."\n";
return 2;
}

my @adresses = qw(267 305 15); #Liste des adresses à interroger puissance P, Q et I
my %result;

foreach (@adresses) {
$opt_mb_ad = $_;
# Création de la requête
my $tx_hd_tr_id = int(rand 65535);
my $tx_hd_length = 6;
my $tx_hd_pr_id = 0;
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);

# Emission de la requête vers le serveur
send(SERVER, $tx_buffer, 0);

# Attente d'une réponse
unless (can_read('SERVER', $opt_timeout)) {
close SERVER;
print STDERR 'receive timeout'."\n"; # erreur si depassement du temps d'attente
return 1;
}

# Réception de l'entête depuis le serveur
my ($rx_frame, $rx_buffer);
recv(SERVER, $rx_buffer, 7, 0);
$rx_frame = $rx_buffer;

# Décodage de l'entête
my ($rx_hd_tr_id, $rx_hd_pr_id, $rx_hd_length, $rx_hd_unit_id) = unpack "nnnC", $rx_buffer;

# Vérifie la cohérence de l'entête
unless (($rx_hd_tr_id == $tx_hd_tr_id) &&
($rx_hd_pr_id == 0) &&
($rx_hd_length < 256) &&
($rx_hd_unit_id == 1)) {
close SERVER;
print STDERR 'error in receive frame'."\n";
return 1;
}

# Réception du corps du message
recv(SERVER, $rx_buffer, $rx_hd_length-1, 0);
$rx_frame .= $rx_buffer;


# Décodage du corps du message
my ($rx_bd_fc, $rx_body) = unpack "Ca*", $rx_buffer;

# Vérification du statut d'exception
if ($rx_bd_fc > 0x80) {

# Affichage du code exception
my ($rx_except_code) = unpack "C", $rx_body;
print 'exception (code '.$rx_except_code.')'."\n";
}

else {

## Lecture de mot
my ($rx_bd_bc, $rx_read_word_data) = unpack "Ca*", $rx_body;

# Lecture d'entier de 16 bits
# un seul registre a lire d'ou le 'n'
$result{$opt_mb_ad} = unpack 'n', $rx_read_word_data;
}
}
close SERVER;
# fin de la boucle foreach
# impression en console

foreach (sort {$a <=> $b} (keys %result)) {
print "<$_> : $result{$_};" # On utilise un hash pour passer les valeurs et avoir plusieurs valeurs par retour
#disp_data(%result);
}
print "\n";


#attente $timeout
sub can_read{
my ($sock_handle, $timeout) = @_;
my $hdl_select="";
vec($hdl_select, fileno($sock_handle),1)=1;
return (select($hdl_select, undef, undef, $timeout)==1);
}

#utilisation du timestamp pour avoir l'heure réseau
my $time = time;
my @months = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
my ($sec, $min, $hour, $day,$month,$year) = (localtime($time))[0,1,2,3,4,5];

print "Unix time ".$time." converts to ".$months[$month]." ".$day.", ".($year+1900);print " ".$hour.":".$min.":".$sec."\n";


}

J'ai aussi utilisé pour les besoins du programme, la variable timestamp pour avoir le temps et l'heure des extractions.
0
clubber43 Messages postés 6 Date d'inscription mardi 11 mars 2014 Statut Membre Dernière intervention 11 mars 2014
11 mars 2014 à 11:37
Et le script qui créé la BDD, mais il ne marche pas :
erreur suivantes :

Malformed UTF-8 line 149,19,24,24,27.

#!/usr/bin/perl
use warnings;
use strict;
use Encode;
use utf8;
use DBI; # Charger le module DBI
use vars qw/ $VERSION /; # version script

ActiverAccents();

# Paramètres de connection à la base de données
my $bd = 'energie';
my $serveur = 'localhost'; # @ IP
my $identifiant = 'root'; # identifiant
my $motdepasse = 'admin';
my $port = ''; #Si vous ne savez pas, ne rien mettre

# Connection à la base de données mysql
print "Connexion à la base de données $bd\n";
my $dbh = DBI->connect( "DBI:mysql:database=$bd;host=$serveur;port=$port",
$identifiant, $motdepasse, {
RaiseError => 1,
}
) or die "Connection impossible à la base de données $bd !\n $! \n $@\n$DBI::errstr";

# Création des tables
print "Création de la table energie\n";
my $sql_creation_table_energie = <<"SQL";
CREATE TABLE Regions (
id_compteur VARCHAR (10) NOT NULL ,
puissance_p INT NOT NULL ,
puissance_q INT NOT NULL ,
courant_In INT NOT NULL ,
PRIMARY KEY ( id_compteur )
) COMMENT = 'base compteur';
SQL

$dbh->do('DROP TABLE IF EXISTS energie;') or die "Impossible de supprimer la table energie\n\n";
$dbh->do($sql_creation_table_energie) or die "Impossible de créer la table energie\n\n";

print "Création de la table releves\n";
my $sql_creation_table_releves = <<"SQL";
CREATE TABLE releves(
id_compteur VARCHAR (10) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'Elle sera générée automatiquement.',
time TIMESTAMP NOT NULL,
) COMMENT = 'Releves';
SQL

$dbh->do('DROP TABLE IF EXISTS releves;') or die "Impossible de supprimer la table releves\n\n";
$dbh->do($sql_creation_table_releves) or die "Impossible de créer la table releves\n\n";


# Lecture des fichiers et insertion des données
#my $fichier_compteur = 'c:/reg2013.txt';
#my $fichier_releves = 'c:/releves.txt';


# Fichier Region
print "Insertion des données dans la table releves\n";
open my $fh_releves, '<:encoding(UTF-8)', $fichier_releves or die "Impossible de lire le fichier $fichier_regions\n";
my $entete_fichier_releves = <$fh_releves>;

################# a mettre en forme####################
# Insertion des données
my $requete_sql_releves = <<"SQL";
INSERT INTO regions ( id_compteur, puissance_p, puissance_q, courant_in, time)
VALUES ( ?, ?, ?, ?, ? ); #
SQL

my $sth_releves = $dbh->prepare($requete_sql_releves);

while ( my $ligne = <$fh_releves> ) {
chomp $ligne;
my ( $id_compteur, puissance_p, puissance_q, courant_in, time) ) = split /\t/, $ligne;
$sth_releves->execute( $id_compteur, puissance_p, puissance_q, courant_in, time)
or die "Echec Requête $requete_sql_releves : $DBI::errstr";
}
close $fh_releves;



# Déconnection de la base de données
$dbh->disconnect();


sub ActiverAccents {
my $encodage;
# Windows
if ( lc($^O ) eq 'mswin32') {
eval {
my ($codepage) = ( 'chcp' =~ m/:\s+(\d+)/ );
$encodage = "cp$codepage";
foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) {
binmode $h, ":encoding($encodage)";
}
};
}
else {
$encodage = 'locale charmap';
eval {
foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) {
binmode $h, ":encoding($encodage)";
}
};
}
return $encodage;
}



Si quelqu'un passe par mon post,

Merci

ju
0
clubber43 Messages postés 6 Date d'inscription mardi 11 mars 2014 Statut Membre Dernière intervention 11 mars 2014
11 mars 2014 à 11:37
.
0
ange cristel Messages postés 1 Date d'inscription mardi 11 mars 2014 Statut Membre Dernière intervention 11 mars 2014
11 mars 2014 à 11:42
Bonjours moi c'est ange cristelle je suis nouvelle sur le site mais je contre bien vous aide
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
clubber43 Messages postés 6 Date d'inscription mardi 11 mars 2014 Statut Membre Dernière intervention 11 mars 2014
11 mars 2014 à 11:43
C'est sympa,
Je chrche en même temps et je posterais mon nouveau code, si j'avance de mon coté ^^

Merci
0
clubber43 Messages postés 6 Date d'inscription mardi 11 mars 2014 Statut Membre Dernière intervention 11 mars 2014
11 mars 2014 à 14:32
Nouveau code après modif,
j'ai encore des erreurs :

- malformed UTF-8 0x20 at line 19 19 24 24 27,
- cant find string terminator.


#!/usr/bin/perl
use warnings;
use strict;
use Encode;
use utf8;
use DBI; # Charger le module DBI


ActiverAccents();

# Paramètres de connection à la base de données
my $bd = 'Energie';
my $serveur = 'localhost'; # @ IP IP
my $identifiant = 'root'; # identifiant
my $motdepasse = 'admin';
my $port = ''; #Si vous ne savez pas, ne rien mettre

# Connection à la base de données mysql
print "Connexion à la base de données $bd\n";
my $dbh = DBI->connect( "DBI:mysql:database=$bd;host=$serveur;port=$port",
$identifiant, $motdepasse, {
RaiseError => 1,
}
) or die "Connection impossible à la base de données $bd !\n $! \n $@\n$DBI::errstr";

# Création des tables
print "Création de la table COMPTEUR\n";
my $sql_creation_table_compteur = <<"SQL";
id_compteur INT NOT NULL ,
emplacement VARCHAR( 10 ) NOT NULL ,
batiment VARCHAR( 10 ) NOT NULL ,
niveau VARCHAR( 10 ) NOT NULL ,
PRIMARY KEY ( id_compteur )
) COMMENT = 'COMPTEUR';
SQL

$dbh->do('DROP TABLE IF EXISTS compteur;') or die "Impossible de supprimer la table compteur\n\n";
$dbh->do($sql_creation_table_compteur) or die "Impossible de créer la table compteur\n\n";

print "Création de la table Releves\n";
my $sql_creation_table_releves = <<"SQL";
CREATE TABLE releves (
id_compteur INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'Elle sera générée automatiquement.',
puissance_p INT NOT NULL ,
puissance_q INT NOT NULL ,
courant_I INT NOT NULL ,
) COMMENT = 'COMPTEUR';
SQL

$dbh->do('DROP TABLE IF EXISTS releves;') or die "Impossible de supprimer la table releves\n\n";
$dbh->do($sql_creation_table_releves) or die "Impossible de créer la table releves\n\n";


# Insertion des données
my $requete_sql_compteur = <<"SQL";
INSERT INTO rcompteur ( id_compteur, emplacement, batiment, niveau)
VALUES ( 1, TDD1, D, 1);
SQL

close $fh_regions;


# Déconnection de la base de données
$dbh->disconnect();


sub ActiverAccents {
my $encodage;
# Windows
if ( lc($^O ) eq 'mswin32') {
eval {
my ($codepage) = ( 'chcp' =~ m/:\s+(\d+)/ );
$encodage = "cp$codepage";
foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) {
binmode $h, ":encoding($encodage)";
}
};
}
else {
$encodage = 'locale charmap';
eval {
foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) {
binmode $h, ":encoding($encodage)";
}
};
}
return $encodage;
}

Si quelqu'u n peut m'aider un peu . . . ^^

Merci

@+
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié par [Dal] le 13/03/2014 à 19:49
Salut clubber43,

Tu fais un
use utf8;
indiquant à Perl que ton script contient des caractères écrits en utf8, mais il semble que cela ne soit pas le cas si tu as en ligne 19 un message "malformed UTF-8 0x20" et que tu aies à cet endroit un caractère qui n'est pas légalement encodé en utf8.

Si ton texte n'est pas en utf8, convertis le en utf8 (ou retire cette directive, si elle ne reflète pas la réalité et que ton script n'est pas en utf8).

Une remarque, stp, cela ne sert à rien de poster un code de 88 lignes alors que le message d'erreur te permet de cerner les lignes problématiques et de diagnostiquer ton problème en le réduisant à une poignée de lignes. En faisant cela, tu avances toi même aussi dans la résolution du problème, tu incites d'avantage les contributeurs du forum à t'aider, et tu te montres plus respectueux à leur égard en limitant autant que tu le peux le temps nécessaire à la compréhension de ton problème.

De plus, pour la lisibilité de ton code, s'il te plaît utilises les balises "code", comme cela


<code perl>
  print "Hello world!\n";
</code>

Dal
0
Ok, c'est sympa, je ne savais pas comment faire, du coup pour la prochaine fois, je ferais ça.

Merci pour le coup de main
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
14 mars 2014 à 11:27
De rien :-)

Le bouton "code" qui permet d'insérer les balises selon le langage est dans l'éditeur du forum, mais il est vrai qu'il est peu explicite. Il faut cliquer sur le triangle avec la pointe vers le bas, à droite de l'icône <> et sélectionner le langage pour lequel tu postes.


Dal
0