The Virtual Crib - Home Automation Software Forum Index
RegisterSearchFAQMemberlistUsergroupsLog in
UPB

 
Reply to topic    The Virtual Crib - Home Automation Software Forum Index » Feature Requests View previous topic
View next topic
UPB

Should UPB be added?
Yes
100%
 100%  [ 2 ]
No
0%
 0%  [ 0 ]
Total Votes : 2

Author Message
d_sellers1



Joined: 09 Sep 2007
Posts: 36
Location: Elgin, TX

Post UPB Reply with quote
I did not see an official thread regarding UPB support so I guess I might as well throw it out there. Personally, I like my UPB equipment. I have a dozen US1-30 switches, two US2-40, a lamp module and of course, an interface module. I don't really have much automated right now other than the fact that one of the US2-40's have four buttons that I can use to turn other stuff on and off.

So, UPB support is at the top of my list. The software doesn't do much for me until this gets added... Wink

Derek
Tue Jan 22, 2008 3:10 pm View user's profile Send private message Visit poster's website Yahoo Messenger
Humanzee



Joined: 22 Aug 2007
Posts: 519
Location: Seattle, WA

Post Reply with quote
Derek,
I can't think of any reason why UPB should not be added. The real issue is how to code it and how to test it. I am sure that you are willing to test any UPB modules that are developed here, however, we would need somebody to code an interface for it. I don't believe that Vaughn owns any UPB products to work with while coding. You might contact him directly to see if you can get some more information about what exactly is needed to get things working for you. What is the most popular UPB computer interface, does it have an SDK etc. The interface with vCrib "should" be easy, its the interface with the specific device that might take some work. If you are willing to do the coding, or learn to do the coding I'm sure he will be interested in hearing from you. Z-wave support has stalled for the moment because of limited ability to test and confirm that any particular z-wave build is working.

_________________
vCrib Tester #1, Forum moderator, using INSTEON devices, X10 sensors and remotes via W800RF, All doors are wired with contact closures.
vCrib Wiki
Wed Jan 23, 2008 5:22 pm View user's profile Send private message
CribKeeper
Site Admin


Joined: 09 Aug 2007
Posts: 653
Location: Overland Park, KS

Post Reply with quote
UPB will absolutely be added, no question. I think what we need polls on is Where things rank on the list. Like the other threads that want camera support. Do you think UPB is more important than camera support? Or RFID or ZWave or EventGhost or SageTV....


Basically I need help determining what I should be coding Tonight, this week, next week.... Everything should be added at some point, but until people start adding stuff themselves, I need to focus on just 3-4 objectives. So I am trying to feel out what you guys want the most.

Again, I will help anyone wanting to write any kind of interface to the full extent of my abilities, but can only do a few things at a time myself. I am in gridlock now and losing all focus because there is just so much to do and every new users will be bringing a few more requests to the table and eventually I will just crack and giveup under the weight of it all.

So any help in making you all the most happy the quickest would be a big help to me.

Vaughn

_________________
the Crib Keeper
www.vcrib.com
Wed Jan 23, 2008 5:59 pm View user's profile Send private message Visit poster's website
d_sellers1



Joined: 09 Sep 2007
Posts: 36
Location: Elgin, TX

Post Reply with quote
Personally, I think UPB should rank higher than anything else but, of course, my opinion is biased. All I have is UPB so I can't really play with the software much until this gets implemented. Talking with Vaughn in the past, the biggest roadblock is getting a hold of an SDK. Unfortunately, I can't seem to find anything useful using the powers of Google. I did find one program that is written in Java but that's a different language. I'm hesitant to try to learn a programming language because the last thing I learned was GWBASIC and QBASIC nearly 15 years ago in high school. I didn't even learn C++ or Pascal.

I think UPB is equipment is much more sophisticated than anything else out there. The switches and modules have to be programed which is done through an interface module and software called UPSTART. Switch names, dimming rates and capabilities, and links are all handled through this software. Once the switch is programmed, I don't think the software and interface module need to be running (except for maybe the link, I'm not sure). I was playing with a trial version of another automation software out there and it relied on UPSTART for the programming but then it could interface with the UPB network using the exported configuration file from UPSTART.

