Announcement

Collapse
No announcement yet.

Z-Wave Interface Backup Script

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    #46
    Originally posted by TechFan View Post
    Mine is empty.
    OK, here is an easier alternative than using CPAN:

    sudo apt-get update
    sudo apt-get -y install libwww-perl

    (I should have known there was a better way than how I've been doing it for the past 20 years!)

    Comment


      #47
      Originally posted by zwolfpack View Post
      OK, here is an easier alternative than using CPAN:

      sudo apt-get update
      sudo apt-get -y install libwww-perl

      (I should have known there was a better way than how I've been doing it for the past 20 years!)
      Lol. Glad you found it! Thanks!

      Anything I can safely do to address (remove/repair) what appears to be broken CPAN?

      Installed libwww-perl

      Code:
      root@HomeTrollerZeeS2:/usr/include/arm-linux-gnueabihf/sys# apt-get install libwww-perl
      Reading package lists... Done
      Building dependency tree       
      Reading state information... Done
      The following extra packages will be installed:
        libencode-locale-perl libfile-listing-perl libfont-afm-perl libhtml-form-perl libhtml-format-perl
        libhtml-parser-perl libhtml-tagset-perl libhtml-tree-perl libhttp-cookies-perl libhttp-daemon-perl
        libhttp-date-perl libhttp-message-perl libhttp-negotiate-perl libio-socket-ip-perl
        libio-socket-ssl-perl liblwp-mediatypes-perl liblwp-protocol-https-perl libmailtools-perl
        libnet-http-perl libsocket-perl liburi-perl libwww-robotrules-perl
      Suggested packages:
        libdata-dump-perl libcrypt-ssleay-perl libauthen-ntlm-perl
      The following NEW packages will be installed:
        libencode-locale-perl libfile-listing-perl libfont-afm-perl libhtml-form-perl libhtml-format-perl
        libhtml-parser-perl libhtml-tagset-perl libhtml-tree-perl libhttp-cookies-perl libhttp-daemon-perl
        libhttp-date-perl libhttp-message-perl libhttp-negotiate-perl libio-socket-ip-perl
        libio-socket-ssl-perl liblwp-mediatypes-perl liblwp-protocol-https-perl libmailtools-perl
        libnet-http-perl libsocket-perl liburi-perl libwww-perl libwww-robotrules-perl
      0 upgraded, 23 newly installed, 0 to remove and 150 not upgraded.
      Need to get 1,198 kB of archives.
      After this operation, 3,413 kB of additional disk space will be used.
      Do you want to continue [Y/n]?
      And, btw, the script worked this time. . .I have a .ZWave backup file! :-)

      Comment


        #48
        [QUOTE=TechFan;1295074]

        Anything I can safely do to address (remove/repair) what appears to be broken CPAN?
        /QUOTE]

        Try to upgrade it and see if that fixes it.
        After you 'sudo cpan' if your are not root, run the following within the CPAN shell:
        install CPAN
        reload cpan
        Len


        HomeSeer Version: HS3 Pro Edition 3.0.0.435
        Linux version: Linux homeseer Ubuntu 16.04 x86_64
        Number of Devices: 633
        Number of Events: 773

        Enabled Plug-Ins
        2.0.54.0: BLBackup
        2.0.40.0: BLLAN
        3.0.0.48: EasyTrigger
        30.0.0.36: RFXCOM
        3.0.6.2: SDJ-Health
        3.0.0.87: weatherXML
        3.0.1.190: Z-Wave

        Comment


          #49
          Originally posted by TechFan View Post
          And, btw, the script worked this time. . .I have a .ZWave backup file! :-)
          Glad you got it working!

          The problem isn't with CPAN, but with the C-compiler. All the #include <sys/*.h> files are missing. Best guess is that the Homeseer build excluded them or deleted them purposfully/accidentally. Only effect would be if you want to build anything from c-source (including of course any perl modules that have c-source components).
          To fix, determine the package that installs the include files, then remove & reinstall it:
          sudo apt-get -y remove <package>
          sudo apt-get -y install <package>
          Not sure how to determine the package unfortunately.

          Comment


            #50
            Originally posted by zwolfpack View Post
            Glad you got it working!

            The problem isn't with CPAN, but with the C-compiler. All the #include <sys/*.h> files are missing. Best guess is that the Homeseer build excluded them or deleted them purposfully/accidentally. Only effect would be if you want to build anything from c-source (including of course any perl modules that have c-source components).
            To fix, determine the package that installs the include files, then remove & reinstall it:
            sudo apt-get -y remove <package>
            sudo apt-get -y install <package>
            Not sure how to determine the package unfortunately.

            K. Thx. I just wasn't sure if I needed to clean up all that installing that module tried. Otherwise, will leave alone for now.

            Comment


              #51
              I was getting a '401 unauthorized' error.
              When I disabled the option 'No Password Required for Local/Same Network Login' (in network settings)
              the scripts works great, only I rather don't disable this setting. Do you know a workaround (running HS on a debian server)?
              Or is the only option to adjust the script with something like this Perlmonks.org


              -- Edit --

              I've been trying several things like create an url with userassword@IPServer but that doesn't work
              I've adjusted the original script

              Code:
              #!/usr/bin/perl
              # Z-Wave backup utility
              # d. g. otto 2016/01/25
              
              # usage: zwbkup.pl [ hs3_host [ formid ... ] ]
              
              use strict;
              use warnings;
              use English;
              use POSIX qw(strftime);
              
              use LWP::UserAgent;
              use HTML::TokeParser;
              use HTML::Entities;
              
              # the default filename starts with an identifier of the interface type
              # guessing for most of these
              my %IFMdlPfx = (
                  0  => "None",        # None, 
                  1  => "ZNet",        # HomeSeer Z-NET Ethernet
                  4  => "SmartStick",  # HomeSeer SmartStick +
                  6  => "ZWaveMe",     # Z-Wave.me UZB
                  2  => "ZStick",      # Aeon Labs Aeotec Z-Stick
                  5  => "ZTroller",    # HomeSeer Z-Troller
                  8  => "HomeProZC",   # ACT HomePro ZC Series
                  11 => "ThinkStick",  # ControlThink ThinkStick
                  14 => "AspireUSB",   # Cooper Aspire USB
                  17 => "AspireRFUSB", # Cooper Aspire RF-USB
                  19 => "SmartStick",  # HomeSeer SmartStick Legacy
                  20 => "CA8700",      # Intermatic CA8700
                  23 => "HA22",        # Intermatic HA22
                  25 => "SigmaUZB",    # Sigma Designs UZB
                  29 => "WDUSB10",     # Wayne-Dalton WDUSB-10
                  32 => "Serial",      # Generic Serial Controller
                  35 => "ZNet",        # Ethernet Interface
              );
              
              # current timestamp portion of backup file name
              my $now = strftime("%Y-%m-%d_%H.%M.%S", localtime);
              
              # cmdline parameter 1: HS3 host
              my $host = shift;
              $host ||= 'localhost';
              my $url = "http://$host/ZWaveControllers";
              my $user = 'admin';
              my $pass = 'password';
              
              my $ua = LWP::UserAgent->new();
              $ua->agent("USER/AGENT/IDENTIFICATION");
              
              # cmdline parameter 2+: form id(s) to process
              my @formids = @ARGV;
              @formids = get($url) unless @formids;
              print "Form ID(s): ", join(",", @formids), "\n";
              
              foreach my $formid (@formids) {
                  # 1st time selects action "Back Up this interface"
                  get($url, $formid);
                  # 2nd time sets the filename and submits the START button to perform the backup
                  get($url, $formid);
                  sleep 2;
                  # this seems to keep it happy...
                  post($url, [ action => 'updatetime' ]);
                  sleep 1;
              }
              
              my (%friendly, %homeid);
              sub get {
                  my ($url, $formid) = @ARG;
                  print "GET $url\n";
                  my $request = HTTP::Request->new(GET => $url);
                  $request->authorization_basic($user, $pass);
              
                  my $rsp = $ua->request($request);
                  print $rsp->status_line, "\n";
                  exit unless $rsp->is_success;
                  my $content = $rsp->as_string;
                  my $p = HTML::TokeParser->new(\$content);
                  my ($form, $select, $optval, $submit, $text, @postdata, %p);
                  my ($friendly, $homeid, $tcol);
                  my @formids;
                  while (my $tok = $p->get_token) {
                      my @tok = @$tok;
                      my $op = shift @tok;
                      if ($op eq 'S') {  # tag Start
                          my ($tag, $attr, $attrseq, $origtext) = @tok;
                          my %attr = %$attr;
                          if ($tag eq 'form') {
                              # form name
                              $form = $attr{name};
                          } elsif ($tag eq 'input') {
                              if ($attr{type} eq 'text' and $attr{name}) {
                                  if ($attr{name} =~ /^Friendly_([0-9A-F]+)/) {
                                      # parse the Networks and Options form for 
                                      # Network Friendly Name and Home ID
                                      $homeid = $1;
                                      $friendly = $attr{value};
                                      $tcol = 1;  # table column number
                                  } elsif ($attr{name} =~ /^NewName_[0-9A-F]+/) {
                                      # Interface Name
                                      # available for use when building the backup file name
                                      $p{IFName} = $attr{value};
                                  } elsif ($attr{name} =~ /^File_[0-9A-F]+/) {
                                      # set the backup file name as appropriate
                                      my $filename = $attr{value};
                                      $filename = generate_filename($filename, %p);
                                      push(@postdata, $attr{name} => $filename);
                                  }
                              }
                          } elsif ($tag eq 'select') {
                              # name of select pulldown form field
                              $select = $attr{name};
                          } elsif ($tag eq 'option') {
                              # an option within a select form field
                              $optval = $attr{value};
                              if ($attr{selected} and $select =~ /IFModel_/) {
                                  # index of selected Interface Model
                                  # available for use when building the backup file name
                                  $p{IFModelIndex} = $attr{value} || 0;
                              }
                          } elsif ($tag eq 'button') {
                              # submit button
                              if ($attr{name} =~ /^GO_[0-9A-F]+/) {
                                  # submit the form
                                  push(@postdata, %attr);
                              }
                          }
                      } elsif ($op eq 'E') {  # tag End
                          my $tag = shift @tok;
                          if ($tag eq 'form') {
                              # end of form - post queued changes
                              if ($form and $form =~ /^Form_([0-9A-F]+)/ and @postdata) {
                                  my $thisid = $1;
                                  push(@formids, $thisid);
                                  if ($formid and $formid eq $thisid) {
                                      post($url, \@postdata);
                                  }
                              }
                              undef $form;
                              undef @postdata;
                              undef %p;
                          } elsif ($tag eq 'select') {
                              undef $select;
                          } elsif ($tag eq 'option') {
                              # end of option - text label is available for query
                              if ($select =~ /^OpSelect_/ and $text =~ /back\s*up/i) {
                                  # set action to 'Back Up this interface';
                                  push(@postdata, $select => $optval);
                              }
                              undef $optval;
                          } elsif ($tag eq 'td') {
                              # table data
                              if ($tcol and $tcol++ == 4) {
                                  # Interface Name is in 4th column of table displaying
                                  # Z-Wave Networks and Options
                                  my $ifname = $text;
                                  # Network Friendly Name and Home ID
                                  # available for use when building the backup file name
                                  $friendly{$ifname} = $friendly;
                                  $homeid{$ifname} = $homeid;
                                  undef $tcol;
                              }
                          }
                      } elsif ($op eq 'T') {  # Text
                          ($text) = @tok;
                          $text =~ s/[\r\n]//g;
                          $text =~ s/^\s+|\s+$//g;
                          $text = decode_entities($text);
                      }
                  }
                  return @formids;
              }
              
              my %submit;
              
              # POST the changes
              sub post {
                  my ($url, $postdata) = @ARG;
                  my @p = @$postdata;
                  # don't submit same button more than once
                  my %p = @p;
                  if ($p{name}) {
                      return if $submit{$p{name}};
                      $submit{$p{name}}++;
                  }
              
                  print "POST $url\n[\n";
                  for (my $ii = 0; $ii < @p; $ii += 2) {
                      print "  $p[$ii] => $p[$ii+1]\n";
                  }
                  print "]\n";
              
                  my $rsp = $ua->post($url, $postdata);
                  print $rsp->status_line, "\n";
                  exit unless $rsp->is_success;
              }
              
              # routine to generate the backup file name
              # default behaviour is
              # {IFModel}_{FriendlyName}_{HomeID}_{TimeStamp}.ZWave
              # customize as desired 
              sub generate_filename {
                  my ($givenname, %p) = @ARG;
              
                  # interface name
                  my $ifname = $p{IFName};
              
                  # Network Friendly Name
                  my $friendly = $friendly{$ifname};
              
                  # HomeID
                  my $homeid = $homeid{$ifname};
              
                  # map interface model index to abbreviation defined above
                  my $idx = $p{IFModelIndex};
                  my $mdlpfx = $IFMdlPfx{$idx};
              
                  # build the darn thing!
                  my $newname = "${mdlpfx}_${friendly}_${homeid}_${now}.ZWave";
                  return $newname;
              }
              And the get actions are good but I can't figure out how to fix the post function with authentication.

              s# perl /etc/HomeSeer/scripts/zwbkup.pl
              GET http://localhost/ZWaveControllers
              200 OK
              Form ID(s): EFB94519D6C8
              GET http://localhost/ZWaveControllers
              200 OK
              POST http://localhost/ZWaveControllers
              [
              OpSelect_[DELETED] => 24
              ]
              401 Unauthorized
              Last edited by alan_smithee; March 3, 2017, 10:38 AM.

              Comment


                #52
                Originally posted by alan_smithee View Post
                I was getting a '401 unauthorized' error.
                When I disabled the option 'No Password Required for Local/Same Network Login' (in network settings)
                the scripts works great, only I rather don't disable this setting. Do you know a workaround (running HS on a debian server)?
                Good point, I'll take a look at adding this in.

                Comment


                  #53
                  Originally posted by zwolfpack View Post
                  Good point, I'll take a look at adding this in.
                  Thank you in advance. I've been reading Perl and trying several things but I'm not that good in programming.

                  Comment


                    #54
                    Originally posted by alan_smithee View Post
                    Thank you in advance. I've been reading Perl and trying several things but I'm not that good in programming.
                    I've updated the base post with 'r3' to provide this capability. The username & password can be hardcoded into the file, or provided via command line option -l username/password:

                    perl zwbkup.pl -l username/passwd

                    Let me know how it goes...

                    Comment


                      #55
                      Originally posted by zwolfpack View Post
                      I've updated the base post with 'r3' to provide this capability. The username & password can be hardcoded into the file, or provided via command line option -l username/password:

                      perl zwbkup.pl -l username/passwd

                      Let me know how it goes...
                      Nice, thank you very much, that was realy fast.
                      The new script works great. I've hardcoded the username and password in the file and chown/chmod to adjust the rights.

                      Comment


                        #56
                        Base post updated to revision 'r4' which adds a retry mechanism. In installations with more than one interface, the process would sometimes not generate one or more of the backups. With the retry mechanism, all the backups generate properly.

                        Comment


                          #57
                          Originally posted by zwolfpack View Post
                          Base post updated to revision 'r4' which adds a retry mechanism. In installations with more than one interface, the process would sometimes not generate one or more of the backups. With the retry mechanism, all the backups generate properly.
                          This one now works with all 3 interfaces and no longer needs a plug-in restart between each directly addressed backup as had to be done with prior versions.
                          HS4 Pro, 4.2.19.0 Windows 10 pro, Supermicro LP Xeon

                          Comment


                            #58
                            Originally posted by rprade View Post
                            This one now works with all 3 interfaces and no longer needs a plug-in restart between each directly addressed backup as had to be done with prior versions.
                            Great, thanks for testing!

                            Comment


                              #59
                              Thank you @zwolfpack

                              I was able to install perl on my minipc and it executed the backup perfectly and even has the date and time. Life is good.

                              Comment


                                #60
                                Not Getting Backup File From Event Execution

                                Hi zwolfpack,

                                Thank you for the backup script. I always like to automate things when possible. I'm on Windows 7 (32-bit) embedded (HomeTroller). When I found your script, I setup a test event to try it out (after installing Perl). However, I don't see any output. I assume that the backup would go to the same location when running the task manually:

                                > C:\Program Files\HomeSeer HS3\Data\Z-Wave

                                I read through the thread, and saw several references to the user name and password, but I'm not clear what those should be. I did try the default "homeseer" Windows logon name and password, but that didn't work. Maybe it's something else?

                                I can see that the event recorded in the log (see screen shot), but I only see 2 entries which occurred when I clicked the execution button and nothing further.

                                Are the username and password required entries for the r4 script?

                                I'm a complete newb, so I'm sure it's something I've setup incorrectly. Appreciate any suggestions on how to ensure it's working!

                                Thanks!
                                Dave
                                Attached Files

                                Comment

                                Working...
                                X