The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Net::PJLink - PJLink protocol implementation

VERSION

Version 1.03

SYNOPSIS

Net::PJLink is a pure perl implementation of the PJLink protocol (http://pjlink.jbmia.or.jp/english/) version 1.00, Class 1. This is a standard protocol for communicating with network-capable projectors. Net::PJLink uses an object-oriented style, with an object representing a group of one or more projectors. An object has methods corresponding to the commands in the PJLink protocol specification.

        use Net::PJLink;

        my $prj = Net::PJLink->new(
                host       => [ '10.0.0.1', '10.0.0.2' ],
                keep_alive => 1,
        );

        $prj->set_power(1); # turn on projectors

        $prj->set_audio_mute(1); # mute sound

        # retreive the current input being used
        my $input = $prj->get_input();
        if ($input->{'10.0.0.1'}->[0] == Net::PJLink::INPUT_RGB) {
                print "RGB input number " . $input->{'10.0.0.1'}->[1];
                print " is active on projector 1.";
        }

        # close network connections to the projectors
        $prj->close_all_connections;

EXPORTS

Net::PJLink uses constants to represent status codes sent to and received from projectors. These constants can be used like Net::PJLink::ERR_COMMAND, or imported into the local namespace by using the Exporter tag :RESPONSES.

        use Net::PJLink qw( :RESPONSES );

        my $prj = Net::PJLink->new(
                host => '192.168.1.10'
        );
        if ($prj->get_power() == POWER_ON) {
                print "Projector is on.";
        }

The two lists below describe each symbol that is exported by the :RESPONSES tag.

Command Response Constants

These are general status codes that are common to many projector commands.

  • OK

    The command succeeded.

  • WARNING

    Status is "warning".

  • ERROR

    Status is "error".

  • ERR_COMMAND

    The command could not be recognized or is not supported by the projector. This could happen because the projector is deviating from the specification, the message is getting corrupted, or there is a bug in this module.

  • ERR_PARAMETER

    An invalid parameter was given in the command.

  • ERR_UNAVL_TIME

    The command is not available at this time (e.g. projector is on standby, warming up, etc.).

  • ERR_PRJT_FAIL

    A projector failure occurred when processing the command.

  • ERR_NETWORK

    A network connection to the projector could not be established.

  • ERR_AUTH

    Authentication failed.

  • ERR_TIMEOUT

    A response from the projector was not received.

  • ERR_PARSE

    The projector's response was received, but could not be understood. This could happen because the projector is deviating from the specification, the message is getting corrupted, or there is a bug in this module.

Status Responses

These values are returned from commands that request information from the projector. See the documentation for each command to find out which values can be returned for that command.

  • POWER_OFF

  • POWER_ON

  • POWER_COOLING

  • POWER_WARMUP

  • INPUT_RGB

  • INPUT_VIDEO

  • INPUT_DIGITAL

  • INPUT_STORAGE

  • INPUT_NETWORK

  • MUTE_VIDEO

  • MUTE_AUDIO

UTILITY METHODS

new(...)

        use Net::PJLink;

        # Send commands to two hosts (batch mode),
        # don't close the connection after each command,
        # if a host cannot be contacted then remove it,
        # wait up to 1 second for a connection to be opened
        my $prj = Net::PJLink->new(
                host            => ['10.0.0.1', '10.0.0.2'],
                try_once        => 1,
                keep_alive      => 1,
                connect_timeout => 1.0,
        );

Constructor for a new PJLink object. It requires at least the host option to indicate where commands should be sent. The full list of arguments:

  • host

    This can be either a string consisting of a hostname or an IP address, or an array of such strings. If you want to add a whole subnet, use something like Net::CIDR::Set to expand CIDR notation to an array of IP addresses. Every command given to this object will be applied to all hosts, and replies will be returned in a hash indexed by hostname or IP address if more than one host was given.

  • try_once

    True/False. Default is false. Automatically remove unresponsive hosts from the list of hosts. This speeds up any subseqent commands that are issued by not waiting for network timeout on a host that is down. If this option evaluates false, the list of hosts will never be automatically changed.

  • batch

    True/False. Force "batch mode" to be enabled or disabled. Batch mode is normally set automatically based on whether multiple hosts are being used. With batch mode on, all results will be returned as a hash reference indexed by hostname or IP address. If batch mode is disabled when commands are sent to multiple hosts, only one of the hosts' results will be returned (which one is unpredictable).

  • port

    Default is 4352, which is the standard PJLink port. Connections will be made to this port on each host.

  • auth_password

    Set the password that will be used for authentication for those hosts that require it. It must be 32 alphanumeric characters or less. The password is not transmitted over the network; it is used to calculate an MD5 sum.

  • keep_alive

    True/False. Default is false. If set, connections will not be closed automatically after a response is received. This is useful when sending many commands.

  • connect_timeout

    The time (in seconds) to wait for a new TCP connection to be established. Default is 0.5. This may need to be changed, depending on your network and/or projector. The default should provide good reliability, and be practical for a small number of projectors. Using a value of 0.05 seems to work well for connecting to a large number of hosts over a fast network in a reasonable amount of time. (Larger values can take a long time when connecting to each host in a /24 subnet.)

  • receive_timeout

    The time (in seconds) to wait for a reply to be received. If this option is not specified, a default of 5 seconds is used. The value needed here might vary greatly between different projector models.

set_auth_password($pass)

Set the password that will be used when connecting to a projector. This will only apply to newly established connections.

        $prj->set_auth_password('secret');

Returns 1 if successful, 0 otherwise (password is too long).

close_connection($host)

Manually close the connection to one host, specified by hostname or IP address. Returns 1 if the connection was found and closed, returns 0 otherwise.

close_all_connections()

Manually close all open connections that are managed by this instance. This is usually used when the object has been created with the keep_alive option.

add_hosts($host1, ...)

Takes arguments of the same form as the host option to the new constructor. These hosts will be appended to the list of hosts that commands will be sent to. Batch mode is enabled if appropriate.

remove_hosts($host1, ...)

Takes arguments of the same form as the host option to the new constructor. These hosts will be removed from the list of hosts that commands will be sent to. Batch mode is not changed by this function in order to avoid a surprise change in output format.

PROJECTOR COMMAND METHODS

These methods are all frontends for projector commands; calling them will issue the corresponding command immediately. The actual return value of these functions depends on whether batch mode is enabled (it is automatically enabled when more than one host has been added). If enabled, the return value of these functions will always be a hash reference, with the keys being hostnames or IP addresses and the values being the response received from that host. To illustrate:

        $prj = Net::PJLink->new(host => '10.0.0.1');

        $prj->set_power(1);
        # => 0

        $prj->add_hosts('10.0.0.2');

        $prj->set_power(1);
        # => { '10.0.0.1' => 0, '10.0.0.2' => 0 }

The return values described below for each method are the return values for each host.

set_power($state)

Turn power on or off. If the single argument is true, turn on; if argument is false, turn off. Returns one of OK, ERR_PARAMETER, ERR_UNAVL_TIME, ERR_PRJT_FAIL.

get_power()

Get the power status. Returns one of POWER_OFF, POWER_ON, POWER_COOLING, POWER_WARMUP, ERR_UNAVL_TIME, or ERR_PRJT_FAIL.

set_input($input_type, $number)

Set the active input. The first argument is the input type, which can be specified using one of the provided values:

  • INPUT_RGB

  • INPUT_VIDEO

  • INPUT_DIGITAL

  • INPUT_STORAGE

  • INPUT_NETWORK

The second argument specifies which of the inputs of that type should be used. For example, to use the second video input:

        $prj->set_input(Net::PJLink::INPUT_VIDEO, 2);

See the get_input_list() method for information on available inputs. Returns one of OK, ERR_PARAMETER, ERR_UNAVL_TIME, or ERR_PRJT_FAIL.

get_input()

Get the current active input. An array reference is returned, with the first value being the input type and the second value indicating which input of that type. Example:

        $prj->get_input();
        # => [ 3, 1 ]

The example response indicates that the first INPUT_DIGITAL source is active.

set_audio_mute($state)

Set audio mute on or off. Returns one of OK, ERR_PARAMETER, ERR_UNAVL_TIME, or ERR_PRJT_FAIL.

set_video_mute($state)

Set video mute on or off. Returns one of OK, ERR_PARAMETER, ERR_UNAVL_TIME, or ERR_PRJT_FAIL.

get_av_mute()

Get the current status of audio and video mute. An array reference is returned, with the first value being audio mute and the second being video mute. If the command failed, ERR_UNAVL_TIME or ERR_PRJT_FAIL may be returned.

get_status()

Get the health status of various parts of the projector. A hash reference is returned, with the keys being the name of the part.

        $prj->get_status();
        # => {
        #       'fan'   => 0,
        #       'lamp'  => 0,
        #       'temp'  => 0,
        #       'cover' => 0,
        #       'filter'=> -7,
        #       'other' => 0,
        # }

The example response indicates that the projector's filter is in a WARNING state, and all other areas are OK.

The values will be one of OK, WARNING, or ERROR.

Example for finding lamp health from multiple projectors:

        my $prj = Net::PJLink->new(
                host => [ '192.168.1.1', '192.168.1.2' ],
        );

        my $result = $prj->get_status();
        while (my($host, $status) = each %$result) {
                my $lamp = $status->{'lamp'};
                print "The projector at $host has lamp status: ";
                print $lamp == OK ? "ok\n" :
                      $lamp == WARNING ? "warning\n" :
                      $lamp == ERROR ? "error\n";
        }

get_lamp_info()

Get the status and hours used for each lamp. The return value is a data structure like:

        [
                [ $status, $hours ],
                ... # each lamp
        ]

For consistency, this structure is used even if the projector only has one lamp.

$status indicates whether the lamp is on or off (1 or 0). $hours is an integer indicating the total number of hours the lamp has been on. If the command was not successful, ERR_UNAVL_TIME or ERR_PRJT_FAIL may be returned.

get_input_list()

Get a list of all available inputs. The return value is a data structure like:

        [
                [ $type, $index ],
                ... # each input
        ]

$type corresponds to one of the five input types:

  • INPUT_RGB

  • INPUT_VIDEO

  • INPUT_DIGITAL

  • INPUT_STORAGE

  • INPUT_NETWORK

$index is the number of that type (i.e. [3, 3] indicates the third digital input). If the command was not successful, ERR_UNAVL_TIME or ERR_PRJT_FAIL may be returned.

get_name()

Get the projector name. Returns a string. If the command was not successful, ERR_UNAVL_TIME or ERR_PRJT_FAIL may be returned.

get_manufacturer()

Get the manufacturer name. Returns a string. If the command was not successful, ERR_UNAVL_TIME or ERR_PRJT_FAIL may be returned.

get_product_name()

Get the product name. Returns a string. If the command was not successful, ERR_UNAVL_TIME or ERR_PRJT_FAIL may be returned.

get_product_info()

Get "other information". Returns a string. If the command was not successful, ERR_UNAVL_TIME or ERR_PRJT_FAIL may be returned.

get_class()

Get information on supported PJLink Class. Returns a single digit. For example, returning "2" indicates that the projector is compatible with the PJLink Class 2 protocol. The PJLink v.1.00 Class 1 specification only defines return values "1" and "2". If the command was not successful, ERR_UNAVL_TIME or ERR_PRJT_FAIL may be returned.

AUTHOR

Kyle Emmons, <kemmons at tma-0.net>

BUGS

This module has only been tested on Panasonic PTFW100NTU projectors.

The code for opening network connections may not work reliably for a large (~200) number of hosts. This is due to network connections timing out before all hosts have been contacted. If you encounter this problem, adjusting the connect_timeout and receive_timeout arguments may help.

Please report any bugs or feature requests to bug-net-pjlink at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Net-PJLink. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Net::PJLink

You can also look for information at:

LICENSE AND COPYRIGHT

Copyright 2017 Kyle Emmons.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.

The PJLink name is a trademark of Japan Business Machine and Information System Industries Association (JBMIA).