Anything that I can do to help, I'll give it a shot. I've been trying to get my hands on some more UPB equipment from eBay so I can donate to the cause but there are not many auctions out there. Perhaps, if someone gets me started with the programming or perhaps some sort of remote access can be set up on my computer to allow someone who can program to look at things and see how it works, just let me know. I can do testing...

Derek
Thu Jan 24, 2008 8:45 am View user's profile Send private message Visit poster's website Yahoo Messenger
Humanzee



Joined: 22 Aug 2007
Posts: 519
Location: Seattle, WA

Post Reply with quote
have you looked at Mr. House? I think its open source too. Don't know if they do UPB or not.

_________________
vCrib Tester #1, Forum moderator, using INSTEON devices, X10 sensors and remotes via W800RF, All doors are wired with contact closures.
vCrib Wiki
Thu Jan 24, 2008 1:03 pm View user's profile Send private message
d_sellers1



Joined: 09 Sep 2007
Posts: 36
Location: Elgin, TX

Post Reply with quote
Humanzee wrote:
have you looked at Mr. House? I think its open source too. Don't know if they do UPB or not.


That looks like it might have some potential. It looks like it is primarily written in Perl and for use with X10. There's no real mention of UPB until you go in to the WIKI and search for UPB. It looks like it has to manually configured or something... for each switch... I'll look in to it and see what I can start to figure out.

Derek
Thu Jan 24, 2008 5:37 pm View user's profile Send private message Visit poster's website Yahoo Messenger
SnyperBob



Joined: 22 Aug 2007
Posts: 630
Location: Illinois

Post Reply with quote
From what I have been reading, it seems that UPB is like 100 times better than the older x10 stuff.

I'd love UPB, Insteon, or any other alternative to X10, but for now I can't afford anything but X10. I'm wondering if I should just save the money I would spend on X10 coupler, filters, etc.....and just put the money towards a UPB starter kit or something.

They're only like $300. Are these things really as simple and easy to use as I've been hearing?

UPB is even more expensive that Insteon. I wish the UPB stuff was as sexy as the Insteon....

Edit: I just noticed that the UPB phase coupler also works with X10 Signals
Fri Jan 25, 2008 5:06 am View user's profile Send private message Visit poster's website AIM Address
d_sellers1



Joined: 09 Sep 2007
Posts: 36
Location: Elgin, TX

Post Reply with quote
Okay... I aquired some stuff from MisterHome. I installed [mh] earlier today but haven't had a chance to play with it. It does have UPB support and I found the file that give it that capability. So, I'm posting them here so maybe this might help someone...

Mods: This software is licensed under the terms of the GNU public license so that's why I am posting the information that I found.

Note: I will attach the files later tonight when I get home because I cannot do it from work and get rid of the code tags.

UPBPIM.pm
Code:
=begin comment

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

File:
   UPBPIM.pm

Description:
   This is the base interface class for Universal Powerline Bus (UPB), Powerline
   Interface Module (PIM). 

   For more information about the UPB protocol:
      http://www.pcslighting.com/downloads.html

   For more information regarding the technical details of the PIM:
      http://www.pcslighting.com/downloads/pulseworx_specifications/PimComm1.5.pdf

Author(s):
    Jason Sharpee
    jason@sharpee.com

   Based loosely on the RCSsTR40.pm code:
   -   Initial version created by Chris Witte <cwitte@xmlhq.com>
   -   Expanded for TR40 by Kirk Bauer <kirk@kaybee.org>

License:
    This free software is licensed under the terms of the GNU public license.

Usage:
   Use these mh.ini parameters to enable this code:

   UPBPIM_serial_port=/dev/ttyS4
   UPBPIM_baudrate=4800
   UPBPIM_network=49
   UPBPIM_moduleid=30
   UPBPIM_password=34554


    Example initialization:

      $myPIM = new UPBPIM("UPBPIM",<networkid>,<networkpassword>,<pimmoduleid>);

      #Turn Light Module ID #0x66 On
      $myPIM->send_upb_cmd("09004466FF236400");
      #Turn Light Module ID #0x66 Off
      $myPIM->send_upb_cmd("09004466FF230000");
      #Turn Light Module ID #0x66 to 50% dim
      $myPIM->send_upb_cmd("09004466FF233200");
   
