⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 x8561.htm

📁 Its a xmpp protocol book
💻 HTM
📖 第 1 页 / 共 4 页
字号:

use constant SENSOR   => defined($opts{'s'}) ? $opts{'s'} : 0;
use constant GRAIN    =&#62; 1;&#13;</PRE
></P
><P
>The last part of the script's setup deals with the coffee state:</P
><P
><PRE
CLASS="SCREEN"
>my $current_status = -1;
my @status;
$status[NOCOFFEE] = 'xa/coffeepot is empty';
$status[COFFEE]   = '/coffee is available!';&#13;</PRE
></P
><P
>We use a two-element array <TT
CLASS="LITERAL"
>@status</TT
> to represent the
two possible coffee states. The value of each array element is a two-part
string, each part separated by a slash ("/"). Each of these parts will
be transmitted in a <TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
> element,
where the first part (which is empty in the element representing the
<TT
CLASS="LITERAL"
>COFFEE</TT
> state) will represent the presence 
<TT
CLASS="LITERAL"
>&#60;show/&#62;</TT
> value, and the second part
will represent the presence <TT
CLASS="LITERAL"
>&#60;status/&#62;</TT
>
value. <A
HREF="x8561.htm#JABTDG-CH-8-EX-5"
>Example 8-5</A
> shows what a 
<TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
> element looks like when
built up with values to represent the <TT
CLASS="LITERAL"
>NOCOFFEE</TT
> state.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="JABTDG-CH-8-EX-5"
></A
><P
><B
>Example 8-5. A <TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
> element representing the <TT
CLASS="LITERAL"
>NOCOFFEE</TT
> state</B
></P
><P
><PRE
CLASS="SCREEN"
>&#60;presence&#62;
  &#60;show&#62;xa&#60;/show&#62;
  &#60;status&#62;coffeepot is empty&#60;/status&#62;
&#60;/presence&#62;&#13;</PRE
></P
></DIV
><P
>Most Jabber clients use different icons in the roster to represent
different <TT
CLASS="LITERAL"
>&#60;show/&#62;</TT
> values. So we use
different values here ("xa" for no coffee, and ""&mdash;blank, which
represents "online" or "available"&mdash; for coffee) to trigger the
icon change. </P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="JABTDG-CH-8-SECT-2.2.2"
>Initialization and calibration</A
></H3
><P
>Whenever we need to talk to the RCX, some initialization via the 
ActiveX control is required. That's the same whether we're going
to calibrate or poll for values. The <TT
CLASS="FUNCTION"
>setup_RCX()</TT
>
function 
takes a single argument&mdash;the identification of which connector the
light sensor is connected to&mdash;and performs the initialization, 
which is described later in <A
HREF="x8561.htm#JABTDG-CH-8-SECT-2.2.8"
>the section called <I
><TT
CLASS="FUNCTION"
>setup_RCX()</TT
></I
></A
>.
The function returns a handle on the <TT
CLASS="LITERAL"
>Win32::OLE</TT
>
object that represents the ActiveX control, which in turn represents
the RCX via the IR tower.</P
><P
><PRE
CLASS="SCREEN"
>my $rcx = &#38;setup_RCX(SENSOR);&#13;</PRE
></P
><P
>If the <TT
CLASS="OPTION"
>-l</TT
> flag is not specified, it means we're going to
be running calibration. So we call the <TT
CLASS="FUNCTION"
>calibrate()</TT
>
function to do this for us. We pass the RCX handle (in <TT
CLASS="LITERAL"
>$rcx</TT
>)
so the calibration can run properly.</P
><P
><PRE
CLASS="SCREEN"
># Either calibrate if no parameters given, or
# run with the parameter given as -l, which will
# be taken as the pivot between coffee and no-coffee.
&#38;calibrate($rcx) unless defined($opts{'l'});
  </PRE
