fhem-mirror/FHEM/99_updatefhem.pm
rudolfkoenig b357dd4f85 Small fixes, preparing for the 5.1 release
git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@930 2b470e98-0d58-463d-a4d8-8e2adae1ed80
2011-07-07 07:02:50 +00:00

195 lines
4.8 KiB
Perl

package main;
use strict;
use warnings;
use IO::Socket;
sub CommandUpdatefhem($$);
sub CommandCULflash($$);
my $server = "fhem.de:80";
my $sdir = "/fhemupdate";
my $ftime = "filetimes.txt";
my $dfu = "dfu-programmer";
#####################################
sub
updatefhem_Initialize($$)
{
my %fhash = ( Fn=>"CommandUpdatefhem",
Hlp=>",update fhem from the nightly CVS" );
$cmds{updatefhem} = \%fhash;
my %chash = ( Fn=>"CommandCULflash",
Hlp=>"<cul> <type>,flash the CUL from the nightly CVS" );
$cmds{CULflash} = \%chash;
}
#####################################
sub
CommandUpdatefhem($$)
{
my ($cl, $param) = @_;
my $lt = "";
my $ret = "";
my $moddir = "$attr{global}{modpath}/FHEM";
#my $moddir = "XXX";
# Read in the OLD filetimes.txt
my %oldtime;
if(open FH, "$moddir/$ftime") {
while(my $l = <FH>) {
chomp($l);
my ($ts, $fs, $file) = split(" ", $l, 3);
$oldtime{$file} = $ts;
}
close(FH);
}
my $filetimes = GetHttpFile($server, "$sdir/$ftime");
return "Can't get $ftime from $server" if(!$filetimes);
my (%filetime, %filesize);
foreach my $l (split("[\r\n]", $filetimes)) {
chomp($l);
return "Corrupted filetimes.txt file"
if($l !~ m/^20\d\d-\d\d-\d\d_\d\d:\d\d:\d\d /);
my ($ts, $fs, $file) = split(" ", $l, 3);
$filetime{$file} = $ts;
$filesize{$file} = $fs;
}
my @reload;
my $newfhem = 0;
foreach my $f (sort keys %filetime) {
if($param) {
next if($f ne $param);
} else {
next if($oldtime{$f} && $filetime{$f} eq $oldtime{$f});
next if($f =~ m/.hex$/); # skip firmware files
}
my $localfile = "$moddir/$f";
my $remfile = $f;
if($f eq "fhem.pl") {
$ret .= "updated fhem.pl, restart of fhem is required\n";
$newfhem = 1;
$localfile = $0;
$remfile = "$f.txt";
}
if($f =~ m/^(\d\d_)(.*).pm$/) {
my $m = $2;
push @reload, $f if($modules{$m} && $modules{$m}{LOADED});
}
my $content = GetHttpFile($server, "$sdir/$remfile");
return "File size for $f does not correspond to filetimes.txt entry"
if(length($content) ne $filesize{$f});
open(FH,">$localfile") || return "Can't write $localfile";
print FH $content;
close(FH)
}
return "Can't write $moddir/$ftime" if(!open(FH, ">$moddir/$ftime"));
print FH $filetimes;
close(FH);
if(!$newfhem) {
foreach my $m (@reload) {
$ret .= "reloading module $m\n";
my $cret = CommandReload($cl, $m);
return "$ret$cret" if($cret);
}
}
return $ret;
}
sub
CommandCULflash($$)
{
my ($cl, $param) = @_;
my $moddir = "$attr{global}{modpath}/FHEM";
#my $moddir = "XXX";
my %ctypes = (
CUL_V2 => "at90usb162",
CUL_V2_HM => "at90usb162",
CUL_V3 => "atmega32u4",
CUL_V4 => "atmega32u2",
);
my @a = split("[ \t]+", $param);
return "Usage: CULflash <Fhem-CUL-Device> <CUL-type>, ".
"where <CUL-type> is one of ". join(" ", sort keys %ctypes)
if(int(@a) != 2 ||
!$defs{$a[0]} ||
$defs{$a[0]}{TYPE} ne "CUL" ||
!$ctypes{$a[1]});
my $cul = $a[0];
my $target = $a[1];
################################
# First get the index file to prove the file size
my $filetimes = GetHttpFile($server, "$sdir/$ftime");
return "Can't get $ftime from $server" if(!$filetimes);
my (%filetime, %filesize);
foreach my $l (split("[\r\n]", $filetimes)) {
chomp($l);
return "Corrupted filetimes.txt file"
if($l !~ m/^20\d\d-\d\d-\d\d_\d\d:\d\d:\d\d /);
my ($ts, $fs, $file) = split(" ", $l, 3);
$filetime{$file} = $ts;
$filesize{$file} = $fs;
}
################################
# Now get the firmware file:
my $content = GetHttpFile($server, "$sdir/$target.hex");
return "File size for $target.hex does not correspond to filetimes.txt entry"
if(length($content) ne $filesize{"$target.hex"});
my $localfile = "$moddir/$target.hex";
open(FH,">$localfile") || return "Can't write $localfile";
print FH $content;
close(FH);
my $cmd = "($dfu MCU erase && $dfu MCU flash TARGET && $dfu MCU start) 2>&1";
my $mcu = $ctypes{$target};
$cmd =~ s/MCU/$mcu/g;
$cmd =~ s/TARGET/$localfile/g;
CUL_SimpleWrite($defs{CUL}, "B01");
sleep(4); # B01 needs 2 seconds for the reset
Log 1, $cmd;
my $result = `$cmd`;
Log 1, $result;
return $result;
}
sub
GetHttpFile($$)
{
my ($host, $filename) = @_;
my $server = IO::Socket::INET->new(PeerAddr => $server);
if(!$server) {
Log 1, "Can't connect to $server\n";
return undef;
}
$host =~ s/:.*//;
my $req = "GET $filename HTTP/1.0\r\nHost: $host\r\n\r\n\r\n";
syswrite $server, $req;
my ($buf, $ret);
while(sysread($server, $buf, 65536) > 0) {
$ret .= $buf;
}
$ret=~ s/.*?\r\n\r\n//s;
Log 1, "Got http://$host$filename, length: ".length($ret);
return $ret;
}
1;