Notes:
    - However this code does establish communication sucessfully with the PIM,
      and adding functionality at this point will be somewhat trivial.
      ( The exhausting hardware / serial part for me is seemingly over ;) )

Special Thanks to:
    Bruce Winter - MH

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


=cut

use strict;

package UPBPIM;

@UPBPIM::ISA = ('Serial_Item');

my %UPBPIM_Data;

sub serial_startup {
   my ($instance) = @_;

   my $port       = $::config_parms{$instance . "_serial_port"};
   my $speed      = $::config_parms{$instance . "_baudrate"};
   $UPBPIM_Data{$instance}{'serial_port'} = $port;   

   &::serial_port_create($instance, $port, $speed);
  if (1==scalar(keys %UPBPIM_Data)) {  # Add hooks on first call only
#      &::MainLoop_post_add_hook(\&UPBPIM::poll_all, 1);
      &::MainLoop_pre_add_hook(\&UPBPIM::check_for_data, 1);
   }
}

sub poll_all {

}

# Takes a hexadecimal string and calculates the checksum in a hexadecimal string
sub get_checksumHex
{
   my ($msg) = @_;
   my $bmsg;
   $bmsg = pack("H*",$msg);
    my @bytes = unpack 'C*', $bmsg;
    my $checksum = 0;
    foreach (@bytes[0..$#bytes]) {
        $checksum += $_;
    }
    $checksum = ~$checksum;
    $checksum++;
    $checksum &= 0xff;
   $checksum = sprintf("%02X",$checksum);

   return $checksum;
}


sub check_for_data {
   for my $port_name (keys %UPBPIM_Data) {
      &::check_for_generic_serial_data($port_name) if $::Serial_Ports{$port_name}{object};
      my $data = $::Serial_Ports{$port_name}{data_record};
      next if !$data;
#      main::print_log("$port_name got: [$::Serial_Ports{$port_name}{data_record}]");
      $UPBPIM_Data{$port_name}{'obj'}->_parse_data($data);

      $main::Serial_Ports{$port_name}{data_record}='';
=begin
      if (($UPBPIM_Data{$port_name}{'obj'}->{'last_change'} + 5) == $main::Time) {
         $UPBPIM_Data{$port_name}{'obj'}->{'last_change'} = 0;
         $UPBPIM_Data{$port_name}{'obj'}->_poll();
      }
=cut
   }
}

sub new {
   my ($class, $port_name,$network_id,$network_password,$device_id) = @_;
   $port_name = 'UPBPIM' if !$port_name;

   my $self = {};
   $$self{state}     = '';
   $$self{said}      = '';
   $$self{state_now} = '';
   $$self{port_name} = $port_name;
   $$self{last_command} = '';
   $$self{xmit_in_progress} = 0;
   @{$$self{command_stack}} = ();
   bless $self, $class;
   $UPBPIM_Data{$port_name}{'obj'} = $self;

#   $UPBPIM_Data{$port_name}{'send_count'} = 0;
#   push(@{$$self{states}}, 'on', 'off');
#   $self->_poll();

#we just turned on the device, lets wait a bit
   $self->set_dtr(1);
   select(undef,undef,undef,0.15);
   
   $self->set_message_mode();
   $self->network_id($network_id) if defined $network_id;
   $self->network_password($network_password) if defined $network_password;
   $self->device_id($device_id) if defined $device_id;
   $self->update_registers();
   return $self;
}

sub set_message_mode
{
   my ($self) = @_;
   return $self->_send_cmd("\x1770028E\x0D");
   
}
sub update_registers
{
   my ($self, $start, $end) = @_;
   my $cmd;
   $start = 0 if not defined $start;
   $end = 255 if not defined $end;
   $cmd= sprintf("%02X%02X",$start,$end);
   $cmd.= get_checksumHex($cmd);
   return $self->_send_cmd("\x12" . $cmd . "\x0D");
}

sub get_register
{
   my ($self, $start,$end) = @_;
   $start=0 if !defined $start;
   $end=1 if !defined $end;

   my $response;
   for (my $index=$start;$index<$start+$end;$index++)
   {
      $response.=sprintf("%02X",@{$$self{'registers'}}->[$index]);      
   }
   return $response;
}

sub get_firwmare_version
{
   my ($self) = @_;
   return $self->get_register(10) . $self->get_register(11);
}

sub send_upb_cmd
{
   my ($self, $cmd) = @_;
   #queue any new commands
   unshift(@{$$self{command_stack}},$cmd) if defined $cmd;
#   &::print_log("UPB Command stack:@{$$self{command_stack}}:");
   #we dont transmit on top of another xmit
   if ($$self{xmit_in_progress} != 1) {
      $$self{xmit_in_progress} = 1;
      #always send the oldest command first
      $cmd = pop(@{$$self{command_stack}});
      if (defined $cmd)
      {
         #put the command back into the stack.. Its not our job to tamper with this array
         push(@{$$self{command_stack}},$cmd);
         $cmd.= get_checksumHex($cmd);
         return $self->_send_cmd("\x14" . $cmd . "\x0D");
      }
   } else {
      return;
   }
}


sub set_register
{
   my ($self, $start, $val) = @_;
   my $cmd;
   return if !defined $start;

   $cmd= sprintf("%02X%02X",$start,$val);
   $cmd.= get_checksumHex($cmd);
   return $self->_send_cmd("\x17" . $cmd . "\x0D");
}

sub network_id
{
   my ($self, $val) = @_;
   $self->set_register(0,$val) if defined $val;
   return $self->get_register(0);   
}

sub device_id
{
   my ($self, $val) = @_;
   $self->set_register(1,$val) if defined $val;
   return $self->get_register(1);   
}

sub network_password
{
   my ($self, $val) = @_;
   $self->set_register(2,$val) if defined $val;
   return $self->get_register(2);   
}

sub _send_cmd {
   my ($self, $cmd) = @_;
   my $instance = $$self{port_name};
#   print "$::Time_Date: UPBPIM: Executing command $cmd\n" unless $main::config_parms{no_log} =~/UPBPIM/;
   my $data = $cmd;
#print "PN:$instance:";
   $main::Serial_Ports{$instance}{object}->write($data);
### Dont overrun the controller.. Its easy, so lets wait a bit
   select(undef,undef,undef,0.15);
   $$self{'last_change'} = $main::Time;
#   $self->_poll();
}

sub _poll{
   my ($self) = @_;
   my $instance = $self->{port_name};
}

sub _parse_data {
   my ($self, $data) = @_;
##   return if (($$self{'last_change'} + 5) > $main::Time);
   my ($name, $val);
   $data =~ s/^\s*//;
   $data =~ s/\s*$//;
#  &::print_log( "UPBPIM: Parsing serial data: $data\n") unless $main::config_parms{no_log} =~/UPBPIM/;

   #PIM to Host Message
   if (uc(substr($data,0,1)) eq 'P')
   {
      #Confirm that the PIM message has more parts to it
      if (length($data) >=2)
      {
         #Register Dump
         if (uc(substr($data,1,1)) eq 'R')
         {
            #get offset
            my $offset;
            my $bRegisters;
            my @Registers;
            $offset = substr($data,2,2);
            $offset = hex($offset);
            if ($offset != 0)
            {   
               # Im too lazy to store this at an offset instead of replacing it entirely
               &::print_log("Partial Register update not supported");
            } else {
               #Convert to a binary quantity
               $bRegisters = pack("H*",substr($data,4,length($data)-4));
               #Convert to a byte array and replace whole register array
               @Registers = unpack("C*",$bRegisters);
               @{$$self{'registers'}} = @Registers;
            }
         }
         #UPB Incoming Message
         elsif (uc(substr($data,1,1)) eq 'U') {
            $self->delegate(substr($data,2,length($data)));
         }            
         #UPB Accept command
         elsif (uc(substr($data,1,1)) eq 'A') {
            #dont really care
         }
         #UPB Busy
         elsif (uc(substr($data,1,1)) eq 'B') {
            $$self{xmit_in_progress} = 0;
         }
         #UPB Acknowledgement
         elsif (uc(substr($data,1,1)) eq 'K') {
            $$self{xmit_in_progress} = 0;
            pop(@{$$self{command_stack}});            
  select(undef,undef,undef,.15);
            $self->process_command_stack();
         }
         #UPB No Acknowledgement
         elsif (uc(substr($data,1,1)) eq 'N') {
            $$self{xmit_in_progress} = 0;
            &::print_log("$self->object_name: Reports device does not respond");
            pop(@{$$self{command_stack}});
   select(undef,undef,undef,.15);
            $self->process_command_stack();
         }
      }
   }
}

sub process_command_stack
{
   my ($self) = @_;
         ## send any remaining commands in stack
         my $stack_count = @{$$self{command_stack}};
#         &::print_log("UPB Command stack2:$stack_count:@{$$self{command_stack}}:");
         if ($stack_count> 0 )
         {
            #send any remaining commands.
            $self->send_upb_cmd();
         }         
}

sub add
{
   my ($self,@p_objects) = @_;

   my @l_objects;

   for my $l_object (@p_objects) {
      if ($l_object->isa('Group_Item') ) {
         @l_objects = $$l_object{members};
         for my $obj (@l_objects) {
            $self->add($obj);
         }
      } else {
          $self->add_item($l_object);
      }
   }
}

sub add_item
{
    my ($self,$p_object) = @_;

#    $p_object->tie_items($self);
    push @{$$self{objects}}, $p_object;
   #request an initial state from the device
   if (! $p_object->isa('UPB_Link') )
   {   
      $p_object->set("report");
   }
   return $p_object;
}

sub remove_all_items {
   my ($self) = @_;

   if (ref $$self{objects}) {
      foreach (@{$$self{objects}}) {
 #        $_->untie_items($self);
      }
   }
   delete $self->{objects};
}

sub add_item_if_not_present {
   my ($self, $p_object) = @_;

   if (ref $$self{objects}) {
      foreach (@{$$self{objects}}) {
         if ($_ eq $p_object) {
            return 0;
         }
      }
   }
   $self->add_item($p_object);
   return 1;
}

sub remove_item {
   my ($self, $p_object) = @_;

   if (ref $$self{objects}) {
      for (my $i = 0; $i < scalar(@{$$self{objects}}); $i++) {
         if ($$self{objects}->[$i] eq $p_object) {
            splice @{$$self{objects}}, $i, 1;
 #           $p_object->untie_items($self);
            return 1;
         }
      }
   }
   return 0;
}


sub set
{
   my ($self,$p_state,$p_setby,$p_response) = @_;
   $self->send_upb_cmd($p_state);
}

sub delegate
{
   my ($self,$p_data) = @_;
   my $network=unpack("C",pack("H*",substr($p_data,4,2)));
   my $destination=unpack("C",pack("H*",substr($p_data,6,2)));
   my $source=unpack("C",pack("H*",substr($p_data,8,2)));
   my $isLink = 0;   
   my $transeq = unpack("C",pack("h*",substr($p_data,3,1)));
   my $count = $transeq & 0b1100;
   $count = $count>>2;
   my $sequence = $transeq & 0b0011;

   if ( (8 & unpack("C",pack("h*",substr($p_data,0,1)))) ==8 )
   {
      $isLink=1;
   }

   # If a packet is being sent with a xmit count greater than 1
    # then make sure we only delagate one packet and not the repeats
   if ($count > 0)
   {
      my $packet=substr($p_data,4,length($p_data)-6);
      if ($packet ne $$self{last_command} or
      ($packet eq $$self{last_command} && $sequence <= $$self{last_sequence} ) )
      {
         $$self{last_command} = $packet;
         $$self{last_sequence} = $sequence;
      } else {
         &::print_log("UPBPIM: duplicate packet, ignore!");
         return;
      }         
   }

#   &::print_log ("DELEGATE:$network:$source:$destination:$isLink:");
   for my $obj (@{$$self{objects}})
   {
      #Match on UPB objects only
      if ($obj->isa("UPB_Device") or $obj->isa("UPB_Link"))
      {
         #networks match
         if ($network == 0 or $obj->network_id() == $network)
         {
            if ($destination == 0 or $obj->device_id() == $destination)
            {
               #if UPB_Device
               if ($obj->isa("UPB_Device") and $isLink == 0 )
               {
                  $obj->set($p_data,$self);
               } elsif ($obj->isa("UPB_Link") and $isLink == 1)
               {
                  $obj->set($p_data,$self);
               }
            }
         }
      }
   }
}

## WIP
sub sset
{
   my ($self,$p_state,$p_setby,$p_response) = @_;

=begin
    # prevent reciprocal sets that can occur because of this method's state
    # propogation
   return if (ref $p_setby and $p_setby->can('get_set_by') and
        $p_setby->{set_by} eq $self);
=cut
#     &::print_log($self->get_object_name() . "::set($p_state, $p_setby)");

   # ensure the setting object is associated w/ the current object before
   #  iterating over the children.  At a minimum, main::set_by_to_target
   #  requires current "set_by" to properly navigate the set_by "chain"
   $self->{set_by} = $p_setby;

=begin
   # Propogate states to all member items
   if ( defined $$self{objects} ) {
      my @l_objects = @{$$self{objects}};
      for my $obj (@l_objects) {
         if ( $obj ne $p_setby and $obj ne $self ) { # Dont loop
#               &::print_log($self->get_object_name() . "::set($p_state, $p_setby) -> $$obj{object_name}") if $main::Debug{occupancy};
                 $obj->set($p_state,$self,$p_response);
            }
         }
      }
   }
=cut
   
   $self->SUPER::set($p_state,$p_setby,$p_response);
   ## if we called ourselves, then dont send the command out on the bus
   return if (ref $p_setby and $p_setby->can('get_set_by') and
        $p_setby->{set_by} eq $self);
   $self->send_upb_cmd($p_state);
}

sub is_member {
    my ($self, $p_object) = @_;

    my @l_objects = @{$$self{objects}};
    for my $l_object (@l_objects) {
   if ($l_object eq $p_object) {
       return 1;
   }
    }
    return 0;
}

sub find_members {
   my ($self,$p_type) = @_;

   my @l_found;
   my @l_objects = @{$$self{objects}};
   for my $l_object (@l_objects) {
      if ($l_object->isa($p_type)) {
         push @l_found, $l_object;
      }
   }
   return @l_found;
}

=begin
sub default_getstate
{
   my ($self,$p_state) = @_;
   return $$self{m_obj}->state();
}
=cut
1;




UPB_Device.pl
Code:
=begin comment
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

File:
   UPB_Device.pm

Description:
   Generic class implementation of a UPB Device.

Author:
   Jason Sharpee
   jason@sharpee.com

License:
   This free software is licensed under the terms of the GNU public license.

Usage:

   $upb_patio_light = new UPB_Device($myPIM,30,1);

   $upb_patio_light->set("ON");

Special Thanks to:
   Bruce Winter - MH

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
=cut

use strict;

package UPB_Device;

@UPB_Device::ISA = ('Generic_Item');

my %message_types = (
#UPB Core Command Set
                  null => 0x00,
                  write_enable => 0x01,
                  write_protect => 0x02,
                  start_setup => 0x03,
                  stop_setup => 0x04,
                  setup_timer => 0x05,
                  auto_address => 0x06,
                  device_status => 0x07,
                  device_control => 0x08,
                  add_link => 0x0B,
                  delete_link => 0x0C,
                  transmit_message => 0x0D,
                  reset => 0x0E,
                  device_signature => 0x0F,
                  get_register => 0x10,
                  set_register => 0x11,
#UPB Code Device Command Set
                  activate_link => 0x20,
                  deactivate_link => 0x21,
                  goto => 0x22,
                  fade_start => 0x23,
                  fade_stop =>0x24,
                  blink => 0x25,
                  indicate => 0x26,
                  toggle => 0x27,
         # new RCS thermostat device commands
                  set_rcs_variable => 0x28,
                  request_rcs_variable => 0x29,
         # end RCS commands
                  report => 0x30,
                  store => 0x31,
#UPB Core Reports
                  device_state_report =>0x86,
                  device_status_report =>0x87,
                  device_variable_report =>0xA9 #RCS Autosend (or request_rcs_variable response) data
 );

sub new
{
   my ($class,$p_interface,$p_networkid,$p_deviceid) = @_;
   my $self={};
   bless $self,$class;

   $self->interface($p_interface) if defined $p_interface;
   $self->network_id($p_networkid) if defined $p_networkid;
   $self->device_id($p_deviceid) if defined $p_deviceid;
   $self->initialize();
   $self->rate(undef);
   $$self{firstOctet} = "0";
   $$self{ackMode} = "1";
   $$self{interface}->add($self);
   return $self;
}

sub initialize
{
   my ($self) = @_;
}

sub interface
{
   my ($self,$p_interface) = @_;
   $$self{interface} = $p_interface if defined $p_interface;
   return $$self{interface};
}

sub network_id
{
   my ($self,$p_network_id) = @_;
   $$self{network_id} = $p_network_id if defined $p_network_id;
   return $$self{network_id};
}

sub device_id
{
   my ($self,$p_device_id) = @_;
   $$self{device_id} = $p_device_id if defined $p_device_id;
   return $$self{device_id};
}

sub rate
{
   my ($self,$p_rate) = @_;
   $$self{rate} = $p_rate if defined $p_rate;
   return $$self{rate};
}

sub set
{
   my ($self,$p_state,$p_setby,$p_response) = @_;

    # prevent reciprocal sets that can occur because of this method's state
    # propogation
    return if (ref $p_setby and $p_setby->can('get_set_by') and
        $p_setby->{set_by} eq $self);

#   &::print_log($self->get_object_name() . "::set($p_state, $p_setby)");

   if ($p_setby eq $self->interface())
   {
       my $network=unpack("C",pack("H*",substr($p_state,4,2)));
         my $destination=unpack("C",pack("H*",substr($p_state,6,2)));
         my $source=unpack("C",pack("H*",substr($p_state,8,2)));
      my $msg=unpack("C",pack("H*",substr($p_state,10,2)));
      my $l_state = $p_state;
      $p_state = undef;
      if ($network == $self->network_id() or $network==0)
      {
         if ( $destination==$self->device_id() or $destination==0 or $source == $self->device_id() )
         {
            if (!($source != $self->device_id() and $msg >= 0x80))
            {
               $p_state = $self->_xlate_upb_mh($l_state);
                &::print_log($self->get_object_name() . "::set($p_state, $p_setby)");
            }
         }
      }
   } else {
      $$self{interface}->set($self->_xlate_mh_upb($p_state));
       &::print_log($self->get_object_name() . "::set($p_state, $p_setby)");
   }
   $self->SUPER::set($p_state,$p_setby,$p_response) if defined $p_state;
}

