diff --git a/fhem/FHEM/98_CULflash.pm b/fhem/FHEM/98_CULflash.pm index 014ae9385..0c53a87c2 100644 --- a/fhem/FHEM/98_CULflash.pm +++ b/fhem/FHEM/98_CULflash.pm @@ -1,6 +1,5 @@ ############################################## # $Id$ -# modified by M. Fischer package main; use strict; use warnings; @@ -8,10 +7,7 @@ use HttpUtils; sub CommandCULflash($$); -my $host = "http://fhem.de"; -my $path = "/fhemupdate4/svn/"; -my $file = "controls_fhem.txt"; -my $dfu = "dfu-programmer"; +my $urlbase = "http://fhem.de/fhemupdate4/svn/"; ##################################### sub @@ -28,65 +24,70 @@ sub CommandCULflash($$) { my ($cl, $param) = @_; - my $modpath = (-d "updatefhem.dir" ? "updatefhem.dir":$attr{global}{modpath}); - my $moddir = "$modpath/FHEM"; - my %ctypes = ( - CUL_V2 => "at90usb162", - CUL_V2_HM => "at90usb162", - CUL_V3 => "atmega32u4", - CUL_V4 => "atmega32u2", + CUL_V2 => + { cmd => 'dfu-programmer at90usb162 erase && '. + 'dfu-programmer at90usb162 flash $filepath && '. + 'dfu-programmer at90usb162 start', + flash => 'CUL_SimpleWrite($defs{$device},"B01");sleep(4); undef;' }, + CUL_V2_HM => + { cmd => 'dfu-programmer at90usb162 erase && '. + 'dfu-programmer at90usb162 flash $filepath && '. + 'dfu-programmer at90usb162 start', + flash => 'CUL_SimpleWrite($defs{$device},"B01");sleep(4); undef;' }, + CUL_V3 => + { cmd => 'dfu-programmer atmega32u4 erase && '. + 'dfu-programmer atmega32u4 flash $filepath && '. + 'dfu-programmer atmega32u4 start', + flash => 'CUL_SimpleWrite($defs{$device},"B01");sleep(4); undef;' }, + CUL_V4 => + { cmd => 'dfu-programmer atmega32u2 erase && '. + 'dfu-programmer atmega32u2 flash $filepath && '. + 'dfu-programmer atmega32u2 start', + flash => 'CUL_SimpleWrite($defs{$device},"B01");sleep(4); undef' }, ); + my @a = split("[ \t]+", $param); - return "Usage: CULflash , ". - "where is one of ". join(" ", sort keys %ctypes) - if(!(int(@a) == 2 && - ($a[0] eq "none" || ($defs{$a[0]} && $defs{$a[0]}{TYPE} eq "CUL")) && - $ctypes{$a[1]})); + return "Usage: CULflash [FHEM-Device|none] TYPE>, ". + "where TYPE is one of ". join(" ", sort keys %ctypes) + if(int(@a)!=2 || !($a[0] eq "none" || $defs{$a[0]}) || !$ctypes{$a[1]}); - my $cul = $a[0]; - my $target = $a[1]; + my $device = $a[0]; + my $type = $a[1]; + my $filename = $a[1].".hex"; + my $fwdir = $attr{global}{modpath} . "/FHEM/firmware"; + my $filepath = "$fwdir/$filename"; ################################ - # First get the index file to prove the file size - my $filetimes = GetFileFromURL("$host$path$file"); - return "Can't get $host$path$file" if(!$filetimes); - - my %filesize; - foreach my $l (split("[\r\n]", $filetimes)) { - chomp($l); - next if ($l !~ m/^UPD (20\d\d-\d\d-\d\d_\d\d:\d\d:\d\d) (\d+) (.*)$/); - $filesize{$3} = $2; + # Get the firmware file: + if(! -d $fwdir) { + mkdir($fwdir) || return "$fwdir: $!"; + } + my $content = GetFileFromURL("$urlbase/FHEM/firmware/$filename"); + return "Cannot get $urlbase/FHEM/firmware/$filename" + if(!$content); + if($content !~ m/:00000001FF/) { + Log3 undef, 3, $content; + return "The retrieved $filename is not a correct .hex file"; } - return "FHEM/$target.hex is not found in $host$path$file" - if(!$filesize{"FHEM/$target.hex"}); - ################################ - # Now get the firmware file: - my $content = GetFileFromURL("$host$path/FHEM/$target.hex"); - return "File size for $target.hex does not correspond to $file entry" - if(length($content) ne $filesize{"FHEM/$target.hex"}); - my $localfile = "$moddir/$target.hex"; + my $localfile = "$filepath"; 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; - - if($cul ne "none") { - CUL_SimpleWrite($defs{$cul}, "B01"); - sleep(4); # B01 needs 2 seconds for the reset + if($device ne "none" && $ctypes{$type}{flash}) { + my $ret = eval $ctypes{$type}{flash}; + Log 1, "CULflash $device: $ret" + if($ret); } + my $cmd = eval "return \"$ctypes{$type}{cmd};\""; Log3 undef, 1, "CULflash $cmd"; - my $result = `$cmd`; + my $result = `($cmd) 2>&1`; Log3 undef, 1, "CULflash $result"; return $result; } -# vim: ts=2:et 1; =pod @@ -95,15 +96,18 @@ CommandCULflash($$)

