diff --git a/lib/Group.pm b/lib/Group.pm index 080268fff..f860dde4b 100644 --- a/lib/Group.pm +++ b/lib/Group.pm @@ -5,8 +5,55 @@ use strict; package Group; +=head1 NAME + +B - You can use this object to group and operate on groups of items: + +=head1 SYNOPSIS + + $outside_lights = new Group($light1, $light2, $light3); + $outside_lights-> add($light4, $light5); + $outside_lights-> add($light6); + set $outside_lights ON if time_now("$Time_Sunset + 0:15"); + + for my $item (list $outside_lights) { + print "member = $item->{object_name}\n"; + } + + if (my $member_name = member_changed $outside_lights) { + my $member = &get_object_by_name($member_name); + print_log "Group member $member_name changed to $member->{state}" + } + + my @members = member_changed_log $sensors; + + # turn off all but the bedroom light when we are getting ready for bed + if( state_now $bedroom_control eq ON ) { + my $all = new Group(list $All_Lights); + $all -> remove ( $master_bedroom ); + set $master_bedroom ON; + set $all OFF; + } + +See mh/code/examples/test_group.pl and mh/code/public/monitor_occupancy_jason.pl for more examples. + +=head1 DESCRIPTION + +=head1 INHERITS + +B + +=head1 METHODS + +=over + +=cut + @Group::ISA = ('Generic_Item'); +=item C +=cut + sub new { my ($class, @items) = @_; my $self = {state => undef}; @@ -16,6 +63,9 @@ sub new { return $self; } +=item C +=cut + sub add { my ($self, @items) = @_; my @item_states = (); @@ -96,6 +146,9 @@ sub include_in_group { #check if X10 item is affected by group } +=item C +=cut + sub set { my ($self, $state, $set_by) = @_; print "Group set: $self set to $state members @{$$self{members}}\n" if $main::Debug{group}; @@ -400,6 +453,8 @@ sub set_group_items { } } +=item C +=cut sub list { my ($self, $memberList, $groupList, $no_child_members ) = @_; @@ -442,6 +497,11 @@ sub list { return sort @$memberList; # Hmmm, to sort or not to sort. } +=item C + +Returns a member object name whenever one changes + +=cut sub member_changed { my ($self) = @_; @@ -451,12 +511,23 @@ sub member_changed { } } +=item C + +Returns a list of recenty changed members. The first one was the most recently changed. + +=cut + sub member_changed_log { my ($self) = @_; return unless $$self{member_changed_log}; return @{$$self{member_changed_log}}; } +=item C + +Remove an item from a group + +=cut sub remove { my ($self, @items) = @_; @@ -469,6 +540,46 @@ sub remove { } } +=back + +=head1 INHERITED METHODS + +=over + +=item C + +=item C + +Like the Generic_Item methods, these return the last state that the group was set to. If a group member changed, these methods will return 'member $state_name' rather than just '$state_name'. You can use the member_changed or get_set_by methods to see which member changed. + +=item C + +Returns a list array of the last max_state_log_entries (mh.ini parm) time_date stamped states. + + +=back + +=head1 INI PARAMETERS + +NONE + +=head1 AUTHOR + +UNK + +=head1 SEE ALSO + +NONE + +=head1 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut # # $Log: Group.pm,v $ diff --git a/lib/HVweb_Item.pm b/lib/HVweb_Item.pm index 364a6cfe4..4e14ad61a 100644 --- a/lib/HVweb_Item.pm +++ b/lib/HVweb_Item.pm @@ -1,33 +1,35 @@ -# -# HVweb_Item.pm -# -# Package to control Homevision controller via the Homevision web server -# -# Set homevision_url= in mh.ini -# -# Create items as follows: -# -# $kitchen_light = new HVweb_Item('On','X10 G1 On','X10 G1 state level%','Main Kitchen Light'); -# $kitchen_light -> add ('Off', 'X10 G1 Off'); -# $vcr = new HVweb_Item('Power', 'IR 45 1 time'); -# $vcr -> add ('Play', 'IR 46 1 time'); -# -# See Homevision documentation for complete list of command formats -# Configure Homevision Webserver to report command results -# -# Operate devices as follows: -# -# set $kitchen_light 'On'; -# set $vcr 'Play'; -# -# By Joseph Gaston (gastoniere@yahoo.com) -# -# - use strict; package HVweb_Item; +=head1 NAME + +B - Control Homevision controller via the Homevision web server + +=head1 SYNOPSIS + + $kitchen_light = new HVweb_Item('On', 'X10 G1 On'); + $kitchen_light -> add ('Off', 'X10 G1 Off'); + $vcr = new HVweb_Item('Power', 'IR 45 1 time'); + $vcr -> add ('Play', 'IR 46 1 time'); + + set $kitchen_light 'On'; + set $vcr 'Play'; + + + +=head1 DESCRIPTION + +See Homevision documentation for complete list of command formats +Configure Homevision Webserver to report command results + +=head1 INHERITS + +B + +=head1 METHODS +=cut + @HVweb_Item::ISA = ('Generic_Item'); sub new { @@ -107,3 +109,25 @@ sub list { ### Some web functions (list_items.pl) need this routine return 1; +=head1 INI PARAMETERS + +Set homevision_url= in mh.ini + +=head1 AUTHOR + +Joseph Gaston (gastoniere@yahoo.com) + +=head1 SEE ALSO + +See Homevision documentation for complete list of command formats + +=head1 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + diff --git a/lib/IR_Item.pm b/lib/IR_Item.pm index f9e54ef09..156b5da35 100644 --- a/lib/IR_Item.pm +++ b/lib/IR_Item.pm @@ -4,6 +4,37 @@ use strict; package IR_Item; +=head1 NAME + +B - Controls IR transmiters + +=head1 SYNOPSIS + + $TV = new IR_Item 'TV'; + $v_tv_control = new Voice_Cmd("tv [power,on,off,mute,vol+,vol-,ch+,ch-]"); + set $TV $state if $state = said $v_tv_control; + + $VCR = new IR_Item 'vcr', '3digit'; + set $VCR "12,RECORD" if time_cron('59 19 * * 3'); + set $VCR "STOP" if time_cron('00 20 * * 3'); + +=head1 DESCRIPTION + +This object controls IR transmiters. The devices currently supported are the X10 IR Commander, HomeVision, CPU-XA/Ocelot/Leopard, and UIRT2 (http://www.fukushima.us/UIRT2/). + +The X10 IR Commander (http://www.x10.com/products/ux17a_bj2.htm) receives commands from the wireless CM17 (firecracker) interface. Currently, you must use the X10 supplied software (http://www.x10.com/commander.htm and/or ftp://ftp.x10.com/pub/applications/commander/) to program the IR Commander to use the codes for your various remotes. + +=head1 INHERITS + +B + +=head1 METHODS + +=over + +=cut + + @IR_Item::ISA = ('Generic_Item'); my %default_map = qw( @@ -13,6 +44,27 @@ my %default_map = qw( my ($hooks_added, @objects_xap); +=item C - Creates a new Item. + +$type is the type of device being controlled. Default is TV. Here are the only valid types for the X10 IR Commander; TV, VCR, CAB, CD, SAT, DVD + +$code specifies how numbers will be treated. Default is 2digit. +- noPad : numbers are not modified +- 2digit : single digits will be padded with a leading zero +- 3digit : numbers will be padded to 3 digits with leading zeros +- addEnter: adds an ENTER command after any numbers, to make changing channels faster on devices that wait for a timeout (e.g. Sony TVs). + +$interface is the transmitter to be used. Default is cm17. +- cm17 : X10 IR Commander +- homevision: HomeVision +- ncpuxa : CPU-XA/Ocelot/Leopard +- uirt2 : UIRT2 (http://www.fukushima.us/UIRT2/) +- xAP : Sends / receives data via the xAP protocol. + +$mapref is a reference to a hash that specifies commands to be mapped to other commands. This is useful for transmitters like the Ocelot which use slot numbers instead of device and function name pairs. Default is a reference to a hash containing ( ON => POWER, OFF => POWER ) Which you would not want if you had descrete ON and OFF codes. + +=cut + sub new { my ($class, $device, $code, $interface, $mapref) = @_; my $self = {}; @@ -136,6 +188,74 @@ sub default_setstate { } } + +=back + +=head1 INHERITED METHODS + +=over + +=item C + +Returns the last state that was sent + +=item C + +Returns the state that was sent in the current pass. + +=item C + +Returns a list array of the last max_state_log_entries (mh.ini parm) time_date stamped states. + +=item C + +Sends out commands to the IR device. Here is a list of valid commands for the X10 IR Commander:: +Note: Commands are not case insensitive + POWER MUTE + CH+ CH- + VOL+ VOL- + 1 2 + 3 4 + 5 6 + 7 8 + 9 0 + MENU ENTER + FF REW + RECORD PAUSE + PLAY STOP + AVSWITCH DISPLAY + UP DOWN + LEFT RIGHT + SKIPDOWN SKIPUP + TITLE SUBTITLE + EXIT OK + RETURN + +=back + +=head1 INI PARAMETERS + +NONE + +=head1 AUTHOR + +UNK + +=head1 SEE ALSO + +NONE + +=head1 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + + # # $Log: IR_Item.pm,v $ # Revision 1.17 2004/07/18 22:16:37 winter diff --git a/lib/LCD.pm b/lib/LCD.pm index d3ecc57f7..6481afd28 100644 --- a/lib/LCD.pm +++ b/lib/LCD.pm @@ -2,6 +2,40 @@ use strict; package LCD; +=head1 NAME + +B - Send and receive data to LCD type displays with keypads + +=head1 SYNOPSIS + + my %lcd_keymap1 = ( N => 'up', I => 'down', M => 'left', H => 'right', F => 'exit', K => 'enter', L => 'left', G => 'right'); + my %lcd_keymap2 = ( 38=> 'up', 40=> 'down', 37=> 'left', 39=> 'right', 17=> 'exit', 96=> 'enter') ; + + $lcd1 = new LCD 'lcdproc', '192.168.0.5:13666', '4x20', 'default', \%lcd_keymap1; + $lcd2 = new LCD 'keyboard', undef, '4x20', 'mh', \%lcd_keymap2; + +=head1 DESCRIPTION + +An example is in mh/code/bruce/lcd.pl. To use simulate an LCD keypad with your pc keyboard, use mh/code/bruce/lcd_keyboard.pl. + +=head1 INHERITS + +NONE + +=head1 METHODS + +=over + +=item C + +Connect to the LCD. Automatically called on startup + +=cut + sub start { my ($self) = @_; my $object = $$self{object}; @@ -56,6 +96,12 @@ sub start { } +=item C + +Disconnect the LCD. + +=cut + sub stop { my ($self) = @_; my $object = $$self{object}; @@ -67,11 +113,23 @@ sub stop { } } +=item C + +Load menu $menu. Default menu is the first one. + +=cut + sub load { my ($self, $menu) = @_; &main::menu_lcd_load($self, $menu); } +=item C + +Returns whatever key is keyed in + +=cut + # Check for incoming key or info from the lcd sub check_key { my ($self) = @_; @@ -103,6 +161,7 @@ sub check_key { } } + # Send display data to the lcd sub send_display { my ($self) = @_; @@ -158,12 +217,24 @@ sub send_display { } } +=item C + +Sends @data to the LCD, one line per list element + +=cut + # Set the data to display sub set { my ($self, @data) = @_; @{$$self{display}} = @data; $$self{refresh} = 1; } +=item C + +Simulates the keyboard being pressed with $key + +=cut + # Set the key entered sub set_key { my ($self, $data) = @_; @@ -176,6 +247,13 @@ sub said_key { $$self{timer}->set(10) if defined $state; return $state; } + +=item C + +Returns true if no key has been pressed in 10 seconds. + +=cut + # Check for recent key activity sub inactive { my ($self) = @_; @@ -213,6 +291,29 @@ sub process { 1; +=back + +=head1 INI PARAMETERS + +NONE + +=head1 AUTHOR + +UNK + +=head1 SEE ALSO + +NONE + +=head1 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut # # $Log: LCD.pm,v $ diff --git a/lib/Network_Item.pm b/lib/Network_Item.pm index 88a89f9c0..9357cdce7 100644 --- a/lib/Network_Item.pm +++ b/lib/Network_Item.pm @@ -1,36 +1,51 @@ +package Network_Item; -# This object simply pings the specified address and sets -# its state according to status -# -# 2011-07-30 MKB Enhanced with WakeOnLan functionality +=head1 NAME -package Network_Item; +B - Uses ping to detect when specified ip address is up. -=begin comment +=head1 SYNOPSIS -Here is an example: + use Network_Item; -use Network_Item; + $network_house = new Network_Item('192.168.0.2', 10); + $network_hp = new Network_Item('192.168.0.66', 20); -$network_house = new Network_Item('192.168.0.2', 10); -$network_hp = new Network_Item('192.168.0.66', 20); + print_log "house just changed to $state" if $state = state_changed $network_house; + print_log "house is $state" if new_second 15 and $state = state $network_house; -print_log "house just changed to $state" if $state = state_changed $network_house; -print_log "house is $state" if new_second 15 and $state = state $network_house; +Example mht entry: -Here is an example mht entry: -#NETWORK IP_ADDRESS NAME Grouplist Interval MAC_ADDRESS -NETWORK, 192.168.4.25, HTPC_Mini, HTPC|HomeGym, 120, 00:1C:C0:AB:CD:AE + #NETWORK IP_ADDRESS NAME Grouplist Interval MAC_ADDRESS + NETWORK, 192.168.4.25, HTPC_Mini, HTPC|HomeGym, 120, 00:1C:C0:AB:CD:AE +=head1 DESCRIPTION -=cut +This object simply pings the specified address and sets its state according to status + +2011-07-30 MKB Enhanced with WakeOnLan functionality + +=head1 INHERITS + +B + +=head1 METHODS +=over + +=cut @Network_Item::ISA = ('Generic_Item'); use IO::Socket qw(AF_INET SOCK_DGRAM SOL_SOCKET SO_BROADCAST); use Socket; +=item C - You can use the Socket_Item object to read and/or write to TCP/IP socket ports. + +=head1 SYNOPSIS + + # An example of a server socket + # Add this mh.ini parm: server_speak_port = 8090 + $socket_server = new Socket_Item(undef, undef, 'server_speak'); + if (my $data = said $socket_server) { + print "speak_server socket data: $data\n"; + speak $data; + } + + # An example of a client socket + my $lcdproc_address = 'misterhouse:13666'; + $lcdproc = new Socket_Item(undef, undef, $lcdproc_address, 'lcdproc'); + + $Vcmd_viavoice = new main::Socket_Item(undef, undef, 'localhost:3234', 'viavoice'); + + # This example walks the reboot menu of a router + $router_reboot = new Voice_Cmd 'Reboot the router'; + $router_client = new Socket_Item(undef, undef, $config_parms{router_address} . ":23", 'router', 'tcp', 'raw'); + set_expect $router_client (Password => $config_parms{router_password}, Number => 24, Number => 4, Number => 11) if said $router_reboot; + + # Example of sending a message to all clients + set $telnet_server "Hi to all clients", 'all'; + +More examples are in mh/code/bruce/telnet.pl, mh/code/examples/socket_test*.pl, mh/code/bruce/monitor_shoutcast.pl, bruce/wxserver_server.pl, and bruce/monitor_router.pl + + +=head1 DESCRIPTION + +=head1 INHERITS + +=head1 METHODS + +=over + +=cut + + @Socket_Item::ISA = ('Generic_Item'); my (%socket_item_by_id); @@ -18,6 +60,10 @@ sub socket_item_by_id { return $socket_item_by_id{$id}; } +=item C + +=cut + sub new { my ($class, $id, $state, $host_port, $port_name, $host_proto, $datatype, $break, $broadcast) = @_; @@ -40,11 +86,31 @@ sub new { return $self; } +=item C + +Allows you to change the server_name/port. + +=cut + sub set_port { my ($self, $host_port) = @_; $$self{host_port} = $host_port; } +=item C + +'host_port' - must be of the form ip_address:port (when creating a client) or it must match a server_* parm in mh.ini (when creating a server) (e.g. server_telnet_port). + +'host_protocol' - can be 'tcp' or 'udp'. Default is 'tcp' + +'datatype' - can be 'raw', 'rawout', or 'record'. If 'raw', the said method returns data as read. If record, said only returns data when reaching a newline. When writing to the port, a newline is added unless datatype is 'raw' or 'rawout'. + +'break_char' - This will be added to data sent with set and, unless datatype=raw, will be used to break incoming data into state_now records. Default is \n\r. + +'name' - is optional. If used you can set debug to this string to turn on debug for just this socket data. + +=cut + sub add { my ($self, $id, $state) = @_; $$self{state_by_id}{$id} = $state if $id; @@ -54,6 +120,12 @@ sub add { # print "db sid=", %socket_Item::socket_item_by_id, "\n"; } +=item C + +Connect to the specified port. This allows mh to act as a client, rather than a server, and initiate communications with a server. + +=cut + sub start { my ($self) = @_; my $port_name = $self->{port_name}; @@ -92,12 +164,24 @@ sub start { return 0; } +=item C + +This will drop the client or server from mh and free up the port. + +=cut + sub stop { my ($self) = @_; my $port_name = $self->{port_name}; &main::socket_close($port_name); } +=item C + +Returns 1 if the socket is available, 0 if not + +=cut + sub is_available { my ($self) = @_; my $host_port = $self->{host_port}; @@ -105,17 +189,35 @@ sub is_available { return &net_socket_check($host_port, $host_proto); } +=item C + +True if the port is active. + +=cut + sub active { my $port_name = $_[0]->{port_name}; return $main::Socket_Ports{$port_name}{socka}; # or scalar @{$main::Socket_Ports{$port_name}{clients}} } +=item C + +True for the mh pass that the socket first becomes active. + +=cut + sub active_now { my $port_name = $_[0]->{port_name}; return $main::Socket_Ports{$port_name}{active_this_pass}; } +=item C + +True for the mh pass that the socket first becomes inactive. + +=cut + sub inactive_now { my $port_name = $_[0]->{port_name}; return $main::Socket_Ports{$port_name}{inactive_this_pass}; @@ -177,6 +279,13 @@ sub peer { return "That's unpossible"; } +=item C + +Returns a data record received by the port. +Note: If you want to process binary socket data, specify server_*_datatype = raw in the mh.ini file. This will cause said to return any data read immediately, rather than buffering up data until a newline is read. + +=cut + sub said { my $port_name = $_[0]->{port_name}; @@ -194,6 +303,12 @@ sub said { return $data; } +=item C + +Reads and returns the next record from the socket handle + +=cut + sub said_next { my $port_name = $_[0]->{port_name}; my $sock = $main::Socket_Ports{$port_name}{socka}; @@ -211,11 +326,26 @@ sub said_next { return $data; } +=item C + +Returns the socket handle, so you can loop on reading/writing data to it directly. + +=cut + sub handle { my $port_name = $_[0]->{port_name}; return $main::Socket_Ports{$port_name}{socka}; } +=item C + +Use this to control echoing of incoming characters: +- set_echo $my_socket 0 -> Do not echo incoming characters +- set_echo $my_socket 1 -> echo incoming characters +- set_echo $my_socket '*' -> echo incoming characters with * + +=cut + sub set_echo { my ($self, $echo) = @_; my $port_name = $self->{port_name}; @@ -223,6 +353,19 @@ sub set_echo { $main::config_parms{"${port_name}_echo"} = $echo; # THIS is what gets quered by mh } +=item C + +Sets the item to the specified state. +- If the specified state has not been defined with 'new' or 'add', the state data is sent. Otherwise the data_stream associated with that state is sent. +- If there is more than one client connected to this port, an optional 2nd parm can be used to pick which client set to. +Values are: +- 'all' (send to all connected clients), +- ip_address (a regular expresion of the ip address(s) you want to send to +- client_number (which client to send to, 0 .. #). Note this can change as clients are added and dropped. +- socket hash name, which can be captured when reading data from the port with this: $client = $Socket_Ports{$port_name}{socka}; + +=cut + sub set { my ($self, $state, $ip_address) = @_; @@ -299,7 +442,11 @@ sub set { } -sub set_expect { +=item C + +Used to send a series of strings to the port, waiting for a specified prompt for each string. This is useful for walking through menus. The arguments passed to set_expect are pairs of 'prompt' => 'response' strings. See example below. + + sub set_expect { my ($self, @set_expect_cmds) = @_; if (active $self) { &main::print_log("set_expect: $$self{port_name} is already active"); @@ -312,7 +459,9 @@ sub set_expect { $$self{set_expect_timer}-> set(10); &::MainLoop_pre_add_hook( \&Socket_Item::set_expect_check, 0, $self ); } -} + } + +=cut sub set_expect_check { my ($self) = @_; @@ -338,7 +487,44 @@ sub set_expect_check { } } +=back + +=head1 INHERITED METHODS + +=over + +=item C + +Returns the last state that was received or sent + +=item C + +Returns the state that was received or sent in the current pass. + +=back + +=head1 INI PARAMETERS + +Server socket ports are specified with mh.ini parms (see 'server options' in mh.ini) + +=head1 AUTHOR +UNK + +=head1 SEE ALSO + +NONE + +=head1 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut +1; # # $Log: Socket_Item.pm,v $ @@ -440,5 +626,3 @@ sub set_expect_check { # - created # # - -1; diff --git a/lib/iButton.pm b/lib/iButton.pm index c4445352e..f98cd3f07 100644 --- a/lib/iButton.pm +++ b/lib/iButton.pm @@ -7,6 +7,169 @@ use strict; package iButton; +=head1 NAME + +B - This is used to query and/or control an iButton device + +=head1 SYNOPSIS + + $v_iButton_connect = new Voice_Cmd "[Connect,Disconnect] to the iButton bus"; + if ($state = said $v_iButton_connect) { + if ($state eq 'Connect') { + print_log &iButton::connect($config_parms{iButton_serial_port}); + print_log &iButton::connect($config_parms{iButton_2_serial_port}); + } + else { + print_log &iButton::disconnect; + print_log &iButton::disconnect, $config_parms{iButton_2_serial_port}; + } + } + + $ib_bruce = new iButton '010000012345ef'; + speak 'Hi Bruce' if ON eq state_now $ib_bruce; + speak 'Later' if OFF eq state_now $ib_bruce; + + $ib_relay1 = new iButton '12000000123456ff', undef, 'A'; + $ib_relay2 = new iButton '12000000123456ff', undef, 'B'; + $v_iButton_relay1 = new Voice_Cmd "Turn relay1 [on,off]"; + if ($state = said $v_iButton_relay1) { + print_log "Setting iButton relay1 to $state"; + set $ib_relay1 $state; + } + + $ib_temp1 = new iButton '1000000029a14f', $config_parms{iButton_2_serial_port}; + $ib_temp2 = new iButton '1000000029f5d6'; + my @ib_temps = ($ib_temp1, $ib_temp2); + + $v_iButton_readtemp = new Voice_Cmd "Read the iButton temperature [1,2]"; + if ($state = said $v_iButton_readtemp) { + my $b = $ib_temps[$state-1]; + my $temp = read_temp $b; + print_log "Temp for sensor $state: $temp F"; + logit("$config_parms{data_dir}/iButton_temps.log", "$state: $temp"); + } + if ($New_Second and !($Minute % 5)) { + run_voice_cmd 'Read the iButton temperature 1' if $Second == 11; + run_voice_cmd 'Read the iButton temperature 2' if $Second == 22; + } + +=head1 DESCRIPTION + +For more information on iButton see the hardware section + +=head1 INHERITS + +B + +=head1 METHODS + +=over + +=item C + +If $port is not specified, the port of the first iButton::connect will be used. +$channel (used for switches like the DS2406) defaults to A + +=item C - Sets the item to the specified state. + +=item C - Returns the last state that was received or sent + +=item C - Returns the state that was received or sent in the current pass. + +=item C - Returns a list array of the last max_state_log_entries (mh.ini parm) time_date stamped states. + +=item C - Returns the temperature of temperature devices. + +=item C - Reads iButton switch data + +=item C - Reads iButton weather station wind speed + +=item C - Reads iButton weather station wind direction + +=back + +In addition to the above, all of the methods provided by the Hardware/iButton/Device.pm module are available (documented in mh/lib/site/Hardware/iButton/Device.pm). + +These functions are also part of the iButton module, but not associated with an object: + +=over + +=item C - Returns a object list of iButton devices that match $family + +=item C - Returns a report of iButton devices that match $family + +=item C - Checks the one wire bus for iButton activity + +=item C - Connect to the one wire bus. Note you can now have multiple iButton interfaces on multiple COM ports. + +=item C - Disconnect to the one wire bus + +=back + +Note, all of these functions take an optional $port parm (required for connect). If not specified, the port of the first connect record will be used. + +The $id required when creating new iButton_Item is the 16 hex character (64 bit) iButton id that is unique to every device. This is often printed on the larger devices. If not, you can use: + + $v_iButton_list = new Voice_Cmd "List all the iButton buttons"; + print_log &iButton::scan_report if said $v_iButton_list; + +The last 2 characters are CRC bits and are optional. If missing (i.e. you only specify the first 14 characters), mh will calculate it. + +The first 2 characters are the iButton family type. Here is a list of family types: + + Field Index: + ------------ + (1) Family code in hex + (2) Number of regular memory pages + (3) Length of regular memory page in bytes + (4) Number of status memory pages + (5) Length of status memory page in bytes + (6) Max communication speed (0 regular, 1 Overdrive) + (7) Memory type (see below) + (8) Part number in iButton package + (9) Part number in non-iButton package + (10) Brief descriptions + + (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) + ------------------------------------------------------- + 01, 0, 0, 0, 0, 1, 0, DS1990A,DS2401,Unique Serial Number + 02, 0, 0, 0, 0, 0, 0, DS1991,DS1205, MultiKey iButton + 04, 16, 32, 0, 0, 0, 1, DS1994,DS2404,4K-bit NVRAM with Clock + 05, 0, 0, 0, 0, 0, 0, DS2405,,Single Addressable Switch + 06, 16, 32, 0, 0, 0, 1, DS1993,DS2403,4K-bit NVRAM + 08, 4, 32, 0, 0, 0, 1, DS1992,DS2402,1K-bit NVRAM + 09, 4, 32, 1, 8, 1, 2, DS1982,DS2502,1K-bit EPROM + 0A, 64, 32, 0, 0, 1, 1, DS1995,DS2416,16K-bit NVRAM + 0B, 64, 32, 40, 8, 1, 3, DS1985,DS2505,16K-bit EPROM + 0C, 256, 32, 0, 0, 1, 1, DS1996,DS2464,64K-bit NVRAM + 0F, 256, 32, 64, 8, 1, 3, DS1986,DS2506,64K-bit EPROM + 10, 0, 0, 0, 0, 0, 0, DS1920,DS1820,Temperature iButton with Trips + 11, 2, 32, 1, 8, 0, 2, DS1981,DS2501,512-bit EPROM + 12, 4, 32, 1, 8, 0, 4, DS2407,,Dual Addressable Switch + 13, 16, 32, 34, 8, 0, 3, DS1983,DS2503,4K-bit EPROM + 14, 1, 32, 0, 0, 0, 5, DS1971,DS2430A,256-bit EEPROM, plus + 64-bit + OTP + 15, 0, 0, 0, 0, 1, 0, DS87C900,,Lock Processor + 16, 0, 0, 0, 0, 0, 0, DS1954,,Crypto iButton + 18, 4, 32, 0, 0, 1, 6, DS1963S,4K-bit Transaction iButton with + SHA + 1A, 16, 32, 0, 0, 1, 6, DS1963,,4K-bit Transaction iButton + 1C, 4, 32, 0, 0, 1, 6, DS2422,,1K-bit EconoRAM with Counter + Input + 1D, 16, 32, 0, 0, 1, 6, DS2423,,4K-bit EconoRAM with Counter + Input + 1F, 0, 32, 0, 0, 0, 0, DS2409,,One-Wire Net Coupler + 20, 3, 8, 0, 0, 1, 9, DS2450,,Quad A-D Converter + 21, 16, 32, 0, 0, 1, 8, DS1921,,Temperature Recorder iButton + 23, 16, 32, 0, 0, 1, 7, DS1973,DS2433,4K-bit EEPROM + 22 DS1822 temperature button + 40, 16, 32, 0, 0, 0, 1, DS1608,,Battery Pack Clock + + + +=cut + @iButton::ISA = ('Generic_Item'); my (%connections, %objects_by_id, %buttons_active); @@ -543,6 +706,29 @@ memory ---------------------------------------------------------------------------- +=head1 INI PARAMETERS + +To enable iButton support in mh, set the mh.ini parm ibutton_serial_port. + +=head1 AUTHOR + +UNK + +=head1 SEE ALSO + +NONE + +=head1 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + + # $Log: iButton.pm,v $ # Revision 1.24 2005/01/23 23:21:46 winter # *** empty log message ***