sub _xlate_upb_mh
{
   my ($self,$p_state) = @_;

   my $network = unpack("C",pack("H*",substr($p_state,4,2)));
      my $destination = unpack("C",pack("H*",substr($p_state,6,2)));
      my $source = unpack("C",pack("H*",substr($p_state,8,2)));
   my $msgid = unpack("C",pack("H*",substr($p_state,10,2)));
   my $msgdata = substr($p_state,12,length($p_state)-14);
   my @args = unpack("C*",pack("H*",$msgdata));
   my $msg=undef;
   my $state = undef;

   for my $key (keys %message_types){
      if ($message_types{$key} == $msgid)
      {
#         &::print_log("FOUND: $key");
         $msg=$key;
         last;
      }
   }

   $state=$msg;
   #Device report.  ON/OFF anything else is the state percentage?
   if ($message_types{device_state_report} == $msgid and
      $source = $self->device_id())
   {
      if ($args[0]==100) {
         $state='ON';
      } elsif ($args[0]==0) {
         $state='OFF';
      } else {
         $state = $args[0] . "%";
      }

   }
   return $state;
}

sub _xlate_mh_upb
{
   my ($self,$p_state) = @_;
   my $cmd;
   my @args;
   my $msg;
   my $level;
   my $rate;

   #msg id
   $msg=$p_state;
   $msg=~ s/\:.*$//;
   $msg=lc($msg);
#   &::print_log("XLATE:$msg:$p_state:");
   if (uc($msg) eq 'ON')
   {
#      $msg = "fade_start";
      $msg = "goto";
      $level=100;
      $rate=$self->rate();
   } elsif (uc($msg) eq 'OFF')
   {
#      $msg = "fade_start";
      $msg = "goto";
      $level = 0;
      $rate = $self->rate();
   } elsif ($msg=~/^([1]?[0-9]?[0-9])/)
   {
#      $msg= "fade_start";
      $msg= "goto";
      $level = $1;
      $rate = $self->rate();
   } elsif (lc($msg) eq 'status')
   {
      $msg = 'report';
   }

=begin
   #Fuzzy logic find message
   for my $key (keys %message_types)
   {
      if ($key=~/$msg/i)
      {
         $msg = $message_types{$key};
         last;
      }
   }
=cut
   $msg = $message_types{$msg};

   #control word
#   $cmd=$$self{firstOctet} . "970";
   $cmd=$$self{firstOctet} . "0". $$self{ackMode} . "0";
   #network id;
   $cmd.= sprintf("%02X",$self->network_id());
   #destination;
   $cmd.= sprintf("%02X",$self->device_id());
   #source
   $cmd.=$self->interface()->device_id();

   #get specified args
   if ($p_state=~/\:/)
   {
      my @targs;
      @targs = split(':',$p_state);
      @targs = shift(@targs);
      @args=@targs;
   }
   #Format the specific message
   elsif ($msg == $message_types{goto})
   {
      $args[0]=$level;
      $args[1]=$rate if defined $rate;
   }

   ##Finish off the command
   $cmd.= sprintf("%02X",$msg);
   for my $arg (@args)
   {
#      &::print_log("XLATE3:$arg:@args:");

      $cmd.= sprintf("%02X",$arg);
   }

   #set length
   substr($cmd,1,1,sprintf("%X",(length($cmd)/2)+1));

   return $cmd;
}
1;