></P
><P
>As with the <TT
CLASS="FUNCTION"
>setup_RCX()</TT
> function, 
<TT
CLASS="FUNCTION"
>calibrate()</TT
> is described later. </P
><P
>The calibration mode will be terminated by ending the script with
Ctrl-C, so the next thing we come across is the call to the function
<TT
CLASS="FUNCTION"
>set_status()</TT
> which represents the first stage
in the normal script mode; <TT
CLASS="FUNCTION"
>set_status()</TT
> is used
to determine the <I
CLASS="EMPHASIS"
>initial</I
> coffee status. </P
><P
>A value is retrieved by calling the ActiveX control's 
<TT
CLASS="FUNCTION"
>Poll()</TT
> function. 
(<A
HREF="x8561.htm#JABTDG-CH-8-TAB-1"
>Table 8-1</A
> lists and described the ActiveX control's 
functions and properties used in this script.)
We specify that we're after a "Sensor Value" (the 9 as the first argument)
from the sensor attached to the connector indicated by the 
<TT
CLASS="LITERAL"
>SENSOR</TT
> constant.</P
><P
><PRE
CLASS="SCREEN"
># Determine initial status (will be either 0 or 1)
my $s = &#38;set_status($rcx-&#62;Poll(9, SENSOR));&#13;</PRE
></P
><P
>The value retrieved&mdash;it's going to be something along the lines of one
of the values displayed when the script was run in calibration mode&mdash;is
passed to <TT
CLASS="FUNCTION"
>set_status()</TT
> which determines whether the
value is above or below the pivot value, and whether the "new" status is
different to the current one. If it is (and it this case, it will be, because
in this first call, the value of <TT
CLASS="LITERAL"
>$current_status</TT
> is
set to -1, which represents neither the COFFEE nor the NOCOFFEE state)
that status will be returned, otherwise <TT
CLASS="LITERAL"
>undef</TT
> will be
returned.</P
><DIV
CLASS="TABLE"
><A
NAME="JABTDG-CH-8-TAB-1"
></A
><P
><B
>Table 8-1. RCX "<I
CLASS="EMPHASIS"
>Spirit</I
>" ActiveX control properties and functions used</B
></P
><TABLE
BORDER="1"
CLASS="CALSTABLE"
><THEAD
><TR
><TH
ALIGN="LEFT"
VALIGN="TOP"
>Property/Function</TH
><TH
ALIGN="LEFT"
VALIGN="TOP"
>Description</TH
></TR
></THEAD
><TBODY
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
><TT
CLASS="FUNCTION"
>Poll(SOURCE, NUMBER)</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
>Retrieves information from the RCX. In this script, the value for the
<I
CLASS="EMPHASIS"
>SOURCE</I
> argument is always <I
CLASS="EMPHASIS"
>9</I
>,
which represents a "Sensor Value", i.e. a value measured at a sensor, 
as opposed to an internal RCX variable or a timer, for example. The 
<I
CLASS="EMPHASIS"
>NUMBER</I
> argument represents the connector to which
the sensor we want to read is attached. </TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
><TT
CLASS="FUNCTION"
>SetSensorMode(NUMBER, MODE [, SLOPE])</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
>The sort of value returned from a sensor is determined with this 
function. As with <TT
CLASS="FUNCTION"
>Poll()</TT
> and 
<TT
CLASS="FUNCTION"
>SetSensorType()</TT
>, <I
CLASS="EMPHASIS"
>NUMBER</I
>
represents the sensor connector. With the <I
CLASS="EMPHASIS"
>MODE</I
> 
argument you can determine the sensor mode: 
<I
CLASS="EMPHASIS"
>Raw (analogue) data</I
> (0), <I
CLASS="EMPHASIS"
>Boolean</I
> (1),
<I
CLASS="EMPHASIS"
>Transitional</I
> (2), <I
CLASS="EMPHASIS"
>Periodic</I
> (3),
<I
CLASS="EMPHASIS"
>Percentage</I
> (4), <I
CLASS="EMPHASIS"
>Celcius</I
> (5),
<I
CLASS="EMPHASIS"
>Farenheit</I
> (6), or <I
CLASS="EMPHASIS"
>Angle</I
> (7).
The <I
CLASS="EMPHASIS"
>SLOPE</I
> argument qualifies the 
<I
CLASS="EMPHASIS"
>Boolean</I
> mode by specifying how True and False are
to be determined.</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
><TT
CLASS="FUNCTION"
>SetSensorType(NUMBER, TYPE)</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
>Use this function to specify the <I
CLASS="EMPHASIS"
>type</I
> of sensor
that you're going to read values from. The <I
CLASS="EMPHASIS"
>NUMBER</I
>
argument is the same as for the <TT
CLASS="FUNCTION"
>Poll()</TT
> and 
represents the sensor connector. The <I
CLASS="EMPHASIS"
>TYPE</I
> 
argument represents the type of sensor that you want to set: 
<I
CLASS="EMPHASIS"
>None</I
> (0), <I
CLASS="EMPHASIS"
>Switch</I
> (1), 
<I
CLASS="EMPHASIS"
>Temperature</I
> (2), <I
CLASS="EMPHASIS"
>Light</I
> (3),
or <I
CLASS="EMPHASIS"
>Angle</I
> (4). </TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
><TT
CLASS="LITERAL"
>property:ComPortNo</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
>This is the serial port to which the ir tower is connected (1 = COM1, 
2 = COM2, and so on).</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
><TT
CLASS="LITERAL"
>property:InitComm</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
>This is more like a function than a property. When invoked, the serial
communication port is initialized in preparation for the IR connection
to the RCX.</TD
></TR
></TBODY
></TABLE
></DIV
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="JABTDG-CH-8-SECT-2.2.3"
>Set up connection to Jabber</A
></H3
><P
>At this stage, we're ready to connect to Jabber. The call to 
<TT
CLASS="FUNCTION"
>setup_Jabber()</TT
> does this for us, returning
a handle to the Jabber connection object that we store in 
<TT
CLASS="LITERAL"
>$jabber</TT
>. We will use this handle to send out
<TT
CLASS="LITERAL"
>&#60;presence/&#62;</TT
> elements later in the
script. The <TT
CLASS="LITERAL"
>$jabber</TT
> variable contains a reference
to a <TT
CLASS="LITERAL"
>Net::Jabber::Client</TT
> object, and is the equivalent
of the <TT
CLASS="LITERAL"
>con</TT
> variable used in the earlier Python scripts
(<A
HREF="x6950.htm"
>the section called <I
>CVS notification</I
> in Chapter 7</A
> and <A
HREF="x7499.htm"
>the section called <I
>Presence-sensitive CVS notification</I
> in Chapter 7</A
>)
to hold the <TT
CLASS="LITERAL"
>Jabber.Connection</TT
> object, 
and <TT
CLASS="LITERAL"
>cb</TT
>, holding the <TT
CLASS="LITERAL"
>ConnectionBean</TT
>
object in the earlier Java script (<A
HREF="x7229.htm"
>the section called <I
>Dialup system watch</I
> in Chapter 7</A
>).</P
><P
><PRE
CLASS="SCREEN"
>my $jabber = &#38;setup_Jabber(SERVER, PORT, USERNAME, PASSWORD, RESOURCE, $s);&#13;</PRE
></P
><P
>As well as passing the constants needed for our client connection to 
the Jabber server, we pass the initial coffee status, held in 
<TT
CLASS="LITERAL"
>$s</TT
>. We'll have a look at what the 
<TT
CLASS="FUNCTION"
>setup_Jabber()</TT
> function does with this initial
status a bit later when we get to the function's definition.</P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="JABTDG-CH-8-SECT-2.2.4"
>Sensor poll / presence push loop</A
></H3
><P
>The main loop starts here:</P
><P
><PRE
CLASS="SCREEN"
># Main loop: check Jabber and RCX
# ===============================
while (1) {
  defined($jabber-&#62;Process(GRAIN)) or 
    die "The connection to the Jabber server was broken\n";
  my $s = &#38;set_status($rcx-&#62;Poll(9, SENSOR));
  &#38;set_presence($jabber, $s) if defined $s;
}&#13;</PRE
></P
><P
>The <TT
CLASS="LITERAL"
>while (1)</TT
> is a bit of a giveaway. This script won't 
stop until you force it to stop, with a Ctrl-C. But that's essentially
what we want. In the loop, we call the <TT
CLASS="FUNCTION"
>Process()</TT
>
method on our Jabber connection object in <TT
CLASS="LITERAL"
>$jabber</TT
>. </P
><P
><TT
CLASS="FUNCTION"
>Process()</TT
> is the equivalent of the JabberPy's
<TT
CLASS="LITERAL"
>process()</TT
> method in the Python scripts.
<TT
CLASS="LITERAL"
>Process()</TT
> waits around for up to the number of seconds
specified as the single argument (or not at all if no argument is specified)
for XML to appear on the stream connection from the Jabber server. If
complete fragments do appear, callbacks, defined to the connection 
object, are called with the elements (<TT
CLASS="LITERAL"
>&#60;iq/&#62;</TT
>s,
<TT
CLASS="LITERAL"
>&#60;message/&#62;</TT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -