Von der Kamera habe ich 3 Stück zurück gesendet, die alle das gleiche Problem hatten. Vielleicht eine Serie, es führt aber dazu, dass ich die Marke meide
Hier sind 3 subs, die man am besten in eine eigene myUtils packt (ein Teil davon ist aber aus dem IPCAM Modul "geklaut". Dabei geht es um den Filetype):
## Kamera Bilder holen
sub getCamPicSave($;$$) {
my ($dv,$snaps,$delay) = @_;
my @devs=();
if ($dv eq "all") {
@devs=devspec2array("TYPE=IPCAM");
}
else {
@devs=split(",",$dv);
}
foreach my $dev (@devs) {
my $ip=InternalVal($dev,"AUTHORITY","-");
my $auth=AttrVal($dev,"basicauth","-");
my $path=AttrVal($dev,"path","-");
my $storage=AttrVal($dev,"storage","-");
my $camDevice=AttrVal($dev,"camDevice","-");
$snaps=AttrVal($dev,"snapshots",0) unless defined($snaps);
$delay=AttrVal($dev,"delay",2) unless defined($delay);
if ($ip ne "-" && $path ne "-" && $storage ne "-" && $camDevice ne "-" && Value($camDevice) eq "present") {
my $camURI="http://".$ip."/".$path;
my $seqWait=0;
my $seqDelay=$delay;
my $count=0;
for (my $i=0;$i<$snaps;$i++) {
$count=$i+1;
my $param = {
url => $camURI,
timeout => 7,
storage => $storage,
dev => $dev,
count => $count,
callback => \&StoreCamFile,
};
InternalTimer(gettimeofday()+$seqWait, "HttpUtils_NonblockingGet", $param, 0);
$seqWait = $seqWait + $seqDelay;
}
}
else {
my $error="CamPic-Error(s): ";
$error.="Device ($dev) not available. " if ($ip eq "-");
$error.="Device ($dev) has no path attribut. " if ($path eq "-");
$error.="Device ($dev) has no camDevice attribut. " if ($camDevice eq "-");
$error.="Could not fetch picture. Cam-Device ($dev) not present. " if (Value($camDevice) ne "present");
Log 3, $error;
fhem("setreading $dev lastError $error");
}
}
return undef;
}
sub StoreCamFile($$$)
{
my ($hash, $err, $data) = @_;
my $dev = $hash->{dev};
my $dev_hash=$defs{$dev};
readingsBeginUpdate($dev_hash);
if ($err) {
Log 3,"CamPic-Error: Image could not be fetched";
readingsBulkUpdate( $dev_hash, 'lastError', $err );
}
else {
my @imageTypes = qw(JPEG PNG GIF TIFF BMP ICO PPM XPM XBM SVG);
my $imageFormat = camPicGuessFileFormat(\$data);
if( ! grep { $_ eq "$imageFormat"} @imageTypes) {
Log 3, "CamPic-Error: Wrong File-Format";
readingsBulkUpdate( $dev_hash, 'lastError', 'CamPic-Error: Wrong File-Format' );
}
else {
my $storage = $hash->{storage};
my $count = $hash->{count};
my $dateTime = TimeNow();
my $timestamp = $dateTime;
$timestamp =~ s/ /_/g;
$timestamp =~ s/(:|-)//g;
$imageFormat = "JPG" if($imageFormat eq "JPEG");
my $filename=$dev."_".$timestamp.".".lc($imageFormat);
open(FH, ">$storage/$filename");
print FH $data;
close(FH);
readingsBulkUpdate( $dev_hash, 'snapshot'.$count, $filename );
readingsBulkUpdate( $dev_hash, 'last', $filename );
readingsBulkUpdate( $dev_hash, 'snapshots', $count );
}
}
readingsEndUpdate( $dev_hash, 1 );
}
sub camPicGuessFileFormat($) {
my ($src) = shift;
my $header;
my $srcHeader;
open(my $s, "<", $src) || return "can't open source image: $!";
$src = $s;
my $reading = read($src, $srcHeader, 64);
return "error while reading source image: $!" if(!$reading);
local($_) = $srcHeader;
return "JPEG" if /^\xFF\xD8/;
return "PNG" if /^\x89PNG\x0d\x0a\x1a\x0a/;
return "GIF" if /^GIF8[79]a/;
return "TIFF" if /^MM\x00\x2a/;
return "TIFF" if /^II\x2a\x00/;
return "BMP" if /^BM/;
return "ICO" if /^\000\000\001\000/;
return "PPM" if /^P[1-6]/;
return "XPM" if /(^\/\* XPM \*\/)|(static\s+char\s+\*\w+\[\]\s*=\s*{\s*"\d+)/;
return "XBM" if /^(?:\/\*.*\*\/\n)?#define\s/;
return "SVG" if /^(<\?xml|[\012\015\t ]*<svg\b)/;
return "unknown";
}
Hier wird auf die Konfiguration (Pfade) eines IPCAM Devices zugegriffen (DEVICENAME).
Aufgerufen wird sie per
{getCamPicSave("DEVICENAME", "ANZAHLSNAPS", "DELAY")}
Damit werden non-blocking ANZAHLSNAPS Bilder im Abstand von DELAY Sekunden geholt und die Readings im entsprechenden IPCAM-Device aktualisiert. Gibt man ANZAHLSNAPS und DELAY nicht an, wird das jeweils aus dem IPCAM Device geholt. Das ist alles nicht sehr elegant und schnell hin gebaut aber es funktioniert.