UPB_Link.pl
Code:
=begin comment
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

File:
   UPB_Link.pm

Description:
   Generic class implementation of a UPB Device.

Author:
   Jason Sharpee
   jason@sharpee.com

License:
   This free software is licensed under the terms of the GNU public license.

Usage:

   $upb_family_movie = new UPB_Light($myPIM,30,1);

   $upb_familty_movie->set("on");

Special Thanks to:
   Bruce Winter - MH

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
=cut

use UPB_Device;

use strict;
package UPB_Link;

@UPB_Link::ISA = ('UPB_Device');

=begin
my %message_types = (    
#UPB Core Command Set
                  null => 0x00,
                  write_enable => 0x01,
                  write_protect => 0x02,
                  start_setup => 0x03,
                  stop_setup => 0x04,
                  setup_timer => 0x05,
                  auto_address => 0x06,
                  device_status => 0x07,
                  device_control => 0x08,
                  add_link => 0x0B,
                  delete_link => 0x0C,
                  transmit_message => 0x0D,
                  reset => 0x0E,
                  device_signature => 0x0F,
                  get_register => 0x10,
                  set_register => 0x11,
#UPB Code Device Command Set
                  activate_link => 0x20,
                  deactivate_link => 0x21,
                  goto => 0x22,
                  fade_start => 0x23,
                  fade_stop =>0x24,
                  blink => 0x25,
                  indicate => 0x26,
                  toggle => 0x27,
                  report => 0x30,
                  store => 0x31,               
#UPB Core Reports
                  device_state_report =>0x86,
                  device_status_report =>0x87
 );
