Device-Modbus

 view release on metacpan or  search on metacpan

lib/Device/Modbus/Server.pm  view on Meta::CPAN

        $response = Device::Modbus::Exception->new(
            function       => $Device::Modbus::function_for{$code},
            exception_code => 4,
            unit           => $adu->unit
        );
    };

    unless (defined $response) {
        $response = Device::Modbus::Response->new(
            code   => $code,
            values => \@vals
        );
    }
    
    return $response;
}

1;
__END__

=head1 NAME

Device::Modbus::Server - Base class for Device::Modbus server objects

=head1 SYNOPSIS

 #! /usr/bin/env perl
 
 use Device::Modbus::TCP::Server;
 use strict;
 use warnings;
 use v5.10;
 
 {
    package My::Unit;
    our @ISA = ('Device::Modbus::Unit');

    sub init_unit {
        my $unit = shift;

        #                Zone            addr qty   method
        #           -------------------  ---- ---  ---------
        $unit->get('holding_registers',    2,  1,  'get_addr_2');
    }

    sub get_addr_2 {
        my ($unit, $server, $req, $addr, $qty) = @_;
        $server->log(4,"Executed server routine for address 2");
        return 6;
    }
 }
 
 my $server = Device::Modbus::TCP::Server->new(
     log_level => 4,
     log_file  => 'logfile'
 );
 
 my $unit = My::Unit->new(id => 3);
 $server->add_server_unit($unit);
 
 $server->start;


=head1 DESCRIPTION

This document describes functionalities common to both Modbus RTU and Modbus TCP servers. Constructors are documented in L<Device::Modbus::RTU::Server> and L<Device::Modbus::TCP::Server>.

First, we will briefly describe the data model inherent to the protocol. This is the base for building the functionalities that the server will expose. Then, these functionalities need to be attached to the server, which must finally be started.

=head1 THE MODBUS DATA MODEL

The Modbus protocol communicates a client with a I<unit> in a server. A unit may offer functionalities in one to four different zones of different types:

=over

=item * Discrete inputs

=item * Discrete outputs (or coils)

=item * Input registers

=item * Holding registers

=back

Client requests are sent to a particular server unit, and they specify the data zone they are directed to, the address which will be affected, and the number of data points they refer to. Write requests include also the transmitted values.

=head1 DEFINING A UNIT

In Device::Modbus, a unit is represented by an object which inherits from Device::Modbus::Unit. Each object maps requests to exposed functions. To execute a function, a request must match its address zone, its set of valid addresses, and the quantity...

To define a unit, you must start with a class that inherits from Device::Modbus::Unit. This class must implement a method called C<init_unit>, which is responsible of defining the mapping to the exposed class methods.

Requests may either I<get> data from the server or they may I<put> data into the server. C<get> and C<put> are the methods used to define the mapping to the functionality exposed by the server. Both methods receive the same arguments: a zone, an addr...

I think the best explanation is an example:

 package My::Unit;
 use parent 'Device::Modbus::Unit';
 
 sub init_unit {
     my $unit = shift;
 
     #                Zone            addr qty   method
     #           -------------------  ---- ---  ---------
     $unit->get('holding_registers',    2,  1,  'get_some_data');
     $unit->put('holding_registers',    0,  1,  'save_some_data');
 }

Here, C<init_unit> exposes two methods from C<My::Unit>. C<get_some_data> reacts only to reading requests; C<save_some_data>, to writing requests. They both act on the C<holding_registers> zone. C<get_some_data> will be executed only for requests for...

Let's go over the different arguments for C<get> and C<put>. The zones that you can use are:

=over

=item discrete_coils

Readable and writable; bit-addressable

=item discrete_inputs

Readable only; bit-addressable

=item input_registers

Readable only; register-addressable

=item holding_registers

Readable and writable; register-addressable

=back

Addresses must be between 0 and 65536. However, they can be defined in any of the following ways:

=over

=item - Using a fixed number

=item - Using two numbers separated by a hyphen to define a range

=item - Using a list of comma-separated numbers or ranges

=item - Using an asterisk. The given method responds to all addresses

=back

The next argument, the quantity of data that the class method may receive or return, is defined using the same rules as addresses.

Finally, you can either use the name of a class method, or a code reference to define the functionality exposed by the unit.

These are more examples:

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.477 second using v1.00-cache-2.02-grep-82fe00e-cpan-2c419f77a38b )