Modul IPCAM überarbeitet

Begonnen von Martin Fischer, 01 Februar 2013, 20:30:37

Vorheriges Thema - Nächstes Thema

Brockmann

Zitat von: errazzor am 06 Oktober 2015, 12:04:02
Ich hätte hier nicht gefragt, wenn ich es mit Selbstrecherche hinbekommen hätte...
Das Stichwort remotecontrol ist doch schon gefallen. Im Wiki gibt es dazu einen ausführlichen Artikel nebst Codebeispielen.
http://www.fhemwiki.de/wiki/Remotecontrol

errazzor

Ja, das hatte ich schon versucht, leider klappt es damit bisher auch nicht.
Versucht hatte ich das Beispiel aus dem Wiki.

Ausgangssituation:

-IPCAM Cam1 angelegt
- als Attribut unter anderem: cmdPanLeft | command=6&onestep=0   (damit würde die Cam nach links schwenken)

^^ Es funktioniert, wenn ich im Cam1-Modul oben mit der Befehlsschaltfläche "set" "pan" "left" auswähle / eingebe. Die Kamera schwenkt nach links.

Ich habe nach dem Wiki eine Remotecontrol angelegt, 4 Buttons wie folgt:

cmdPanLeft:REWIND,cmdPanRight:FF,cmdTiltUp:VOLUP,cmdTiltDown:VOLDOWN

Dazu ein Notify:

define notify_Cam1_Test notify Cam1_Test set Cam1 $EVENT

Drücke ich auf der Remotecontrol die Taste "links", sehe ich oben, dass der befehl "cmdPanLeft" gesendet wird - aber es passiert nichts.

Habe ich irgendwo einen Denkfehler?




marvin78

Ah. Eine konkrete Frage. Geht doch ;)

Mache mal ein list aller beteiligten Devices und poste jeweils das Ergebnis in Codetags.

errazzor

Gerne, ich hoffe das hilft:


Internals:
   AUTHORITY  192.168.178.26
   CFGFN
   DEF        192.168.178.26
   NAME       Cam1
   NR         815
   SEQ        0
   STATE      Defined
   TYPE       IPCAM
Attributes:
   basicauth  foo:bar
   cmd01      command=6&onestep=0
   cmdPanLeft command=6&onestep=0
   cmdPanRight command=4&onestep=0
   cmdTiltDown command=0&onestep=0
   cmdTiltUp  command=2&onestep=0
   path       videostream.cgi
   pathPanTilt decoder_control.cgi?
   room       Cam



Internals:
   CFGFN
   NAME       Cam1_Test
   NR         950
   STATE      cmd01
   TYPE       remotecontrol
   Readings:
     2015-10-06 12:58:00   state           cmd01
Attributes:
   rc_iconpath icons/remotecontrol
   rc_iconprefix black_btn_
   room       Cam
   row00      cmd01:REWIND,cmdPanRight:FF,cmdTiltUp:VOLUP,cmdTiltDown:VOLDOWN



Internals:
   CFGFN
   DEF        Cam1_Test set Cam1 $EVENT
   NAME       notify_Cam1_Test
   NOTIFYDEV  Cam1_Test
   NR         963
   NTFY_ORDER 50-notify_Cam1_Test
   REGEXP     Cam1_Test
   STATE      2015-10-06 12:58:00
   TYPE       notify
   Readings:
     2015-10-06 12:18:37   state           active
Attributes:
   room       Cam


marvin78

Du hast es oben selbst geschrieben

Zitat^^ Es funktioniert, wenn ich im Cam1-Modul oben mit der Befehlsschaltfläche "set" "pan" "left" auswähle / eingebe. Die Kamera schwenkt nach links

Der Befehl heißt schlicht nicht

set Cam1 cmdPanLeft

sondern

set Cam1 pan left

Und so musst du auch deine RemoteControl konfigurieren.

Das meinte ich mit "commandref lesen". Es steht drin.

errazzor

#80
Ok, alles klar. Ich habs hinbekommen.

row00      pan left:REWIND [...]

Damit funktioniert es. Freue mich sehr, vielen Dank für die Hilfe.

Manchmal braucht es halt Denkanstöße oder einen Schubs in die richtige Richtung.
Danke nochmal.

marvin78

#81
Sollte folgendes nicht funktionieren

attr Cam1_Test  row00 pan left:REWIND

"erfinde" einfach selber einen Befehlf und übersetze im im notify (am besten mit einer eigenen sub in einer myUtils).

Beispiel:

attr Cam1_Test row00 set Cam1 left:REWIND

als Button in der RC.

Das notify (kann dann für alle Events gelten):

define notify_Cam1_Test notify Cam1_Test {myCamRemote($EVENT)}

Und dann die sub in der myUtils:

sub myCamRemote($) {
  my ($EVENT)=@_;

  if ($EVENT eq "left") {
    fhem("set Cam1 pan left");
  }
  return undef;
}


Das bitte als Anregung sehen. Denkanstöße gab's hier schon genug. Leider hast du noch nicht weiter gedacht. Versuche die Dinge zu verstehen und nicht einfach nur nach zu machen.

errazzor

#82
Ich verstehe was Du sagen willst.

Ich habe gerade festgestellt, dass es eigentlich mehr Zufall ist, dass die Kommandos funktionieren.

Also mit "set pan left" wird halt offenbar ein direkter Befehl in der Kamera bzw. im Modul ausgeführt, ich dachte die ganze Zeit, der Befehl liest dann das entsprechende cmd-Attribut aus. Ist aber natürlich nicht so.

Eigentlich wollte ich die Befehle bzw. URLs aus den Attributen verwenden, weil ich damit auch bestimmte Positionen anfahren kann. Müsste ja eigentlich auch irgendwie gehen.
Muss ich mal weitertesten.

marvin78

Probiere mal folgendes:

attr Cam1_Test  row00 /pan left:REWIND/

Ich bin nicht sicher, ob das funktioniert.

Es ist aber auch nichts falsch daran, eine sub zu verwenden. Im Gegenteil. Das bietet einem flexible Erweiterungsmöglichkeiten.

Jojo11

Hallo,

wäre es vielleicht möglich, die Anzahl der custom commands im IPCAM-Modul von 15 auf mindestens 30 anzuheben? Vom code her sehe ich (als Nicht-Programmierexperte) keine Schwierigkeiten - spricht irgendwas dagegen? Mit 15 komme ich leider nicht aus  :-\

schöne Grüße
Jo

speex

Hallo Marvin, ich versuche gerade deine getsnap Non Blocking Sub zu übernehmen allerdings hat er bei mir ein Problem mit dem cgi jpeg das meine D-Link Cam erzeugt:
image/jpeg.cgi

Er schmeisst mir immer den Fehler das dass File Format nicht korrekt sei:
lastError | CamPic-Error: Wrong File-Format

Hat da jemand Rat wie ich den Code anpassen könnte?

marvin78

Dann versuche doch mal den Check auf Filetype auszukommentieren.

speex

#87
Jetzt bin ich schon einen Schritt weiter es wird eine datei erzeugt allerdings mit der Dateiendung unknown?

Wie muss ich das denn für die cgi endung anpassen das mir dort ein JPG erzeugt wird.

Mein Code sieht nun so aus:
## 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 "-") {
              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);
  { {
          my $imageFormat = camPicGuessFileFormat(\$data);
          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";
}


Erzeugt bei mir folgende Datei:
IPCam_20151020_153101.unknown

Wenn ich hier unknown durch jpg ersetze ist das Bild auch nicht funktional sowie die dateigrösse macht mich auch stutzig von 94byte die Bilder die das IPCam Device von sich aus holt sind ca. 22-25kb groß.

Der path zu meiner D-Link DCS-942L ist:
image/jpeg.cgi


stocher leider irgendwie im trüben, danke für die Tipps. :)

Jojo11

Ein recht verbreitetes Problem scheint zu sein, dass manche Kameras kein jpg sondern eine html-Seite zurückgeben. Dann gibt es ebenfalls diese Meldung.

schöne Grüße
Jo


marvin78

Viele Kameras haben 2 Funktionen, ein Bild zu liefern. Eine liefert ein HTML und eine ein JPEG.