=cut

sub new
{
   my ($class,$p_interface,$p_networkid,$p_deviceid) = @_;

   my $self = $class->SUPER::new($p_interface,$p_networkid,$p_deviceid);
   bless $self,$class;
   $$self{firstOctet} = "8";
   return $self;
}

sub _xlate_upb_mh
{
   my ($self,$p_state) = @_;

   my $state = undef;
   $state = $self->SUPER::_xlate_upb_mh($p_state);

   ## As link devices, we xlate activate/deactivate into ON/OFF
   if (lc($state) eq 'activate_link') {
      $state = 'ON';
   } elsif (lc($state) eq 'deactivate_link') {
      $state = 'OFF';
   }
   return $state;
}

sub _xlate_mh_upb
{
   my ($self,$p_state) = @_;
   my $state=$p_state;
   if (lc($p_state) eq 'on') {
      $state = 'activate_link';
   } elsif (lc($p_state) eq 'off') {
      $state = 'deactivate_link';
   }
   return $self->SUPER::_xlate_mh_upb($state);

}

1;

Fri Jan 25, 2008 6:48 pm View user's profile Send private message Visit poster's website Yahoo Messenger
Display posts from previous:    
Reply to topic    The Virtual Crib - Home Automation Software Forum Index » Feature Requests All times are GMT - 6 Hours
Page 1 of 1

 
Jump to: 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Design by Freestyle XL / Flowers Online.