CULflash

    - CULflash <CUL-Name> <CUL-Version>
    + CULflash [fhem-device|none]; <TYPE>

    - Download the CUL firmware from a nightly SVN chekout and flash the - hardware. Currently only the CUL is supported with its versions: + Download the firmware from a nightly SVN chekout and flash the + hardware. + Currently the CUL is supported with its versions: CUL_V2, CUL_V2_HM, CUL_V3, CUL_V4.
    - Note: dfu-programmer has to be installed in the path, this is - already the case with the Fritz!Box 7390 image from fhem.de
    + If the fhem-device is none, than the inserted device must already be in the + flash-mode.
    + Note:for flashing the CUL dfu-programmer has to be installed in the + path, this is already the case with the Fritz!Box 7390 image from + fhem.de
    - If the CUL is not yet flashed, then specify "none" as CUL-Name. Example:
      CULflash CUL CUL_V3
      @@ -113,6 +117,33 @@ CommandCULflash($$) normal on the FB7390.
    - =end html + +=begin html_DE + + +

    CULflash

    +
      + CULflash [fhem-device|none]; <TYPE>
      +
      + Lädt die spezifizierte Firmware von fhem.de und programmiert das + angeschlossene Gerät. + Z.Zt unterstützt wird das CUL und folgende Versionen: + CUL_V2, CUL_V2_HM, CUL_V3, CUL_V4.
      + Falls als fhem-device none angegeben wurde, dann muss sich das + angeschlossene Gerät bereits in flash-mode befinden.
      + Achtung:Für CUL flashen muss dfu-programmer installiert und im + Pfad auffindbar sein, das ist der Fall bei dem Fritz!BOX 7390 Paket von + fhem.de
      + + Beispiele: +
        + CULflash CUL CUL_V3
        + CULflash none CUL_V3
        +
      + Achtung: die Meldung "dfu-programmer: failed to release interface 0." ist + auf der FB7390 "normal". +
    + +=end html_DE =cut diff --git a/fhem/contrib/fhemupdate.pl b/fhem/contrib/fhemupdate.pl index bad3565c2..ed4da4f95 100755 --- a/fhem/contrib/fhemupdate.pl +++ b/fhem/contrib/fhemupdate.pl @@ -26,127 +26,121 @@ die "SVN failed, exiting\n" if($?); `../copyfiles.sh`; -for(my $loop = 0; $loop < 2; $loop++) { - ################################# - # new Style - chdir("$homedir/fhem"); - my $uploaddir2= ($loop ? "fhemupdate4" : "fhemupdate2"); - system("mkdir -p $uploaddir2"); +################################# +# new Style +chdir("$homedir/fhem"); +my $uploaddir2 = "fhemupdate4"; +system("mkdir -p $uploaddir2"); - my %filelist2 = ( - "./fhem.pl.txt" => { type=>",fhem,", dir=>"." }, - "./CHANGED" => { type=>",fhem,", dir=>"." }, - "FHEM/.*.pm" => { type=>",fhem,", dir=>"FHEM" }, - "FHEM/FhemUtils/.*.pm" => { type=>",fhem,", dir=>"FHEM/FhemUtils"}, - "FHEM/FhemUtils/update-.*", => { type=>",fhem,", dir=>"FHEM/FhemUtils"}, - "FHEM/lib/.*.pm" => { type=>",fhem,", dir=>"FHEM/lib"}, - "FHEM/lib/SWAP/.*.xml" => { type=>",fhem,", dir=>"FHEM/lib/SWAP"}, - "FHEM/lib/SWAP/panStamp/.*" => { type=>",fhem,", dir=>"FHEM/lib/SWAP/panStamp"}, - "FHEM/lib/SWAP/justme/.*" => { type=>",fhem,", dir=>"FHEM/lib/SWAP/justme"}, - "FHEM/lib/Device/.*.pm" => { type=>",fhem,", dir=>"FHEM/lib/Device"}, - "FHEM/lib/Device/Firmata/.*.pm"=>{ type=>",fhem,", dir=>"FHEM/lib/Device/Firmata"}, - "../culfw/Devices/CUL/.*.hex" => { type=>",fhem,", dir=>"FHEM", - dir3=>"FHEM", }, - "www/pgm2/.*" => { type=>"fhem,", dir=>"www/pgm2"}, - "www/jscolor/.*" => { type=>"fhem,", dir=>"www/pgm2"}, - "www/gplot/.*.gplot" => { type=>"fhem,", dir=>"www/pgm2"}, - "www/images/dark/.*.png" => { type=>"fhem,", dir=>"www/pgm2"}, - "www/images/bright/.*.png" => { type=>"fhem,", dir=>"www/pgm2"}, - "www/images/bright/.*.png" => { type=>"fhem,", dir=>"www/pgm2"}, - "www/images/fhemSVG/.*.svg" => { type=>"fhem,", dir=>"www/pgm2"}, - "www/images/openautomation/.*.svg" => { type=>"fhem,", dir=>"www/pgm2"}, - "www/images/openautomation/.*.txt" => { type=>"fhem,", dir=>"www/pgm2"}, - "www/images/darktouchpad/.*.png" => { type=>"fhem,", dir=>"www/pgm2"}, - "www/images/default/.*" => { type=>"fhem,", dir=>"www/pgm2"}, - "www/images/default/remotecontrol/.*" => { type=>"fhem,", dir=>"www/pgm2"}, - "www/images/smallscreen/.*" => { type=>"fhem,", dir=>"www/pgm2"}, - "docs/commandref(_..)?.html" => { type=>"fhem,", dir=>"www/pgm2"}, - "docs/faq(_..)?.html" => { type=>"fhem,", dir=>"www/pgm2"}, - "docs/HOWTO(_..)?.html" => { type=>"fhem,", dir=>"www/pgm2"}, - "docs/fhem.*.png" => { type=>"fhem,", dir=>"www/pgm2"}, - "docs/.*.jpg" => { type=>"fhem,", dir=>"www/pgm2"}, - ); +my %filelist2 = ( + "./fhem.pl.txt" => { type=>",fhem,", dir=>"." }, + "./CHANGED" => { type=>",fhem,", dir=>"." }, + "./configDB.pm" => { type=>",fhem,", dir=>"." }, + "FHEM/.*.pm" => { type=>",fhem,", dir=>"FHEM" }, + "FHEM/FhemUtils/.*.pm" => { type=>",fhem,", dir=>"FHEM/FhemUtils"}, + "FHEM/FhemUtils/update-.*", => { type=>",fhem,", dir=>"FHEM/FhemUtils"}, + "FHEM/lib/.*.pm" => { type=>",fhem,", dir=>"FHEM/lib"}, + "FHEM/lib/.*.xml" => { type=>",fhem,", dir=>"FHEM/lib"}, + "FHEM/lib/SWAP/.*.xml" => { type=>",fhem,", dir=>"FHEM/lib/SWAP"}, + "FHEM/lib/SWAP/panStamp/.*" => { type=>",fhem,", dir=>"FHEM/lib/SWAP/panStamp"}, + "FHEM/lib/SWAP/justme/.*" => { type=>",fhem,", dir=>"FHEM/lib/SWAP/justme"}, + "FHEM/lib/Device/.*.pm" => { type=>",fhem,", dir=>"FHEM/lib/Device"}, + "FHEM/lib/Device/Firmata/.*.pm"=>{ type=>",fhem,", dir=>"FHEM/lib/Device/Firmata"}, + "www/pgm2/.*" => { type=>"fhem,", dir=>"www/pgm2"}, + "www/jscolor/.*" => { type=>"fhem,", dir=>"www/pgm2"}, + "www/codemirror/.*" => { type=>"fhem,", dir=>"www/pgm2"}, + "www/gplot/.*.gplot" => { type=>"fhem,", dir=>"www/pgm2"}, + "www/images/fhemSVG/.*.svg" => { type=>"fhem,", dir=>"www/pgm2"}, + "www/images/openautomation/.*.svg" => { type=>"fhem,", dir=>"www/pgm2"}, + "www/images/openautomation/.*.txt" => { type=>"fhem,", dir=>"www/pgm2"}, + "www/images/default/.*" => { type=>"fhem,", dir=>"www/pgm2"}, + "www/images/default/remotecontrol/.*" => { type=>"fhem,", dir=>"www/pgm2"}, + "docs/commandref(_..)?.html" => { type=>"fhem,", dir=>"www/pgm2"}, + "docs/faq(_..)?.html" => { type=>"fhem,", dir=>"www/pgm2"}, + "docs/HOWTO(_..)?.html" => { type=>"fhem,", dir=>"www/pgm2"}, + "docs/fhem.*.png" => { type=>"fhem,", dir=>"www/pgm2"}, + "docs/.*.jpg" => { type=>"fhem,", dir=>"www/pgm2"}, + "docs/fhemdoc.js" => { type=>"fhem,", dir=>"www/pgm2"}, +); - # Can't make negative regexp to work, so do it with extra logic - my %skiplist2 = ( - # "www/pgm2" => ".pm\$", - ); +# Can't make negative regexp to work, so do it with extra logic +my %skiplist2 = ( +# "www/pgm2" => ".pm\$", +); - # Read in the file timestamps - my %filetime2; - my %filesize2; - my %filedir2; - my %filetype2; - foreach my $fspec (keys %filelist2) { - $fspec =~ m,^(.+)/([^/]+)$,; - my ($dir,$pattern) = ($1, $2); - my $tdir = $filelist2{$fspec}{$loop ? "dir3" : "dir"}; - $tdir = $dir if(!$tdir); - opendir DH, $dir || die("Can't open $dir: $!\n"); - foreach my $file (grep { /$pattern/ && -f "$dir/$_" } readdir(DH)) { - next if($skiplist2{$tdir} && $file =~ m/$skiplist2{$tdir}/); - my @st = stat("$dir/$file"); - my @mt = localtime($st[9]); - $filetime2{"$tdir/$file"} = sprintf "%04d-%02d-%02d_%02d:%02d:%02d", - $mt[5]+1900, $mt[4]+1, $mt[3], $mt[2], $mt[1], $mt[0]; - $filesize2{"$tdir/$file"} = $st[7]; - $filedir2{"$tdir/$file"} = $dir; - $filetype2{"$tdir/$file"} = $filelist2{$fspec}{type}; - } - closedir(DH); +# Read in the file timestamps +my %filetime2; +my %filesize2; +my %filedir2; +my %filetype2; +foreach my $fspec (keys %filelist2) { + $fspec =~ m,^(.+)/([^/]+)$,; + my ($dir,$pattern) = ($1, $2); + my $tdir = $dir; + opendir DH, $dir || die("Can't open $dir: $!\n"); + foreach my $file (grep { /$pattern/ && -f "$dir/$_" } readdir(DH)) { + next if($skiplist2{$tdir} && $file =~ m/$skiplist2{$tdir}/); + my @st = stat("$dir/$file"); + my @mt = localtime($st[9]); + $filetime2{"$tdir/$file"} = sprintf "%04d-%02d-%02d_%02d:%02d:%02d", + $mt[5]+1900, $mt[4]+1, $mt[3], $mt[2], $mt[1], $mt[0]; + $filesize2{"$tdir/$file"} = $st[7]; + $filedir2{"$tdir/$file"} = $dir; + $filetype2{"$tdir/$file"} = $filelist2{$fspec}{type}; } + closedir(DH); +} - chdir("$homedir/fhem/$uploaddir2"); - my %oldtime; - if(open FH, "filetimes.txt") { - while(my $l = ) { - chomp($l); - my ($ts, $fs, $file) = split(" ", $l, 3); - $oldtime{"$file.txt"} = $ts if($file =~ m/fhem.pl/); - $oldtime{$file} = $ts; - } - close(FH); +chdir("$homedir/fhem/$uploaddir2"); +my %oldtime; +if(open FH, "filetimes.txt") { + while(my $l = ) { + chomp($l); + my ($ts, $fs, $file) = split(" ", $l, 3); + $oldtime{"$file.txt"} = $ts if($file =~ m/fhem.pl/); + $oldtime{$file} = $ts; } + close(FH); +} - open FH, ">filetimes.txt" || die "Can't open filetimes.txt: $!\n"; +open FH, ">filetimes.txt" || die "Can't open filetimes.txt: $!\n"; - my %controls = (fhem=>0); - foreach my $k (keys %controls) { - my $fname = "controls_$k.txt"; - $controls{$k} = new IO::File ">$fname" || die "Can't open $fname: $!\n"; - if(open(ADD, "../../fhemupdate.control.$k")) { - while(my $l = ) { - my $fh = $controls{$k}; - print $fh $l; - } - close ADD; - } - } - - my $cnt; - foreach my $f (sort keys %filetime2) { - my $fn = $f; - $fn =~ s/.txt$// if($fn =~ m/.pl.txt$/); - print FH "$filetime2{$f} $filesize2{$f} $fn\n"; - foreach my $k (keys %controls) { +my %controls = (fhem=>0); +foreach my $k (keys %controls) { + my $fname = "controls_$k.txt"; + $controls{$k} = new IO::File ">$fname" || die "Can't open $fname: $!\n"; + if(open(ADD, "../../fhemupdate.control.$k")) { + while(my $l = ) { my $fh = $controls{$k}; - print $fh "UPD $filetime2{$f} $filesize2{$f} $fn\n" - } - my $newfname = $f; - if(!$oldtime{$f} || $oldtime{$f} ne $filetime2{$f}) { - $f =~ m,^(.*)/([^/]*)$,; - my ($tdir, $file) = ($1, $2); - system("mkdir -p $tdir") unless(-d $tdir); - system("cp ../$filedir2{$f}/$file $tdir/$file"); - $cnt++; + print $fh $l; } + close ADD; } - close FH; +} +my $cnt; +foreach my $f (sort keys %filetime2) { + my $fn = $f; + $fn =~ s/.txt$// if($fn =~ m/.pl.txt$/); + print FH "$filetime2{$f} $filesize2{$f} $fn\n"; foreach my $k (keys %controls) { - close $controls{$k}; + my $fh = $controls{$k}; + print $fh "UPD $filetime2{$f} $filesize2{$f} $fn\n" } + my $newfname = $f; + if(!$oldtime{$f} || $oldtime{$f} ne $filetime2{$f}) { + $f =~ m,^(.*)/([^/]*)$,; + my ($tdir, $file) = ($1, $2); + system("mkdir -p $tdir") unless(-d $tdir); + system("cp ../$filedir2{$f}/$file $tdir/$file"); + $cnt++; + } +} +close FH; + +foreach my $k (keys %controls) { + close $controls{$k}; } $ENV{RSYNC_RSH}="ssh"; @@ -161,15 +155,21 @@ if(0) { my $fsize = $st[7]; } +system("cp -p ../culfw/Devices/CUL/*.hex fhemupdate4/FHEM"); +system("cp -p ../culfw/Devices/CUL/*.hex fhemupdate4/FHEM/firmware"); +system("cp -p FHEM/firmware/*.hex fhemupdate4/FHEM/firmware"); + my $rsyncopts="-a --delete --compress --verbose"; system("rsync $rsyncopts fhemupdate4/. fhem.de:fhem/fhemupdate4/svn"); if(-f "commandref_changed") { system("scp docs/commandref.html docs/commandref_DE.html fhem.de:fhem"); } + system("scp CHANGED MAINTAINER.txt fhem.de:fhem"); system("scp fhem.de:fhem/stats/data/fhem_statistics_db.sqlite .."); - chdir("$homedir"); + +system("sh stats/dostats.sh"); system("sh mksvnlog.sh > SVNLOG"); system("scp SVNLOG fhem.de:fhem");