Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!perl -w
- use 5.10.0;
- ##
- ## Loading local modules
- BEGIN {
- use File::Basename;
- use Cwd qw/abs_path/;
- my $basePath = dirname abs_path $0;
- push @INC,
- $basePath.'/lib',
- }
- use utf8;
- use Getopt::Long;
- use POSIX;
- use Try::Tiny;
- use Device::Modbus;
- use Device::Modbus::RTU::Client;
- use Device::Modbus::TCP::Client;
- use JSON qw | to_json encode_json|;
- use DBI;
- use DBD::mysql;
- use YAML::Tiny;
- ##
- ## Self Modules
- use Hazel::Db qw|initDB|;
- ##
- ## Load config file
- my $configFilename = 'default_config.yaml';
- my $yaml = YAML::Tiny->read($configFilename);
- my $config = $yaml->[0];
- my $dbConfig = $yaml->[1];
- ##
- ## Data Structure
- my %dataStructure = (
- -configFilename => 'default_config.yaml',
- -collectInterval => 5,
- -portType => 'TCP',
- -ipAddress => $config->{tcp}->{ipAddress},
- -rtuRelatedPort => $config->{rtu}->{rtuRelatedPort}, #default
- -baudrate => $config->{rtu}->{baudrate},
- -parity => $config->{rtu}->{parity},
- -help => '',
- -install => '',
- -verbose => 0,
- -DB => {
- -db_name => $dbConfig->{database}->{db_name},
- -host => $dbConfig->{database}->{host},
- -port => $dbConfig->{database}->{port},
- -user => $dbConfig->{database}->{user},
- -passwd => $dbConfig->{database}->{passwd},
- },
- );
- ##
- ## Populate essential vars from cli
- GetOptions(
- "ptype=s" => \$dataStructure{-portType},
- "ip=s" => \$dataStructure{-ipAddress},
- "collectInterval=i" => \$dataStructure{-interval},
- "port=s" => \$dataStructure{-rtuRelatedPort},
- "help" => \$dataStructure{-help},
- "install" => \$dataStructure{-install},
- "verbose" => \$dataStructure{-verbose},
- "conf=s" => \$dataStructure{-configFilename},
- );
- ##
- ## configuration routines
- install() if ($dataStructure{-install} ne '');
- die(<DATA>) if ($dataStructure{-help} ne '');
- print 'Initializing database interface...',"\n" if $dataStructure{-verbose};
- my $dbConnection = initDB(%dataStructure);
- print 'Local database ready!', "\n" if $dataStructure{-verbose};
- ##
- ## Magic goes here
- print 'Initializing reading...', "\n" if $dataStructure{-verbose};
- $yaml = YAML::Tiny->read($dataStructure{-configFilename});
- my $registers = $yaml->[2]->{'readings'};
- my $numberOfRegisters = keys %{$registers};
- while(1)
- {
- { # Request scope
- my %response;
- try { for (my $i = 0; $i <= $numberOfRegisters -1; $i++) {
- ##
- ## Define the instance type accordingly with [ptype]
- my $clientBus = (sub(){
- my $client;
- ##
- ## RTU Modbus object instance
- if ($dataStructure{-portType} eq 'rtu') {
- $client = Device::Modbus::RTU::Client->new(
- port => $dataStructure{-rtuRelatedPort},
- baudrate => $dataStructure{-baudrate},
- parity => $dataStructure{-parity},
- );
- }
- ##
- ## TCP Modbus object instance
- if ($dataStructure{-portType} eq 'tcp') {
- $client = Device::Modbus::TCP::Client->new(
- host => $dataStructure{-ipAddress},
- );
- }
- return $client;
- })->();
- ##
- ## mounting request based in conf file
- my %request = (
- unit => $registers->{$i}->{unit},
- address => $registers->{$i}->{address},
- quantity => $registers->{$i}->{quantity},
- );
- my $readings;
- if ($registers->{$i}->{function} eq 'read_coils') {
- $request = $clientBus->read_coils(%request);
- } elsif ($registers->{$i}->{function} eq 'read_holding_registers') {
- $request = $clientBus->read_holding_registers(%request);
- }
- print 'Mounting request: ', join "\t", %request, "\n" if $dataStructure{-verbose};
- print 'Sending request...' if $dataStructure{-verbose};
- $clientBus->send_request($request);
- $response{$i} = $clientBus->receive_response and $clientBus->disconnect;
- print 'Request done!!', "\n\n" if defined $response{$i};
- my %readings = (
- station_id => $config->{station_id},
- id => $response{$i}->{id},
- register => $registers->{$i}->{address},
- value => $response{$i}->{message}->{values}[0],
- zone => $response{$i}->{message}->{function},
- code => $response{$i}->{message}->{code},
- created_at => strftime("%Y-%m-%d %H:%M:%S", localtime(time)),
- );
- $readings{data} = encode_json \%readings;
- $dbConnection->do("INSERT INTO data_readings (station_id, data, created_at) VALUES ($readings{station_id},'$readings{data}','$readings{created_at}')");
- }}
- catch
- {
- print 'Error:: error while sending request to device: ', $!, "\n";
- }
- } #EOS
- sleep $dataStructure{-collectInterval};
- }
- ## Functions below ##
- ##
- ## Installation routine
- sub install {
- `echo "alias collector='\$PWD/collector.pl \$\@'" >> ~/.bashrc`;
- exit;
- }
- __DATA__
- ############################################################################################################
- ######################################## Collertor Script ##################################################
- Usage:
- [perl] collector[.pl] --ptype=[tcp||rtu] (--port=/dev/ttyUSB0 ||--ip=127.0.0.1) --collectInterval=1
- --ptype Set the port type to use, it can hold the 'rtu' and 'tcp' values
- If 'tcp' value is settled, the parameter --ip turns out to be obligatory
- --port Define the linux device port, the default value if not specified is: /dev/ttyUSB0
- --ip Define the ipv4 address of the master CLP to connect
- --collecInterval Define interval between requests for the given connection.
- if not defined assume interval equals 1s
- --pipe Point its value to the filename of the pipe who will hold the data structure
- --install Install the Perl script as an alias using his own filename.
- --verbose Enable verbosity
- ############################################################################################################
- ############################################################################################################
Add Comment
Please, Sign In to add comment