Neues Modul für Epson-Projektoren

Begonnen von henryk, 31 Mai 2013, 18:26:09

Vorheriges Thema - Nächstes Thema

henryk

Moin,

Ich habe nach längerer Rumfummelei (Liebe Güte ist Perl eine schlimme Sprache) ein Modul geschrieben für meinen Epson-Projektor. Es benutzt einen internen Timer um den Projektor nach seinem Zustand zu pollen (Lampenbetriebszeit, Betriebszustand, angezeigter Eingang, ...) und erlaubt die wichtigsten Funktionen zu steuern: An/Aus, Eingang ändern, Bild schwarzschalten.

Das ESCVP21-Kommunikationsinterface ist, soweit ich der Doku entnehmen kann, an vielen, wenn nicht sogar den meisten Epson-Projektoren vorhanden. Diese Grundfunktionen sollten überall gehen. Es gibt 3 verschiedene Anschlussmöglichkeiten: USB (soweit ich sehen kann wird das dann doch wieder ein COM-Port, für Windows mit einem Epson-Treiber, für Linux geht es evt. einfach so? hat jemand ein Gerät zum Testen?), RS-232 und Ethernet. Die ersten beiden müssten mit dem Modul einfach so funktionieren. Selbst teste ich mit einem EH-TW3000 und RS232 an einem RS232-USB-Konverter. Das Ethernet ist ein bisschen anders, da bräuchte ich jemanden der so ein Gerät hat um das unterstützen zu können.

Die Eingänge des Projektors werden normalerweise durch zweistellige Hex-Werte bezeichnet. Ich habe eine Tabelle eingebaut, aus der Doku, die das in vermutlich genehmere Zeichenfolgen übersetzt (also etwa analog-rgb2 statt 21 für den VGA-Eingang).


Ein Problem habe ich noch: Wenn ich in FHEMWEB longpoll auf 1 setzt bekomme ich asynchron die Veränderungen der Readings im Webinterface angezeigt. Sehr schön. Ausser für state. Mache ich da was falsch im Modul oder hab ich was falsch konfiguriert oder ist das einfach nur konterintuitiv?

--
Henryk Plötz
Grüße aus Berlin

henryk

Moin,

ich hab das Modul etwas weiter angepasst um sich an die allgemeinen Konventionen der anderen AV-Module zu halten (YAMAHA, Denon, VIERA): Eingänge umgeschaltet werden jetzt mit "set ... input ..." (statt vorher mit source, wie das im Protokoll heisst), und das "set ... mute" nimmt jetzt ein optionales on/off-Argument, dafür gibt's kein unmute mehr. Ausserdem habe ich die Magie von webCmd und devStateIcon halbwegs durchschaut, so dass jetzt bessere Darstellung/Kommandos in FHEMWEB zu sehen ist/sind.

Die Berechnung von state habe ich auch geändert, das ist jetzt status-eingang (dank devStateIcon wird trotzdem ein "on"-Icon angezeigt). Diese Form wird auch von set akzeptiert, so dass LightScene den aktuellen Zustand lesen und schreiben können sollte (ungestet).

Weil Anhängen hier doof ist, hab ich's auf github getan: https://raw.github.com/henryk/fhem-escvp21/master/FHEM/70_ESCVP21.pm
(Eine controls-Datei für update habe ich nicht angelegt, weil ich hoffe dass das Modul in FHEM integriert werden kann.)

--
Henryk Plötz
Grüße aus Berlin

rudolfkoenig

Hallo Henryk,

wenn ich es in fhem/contrib einchecken soll, sag Bescheid.
Wenn Du bereit bist das Modul hier zu supporten, dann schick mir bitte Dein sourceforge account.

Gruss,
  Rudi

henryk

Moin,

Zitat von: rudolfkoenig schrieb am Sa, 01 Juni 2013 10:22Wenn Du bereit bist das Modul hier zu supporten, dann schick mir bitte Dein sourceforge account.

Ja, gerne. Mein Sourceforge-Name ist "henryk". Was ist der Unterschied zwischen contrib/ und nicht?

Bitte die aktuelle Version von github nehmen, hab da jetzt alles drin was ich drin haben wollte, inkl. Doku auf Deutsch und Englisch.

--
Henryk Plötz
Grüße aus Berlin

rudolfkoenig

Hab Dich in sourceforge hinzugefuegt.

fhem/FHEM: hierher gehoeren nur dokumentierte und in Forum betreute (neudeutsch supportete) Module. Alles andere kommt nach fhem/contrib. FHEM wird per update aktualisiert, contrib nicht.

>  Bitte die aktuelle Version von github nehmen...

Das ist jetzt Deine Aufgabe :) Bitte auch fhem/MAINTAINER.txt aktualisieren.

hatamoto

Hallo Henryk,

bin seit kurzem auch Besitzer eines Epson Beamers und würde gerne deine Steuerung bei mir einbauen.
Einen USB-RS232-Adapter habe ich mir schon besorgt. Wie hast Du den Adapter in der .cfg definiert (Type)?
define rs232 <type> /dev/ttyUSB0

Gruß Chris

hatamoto

Nach längerem Ausprobieren und Testen habe ich den USB-RS232-Adapter und das Modul nun zum Laufen gebracht.
Funktioniert alles wie gewünscht.
Jedoch taucht im log ein Fehler auf:
"Use of uninitialized value in split at ./FHEM/70_ESCVP21.pm line 454"
Auswirkungen konnte ich jedoch bisher keine feststellen.

Gruß Chris

gandy

Wird das Modul noch weiterentwickelt? Ich hätte einen patch parat, der obigen Fehler behebt.

Grüße,
Andy.
fhem (svn) auf i5-4210U NUC
2x HMLAN, 19x HM-SEC-RHS, 15x HM-LC-Bl1PBU-FM, etc.
ODYS Neron Tablet / Android 4.2
Samsung Galaxy Tab 2 10.1N / Android 4.1.2
Samsung Galaxy Note / Android 6.0.1

volschin

Hallo Andy,
hast Du ein Feedback bekommen? Ich möchte das Modul auch einsetzen und wäre an dem Patch interessiert.

Kannst Du ihn hier posten?

Die Datei habe ich nur auf github gefunden, nicht aber in contrib. Stand 1 Jahr alt.

Gruß,
Veit
Intel NUC+Ubuntu 24.04+Docker+FHEM6
HomeMatic: HM-MOD-RPI-PCB+HM-USB-CFG2+hmland+diverse, HUE: Hue-Bridge, RaspBee+deCONZ+diverse
Amzn Dash-Buttons, Siro Rollos
4xRPi, 4xCO20, OWL+USB, HarmonyHub, FRITZ!Box 7590, Echo Dots+Show8, HomeBridge

hillbicks

Wird sicher nicht jeder einen HTPC mir Linux am Beamer betreiben, aber für diejenigen die das haben reicht der cec-cient vollkommen aus.  Mache damit meinen Epson tw7200 an und aus wenn das mediacenter an oder ausgeschaltet wird. Bei Interesse kann  ich hier den Code einstellen

Sent from my Xperia Z2 Tablet Wifi using Tapatalk


gandy

@Veit: Ich habe nur eine kleine Abfrage in ESCVP21_IssueQueuedCommand() eingebaut, vor dem unglücklichen split-Kommando in besagter Zeile 454:

sub ESCVP21_IssueQueuedCommand($)
{
  my ($hash) = @_;
  # If a command is still active we can't do anything
  if($hash->{ActiveCommand}) {
    return;
  }
  return unless defined $hash->{CommandQueue};

  ($hash->{ActiveCommand}, $hash->{CommandQueue}) = split(/\|/, $hash->{CommandQueue}, 2);


Beste Grüße,
Andy.
fhem (svn) auf i5-4210U NUC
2x HMLAN, 19x HM-SEC-RHS, 15x HM-LC-Bl1PBU-FM, etc.
ODYS Neron Tablet / Android 4.2
Samsung Galaxy Tab 2 10.1N / Android 4.1.2
Samsung Galaxy Note / Android 6.0.1

volschin

Hallo Andy,
super, danke. Mein RasPi serial Port Modul ist angekommen und ich werde am Wochenende mal ein bisschen testen.

Gruß
Veit
Intel NUC+Ubuntu 24.04+Docker+FHEM6
HomeMatic: HM-MOD-RPI-PCB+HM-USB-CFG2+hmland+diverse, HUE: Hue-Bridge, RaspBee+deCONZ+diverse
Amzn Dash-Buttons, Siro Rollos
4xRPi, 4xCO20, OWL+USB, HarmonyHub, FRITZ!Box 7590, Echo Dots+Show8, HomeBridge

Astrofreak85

Hi...hat das Modul noch jemand am laufen?
klappt bei mir nämlich aktuell nicht so richtig  :-/

hab ein USB->RS232 Adapter

Astrofreak85

Auf wundersame weise klappt es auf einmal...komisch

Genial :) Jetzt geht endlich das komplette Heimkino mit nur einem Knopfdruck^^

tobi_555

Hallo,

ich versuche gerade die Betriebsstunden auf den EIB zu bringen, das klappt aber nicht wirklich.

hier meine conf:
define Bea_2_KNX_2 notify Beamer:LAMP:.* set 12_Beamer_Betriebsstunden value $VALUE
attr Bea_2_KNX_2 group Beamer zu KNX
attr Bea_2_KNX_2 room Gateway

define 12_Beamer_Betriebsstunden EIB 12/0/0
attr 12_Beamer_Betriebsstunden IODev tul
attr 12_Beamer_Betriebsstunden alias 12_Beamer_Betriebsstunden_12/0/0
attr 12_Beamer_Betriebsstunden model dpt7
attr 12_Beamer_Betriebsstunden room EIB


In den Readings habe ich bei LAMP 884 Stunden
Die Eib-Adresse kann ich auch beschreiben.

Jetzt muss ich den Reading Wert auf die Adresse bekommen.

Jumbo

Hi

habe das Modul gerade entdeckt !

Ich habe einen Epson 9200 , der hat ja einen Netzwerkanschluss. Kann ich das Modul damit betreiben ?

danke im voraus.

tobi_555

Hallo,

so wie ich das lese geht es noch nicht

</ul>
    Per Netzwerk angeschlossene Ger&auml;te:<br><ul>
    Zur Zeit nicht unterst&uuml;tzt
    </ul>
    <br>

Astrofreak85

#17
hmm...verdammt...irgendwas passt hier nicht....musste mein System einmal neu booten, jetzt geht die Ansteuerung nich mehr :-/ der USB->RS232 Adapter ist aber immernoch /dev/ttyUSB0....

:-( steh grad bissl aufm schlauch...

Edit: Einmal Beamer mit FB geschaltet, schon gehts auch aus FHEM wieder...

DJAlex

Hi ich hab hier einen Epson EH-TW8100 einen Raspberry einen USB->RS232 Konverter und würde das gerne testen.
Ich check nur gerade nicht was ich alles machen und installieren muss.

Stimmt das so:

- Raspberry -> FHEM instalieren
- USB->RS232 anschließen
- Modul mit define erstellen? Was genau muss ich da schreiben.
Die Datei aus dem Anhang hier muss ins Verzeichnis FHEM oder und dann der Befehl "reload ..."

Stimmt das so oder muss ich noch irgendwas installieren? auf dem Raspberry oder so?

Danke schon mal

tobi_555

Hallo,

du musst:

1. Raspberry FHEM installieren
2. Die Date von SVG downloaden und mit z.b. WINSCP in das Verzeichnis /opt/fhem/FHEM laden.
3. Jetzt finden wir die Schnittstelle heraus in dem wir mit WINSCP im Verzeichnis /dev/serial/by-id schauen was dort steht:
    in meinem fall usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0
4. Autocreate sollte in der conf.cfg stehen
define autocreate autocreate
5. Die Schnitstelle denfinieren mit:
define Beamer ESCVP21 /dev/ttyUSB0@9600
Meine Schnitstelle ist 0 und die Bautrate ist 9600

dann den Beamer von Hand starten und die FHEM Seite aktualisieren. Wenn du jetzt in FHEM den Beamer öffnest kannst du dir die Readings anschauen.

Wenn es nicht funktioniert kannst du ja mal die Logfile anschauen.

DJAlex

Cool Danke,

ich probier das schnellst möglich und sag bescheid.

rip

Danke für eure Anleitungen!

Bei mir hats gerade geklappt, zumindest mal das EIN/AUS und Quelle wechseln (über einen RS232-Nullmodem-USB-Adapter vom RasPi --> Epson EMP-TW680 Beamer). Habe zuvor den Patch von gandy in die 70_ESCVP21.pm eingegeben.

tobi_555

#22
Hallo,

ich habe mir die Eingänge für die Beamer tw5900, tw6000 und tw6000w hinzugefügt.
Getestet mit tw5900.
tw6000 und tw6000w sind laut doku gleich.

Wenn jemand noch die Eingänge braucht, einfach 70_ ESCVP21 erweitern :
  ['tw(5900|6000|6000w)', [
      ['10', "component-cycle"],
      ['14', "component-ycbcr"],
      ['15', "component-ypbpr"],
      ['1f', "component-auto"],
      ['20', "pc-cycle"],
      ['21', "pc-analog-rgb"],
      ['30', "hdmi1"],
      ['40', "video-cycle"],
      ['41', "video-rca"],
    ]
  ],

und
  ['tw(5900|6000|6000w)', ['10', '14', '15', '1f', '20', '21', '30', '31', '33', '34', '35', '40', '41', '52', 'a0', 'a1', 'a3', 'a4', 'a5', 'd0', 'd1', 'd3', 'd4', 'd5']],


tobi_555

Hallo,

habe noch 3 neue Readings hinzugefügt:

Aspect, Seriennummer und Lampenmodus (Normal oder Eco) wurde getestet mit tw5900

    ESCVP21_QueueGet($hash,"VOL");
    ESCVP21_QueueGet($hash,"SOURCE");
    ESCVP21_QueueGet($hash,"PWR");
    ESCVP21_QueueGet($hash,"MSEL");
    ESCVP21_QueueGet($hash,"MUTE");
    ESCVP21_QueueGet($hash,"LAMP");
    ESCVP21_QueueGet($hash,"ERR");
    ESCVP21_QueueGet($hash,"SNO");
    ESCVP21_QueueGet($hash,"ASPECT");
    ESCVP21_QueueGet($hash,"LUMINANCE");



Ich würde gerne noch die Befehle der Fernbedienung über Fhem steuern, bin mit Pearl noch am Anfang.

Hat mir jemand eine Hilfestellung für den ersten Befehl?


gruß Tobi

Astrofreak85

funktioniert :)
hab auch den tw5900, danke!

tobi_555

#25
So,
habe jetzt mal die Befehle der Doku entnommen und gleich aufgebaut wie die Source Tabelle. Die Befehle für die Remote müssen aber mit KEY ausgeführt werden. Wie kann ich jetzt in FHEM eine Tabelle anzeigen lassen mit der Auswahl an Tasten  ?

my @ESCVP21_REMOTE = (
  ['03', "Menü"],
  ['05', "ESC"],
  ['14', "Auto"],
  ['16', "Enter"],
  ['35', "UP"],
  ['36', "Down"],
  ['37', "Left"],
  ['38', "Right"],
  ['48', "Source"],
);

my @ESCVP21_REMOTE_OVERRIDE = (
  # From documentation
);

my @ESCVP21_REMOTE_AVAILABLE = (
  ['tw(5900|6000|6000w)', ['03', '05', '14', '16', '35', '36', '37', '38', '48']],
);


Hier habe ich mal Remote im WebCMD hinzugefügt
my %table = ESCVP21_SourceTable($hash);
  $hash->{SourceTable} = \%table;
  $attr{$hash->{NAME}}{webCmd} = "on:off:input:remote:";
  $attr{$hash->{NAME}}{devStateIcon} = "on-.*:on:off mute-.*:muted:mute off:off:on";

Jumbo

Weiss niemand wie man das ganze per Netzwerk einbinden kann ? respektive das Modul mit Netzwerk fertigstellen kann ?

Danke

tobi_555

Leider habe ich nur eine RS232 Schnittstelle.

Ich versuche Gerade die Fernbedienung`s Befehle mit ein zu bauen. Habe das für den tw5900 mal angefangen und den Aufbau genau wie die Source Befehle gemacht. Jetzt sollte ich sie noch auf die Schnittstelle schicken und in FHEM bedienbar machen. Aber genau hier hört mein Wissen auf.

Hier mal mein Code mit allen Änderungen:
##############################################
#
# A module to control Epson projectors via ESC/VP21
#
# written 2013 by Henryk Ploetz <henryk at ploetzli.ch>
#
# The information is based on epson322270eu.pdf and later epson373739eu.pdf
# Some details from pl600pcm.pdf were used, but this enhanced support is not
# complete.
#
##############################################
# Definition: define <name> ESCVP21 <port> [<model>]
# Parameters:
#    port - Specify the serial port your projector is connected to, e.g. /dev/ttyUSB0
#           (For consistent naming, look into /dev/serial/by-id/ )
#           Optionally can specify the baud rate, e.g. /dev/ttyUSB0@9600
#   model - Specify the model of your projector, e.g. tw3000 (case insensitive)
#
# 15.01.15 Add new Models for Input: EH-TW5900 / EH-TW6000 / EH-TW6000W
# 23.01.15 Add Readings: serial number / Luminance (00:Normal-30:Auto-40:Full-50:Zoom-70:Wide) / Aspect (00:Normal-01:Eco)


package main;

use strict;
use warnings;
use POSIX;
use DevIo;

my @ESCVP21_SOURCES = (
  ['10', "cycle1"],
  ['11', "analog-rgb1"],
  ['12', "digital-rgb1"],
  ['13', "rgb-video1"],
  ['14', "ycbcr1"],
  ['15', "ypbpr1"],
  ['1f', "auto1"],
  ['20', "cycle2"],
  ['21', "analog-rgb2"],
  ['22', "rgb-video2"],
  ['23', "ycbcr2"],
  ['24', "ypbpr2"],
  ['25', "ypbpr2"],
  ['2f', "auto2"],
  ['30', "cycle3"],
  ['31', "digital-rgb3"],
  ['33', "rgb-video3"],
  ['34', "ycbcr3"],
  ['35', "ypbpr3"],
  ['c0', "cycle5"],
  ['c3', "scart5"],
  ['c4', "ycbcr5"],
  ['c5', "ypbpr5"],
  ['cf', "auto5"],
  ['40', "cycle4"],
  ['41', "video-rca4"],
  ['42', "video-s4"],
  ['43', "video-ycbcr4"],
  ['44', "video-ypbpr4"],
  ['52', "usb-easymp"],
  ['a0', "hdmi2"],
  ['a1', "digital-rgb-hdmi"],
  ['a3', "rgb-video-hdmi"],
  ['a4', "ycbcr-hdmi"],
  ['a5', "ypbpr-hdmi"],
  ['d0', "wirelesshd"],
  ['d1', "digital-rgb-hdmi-2"],
  ['d3', "rgb-video-hdmi-2"],
  ['d4', "ycbcr-hdmi-2"],
  ['d5', "ypbpr-hdmi-2"],
);

my @ESCVP21_SOURCES_OVERRIDE = (
  # From documentation
  ['tw[12]0', [
      ['14', "component1"],
      ['15', "component1"],
    ]
  ],
  ['tw500', [
      ['23', "rgb-video2"],
      ['24', "ycbcr2"],
    ]
  ],
  # From experience
  ['tw3000', [
      ['30', "hdmi1"],
    ]
  ],
  ['tw(5900|6000|6000w)', [
      ['10', "component-cycle"],
      ['14', "component-ycbcr"],
      ['15', "component-ypbpr"],
      ['1f', "component-auto"],
      ['20', "pc-cycle"],
      ['21', "pc-analog-rgb"],
      ['30', "hdmi1"],
      ['40', "video-cycle"],
      ['41', "video-rca"],
    ]
  ],

);

my @ESCVP21_SOURCES_AVAILABLE = (
  ['tw100h?', ['10', '11', '20', '21', '23', '24', '31', '40', '41', '42', '43', '44']],
  ['ts10', ['10', '11', '12', '13', '20', '21', '22', '23', '24', '40', '41', '42']],
  ['tw10h?', ['10', '13', '14', '15', '20', '21', '40', '41', '42']],
  ['tw200h?', ['10', '13', '14', '15', '20', '21', 'c0', 'c4', 'c5', '40', '41', '42']],
  ['tw500', ['10', '11', '13', '14', '15', '1f', '20', '21', '23', '24', '25', '2f', '30', 'c0', 'c4', 'c5', 'cf', '40', '41', '42']],
  ['tw20', ['10', '13', '14', '15', '20', '21', '40', '41', '42']],
  ['tw(600|520|550|800|700|1000)', ['10', '14', '15', '1f', '20', '21', '30', 'c0', 'c3', 'c4', 'c5', 'cf', '40', '41', '42']],
  ['tw2000', ['10', '14', '15', '1f', '20', '21', '30', 'a0', '40', '41', '42']],
  ['tw[345]000', ['10', '14', '15', '1f', '20', '21', '30', 'a0', '40', '41', '42']],
  ['tw420', ['10', '11', '14', '1f', '30', '41', '42']],
  ['tw(5900|6000|6000w)', ['10', '14', '15', '1f', '20', '21', '30', '31', '33', '34', '35', '40', '41', '52', 'a0', 'a1', 'a3', 'a4', 'a5', 'd0', 'd1', 'd3', 'd4', 'd5']],
);

my @ESCVP21_REMOTE = (
  ['03', "Menü"],
  ['05', "ESC"],
  ['14', "Auto"],
  ['16', "Enter"],
  ['35', "UP"],
  ['36', "Down"],
  ['37', "Left"],
  ['38', "Right"],
  ['48', "Source"],
);

my @ESCVP21_REMOTE_OVERRIDE = (
  # From documentation
);

my @ESCVP21_REMOTE_AVAILABLE = (
  ['tw(5900|6000|6000w)', ['03', '05', '14', '16', '35', '36', '37', '38', '48']],
);

sub ESCVP21_Initialize($$)
{
  my ($hash) = @_;
  $hash->{DefFn}    = "ESCVP21_Define";
  $hash->{SetFn}    = "ESCVP21_Set";
  $hash->{ReadFn}   = "ESCVP21_Read"; 
  $hash->{ReadyFn}  = "ESCVP21_Ready";
  $hash->{UndefFn}  = "ESCVP21_Undefine";
  $hash->{AttrList} = "TIMER";  # FIXME, are these needed or are they implicit? "event-on-update-reading event-on-change-reading stateFormat webCmd devStateIcon"
  $hash->{fhem}{interfaces} = "switch_passive;switch_active";
 
}

sub ESCVP21_Define($$)
{
  my ($hash, $def) = @_;
  DevIo_CloseDev($hash);
  my @args = split("[ \t]+", $def);
  if (int(@args) < 2) {
    return "Invalid number of arguments: define <name> ESCVP21 <port> [<model> [<timer>]]";
  }

  my ($name, $type, $port, $model, $timer) = @args;
  $model = "unknown" unless defined $model;
  $timer = 30 unless defined $timer;
  $hash->{Model} = lc($model);
  $hash->{DeviceName} = $port;
  $hash->{CommandQueue} = '';
  $hash->{ActiveCommand} = '';
  $hash->{Timer} = $timer;
  $hash->{STATE} = 'Initialized';

  my %table = ESCVP21_SourceTable($hash);
  $hash->{SourceTable} = \%table;
  $attr{$hash->{NAME}}{webCmd} = "on:off:input";
  $attr{$hash->{NAME}}{devStateIcon} = "on-.*:on:off mute-.*:muted:mute off:off:on";

  my $dev;
  my $baudrate;
  ($dev, $baudrate) = split("@", $port);
  $readyfnlist{"$name.$dev"} = $hash;
  return undef;
}

sub ESCVP21_Ready($)
{
  my ($hash) = @_;
  return DevIo_OpenDev($hash, 0, "ESCVP21_Init");
}

sub ESCVP21_Undefine($$)
{
  my ($hash,$arg) = @_;
  my $name = $hash->{NAME};
  RemoveInternalTimer("watchdog:".$name);
  RemoveInternalTimer("getStatus:".$name);
  DevIo_CloseDev($hash);
  return undef;
}

sub ESCVP21_Init($)
{
  my ($hash) = @_;
  my $time = gettimeofday();
  $hash->{CommandQueue} = '';
  $hash->{ActiveCommand} = "init";
  ESCVP21_Command($hash,"");
  ESCVP21_ArmWatchdog($hash);

  return undef;
}

sub ESCVP21_ArmWatchdog($)
{
  my ($hash) = @_;
  my $time = gettimeofday();
  my $name = $hash->{NAME};

  Log 5, "ESCVP21_ArmWatchdog: Watchdog disarmed";
  RemoveInternalTimer("watchdog:".$name);

  if($hash->{ActiveCommand}) {
    my $timeout;
    if($hash->{ActiveCommand} =~ /^power(On|Off)$/) {
      # Power commands take a while
      $timeout = 60;
    } elsif($hash->{ActiveCommand} =~ /^SOURCE/) {
      # Source changes may incorporate autoadjust and also take some time
      $timeout = 5;
    } else {
      # All others should be faster
      $timeout = 3;
    }

    Log 5, "ESCVP21_ArmWatchdog: Watchdog armed for $timeout seconds";
    InternalTimer($time + $timeout, "ESCVP21_Watchdog", "watchdog:".$name, 0);
  }
}

sub ESCVP21_Watchdog($)
{
  my($in) = shift;
  my(undef,$name) = split(':',$in);
  my $hash = $defs{$name};
 
  Log 3, "ESCVP21_Watchdog: called for command '$hash->{ActiveCommand}', resetting communication";
 
  ESCVP21_Queue($hash, $hash->{ActiveCommand}, 1) unless $hash->{ActiveCommand} =~ /^init/;
 
  my $command_queue_saved = $hash->{CommandQueue};
  ESCVP21_Init($hash);
  $hash->{CommandQueue} = $command_queue_saved;
}

sub ESCVP21_Read($)
{
  my ($hash) = @_;
  my $buffer = '';
  my $line = undef;
  if(defined($hash->{PARTIAL}) && $hash->{PARTIAL}) {
    $buffer = $hash->{PARTIAL} . DevIo_SimpleRead($hash);
  } else {
    $buffer = DevIo_SimpleRead($hash);
  }

  ($line, $buffer) = ESCVP21_Parse($buffer);
  while($line) {
    Log 4, "ESCVP21_Read (" . $hash->{ActiveCommand} . ") '$line'";

    # When we get a state response, update the corresponding reading
    if($line =~ /([^=]+)=([^=]+)/) {
      readingsBeginUpdate($hash);
      readingsBulkUpdate($hash, $1, $2) unless $hash->{READINGS}{$1}{VAL} eq $2;
      ESCVP21_UpdateState($hash);
      readingsEndUpdate($hash, 1);
    }

    my $last_command = $hash->{ActiveCommand};

    if($hash->{ActiveCommand} eq "init") {
      # Wait for the first colon response
      if($line eq ":") {
$hash->{ActiveCommand} = "initPwr";
ESCVP21_Command($hash,"PWR?");
      }
    } elsif ($hash->{ActiveCommand} eq "initPwr") {
      # Wait for the first PWR state response
      if($line =~ /^PWR=.*/) {
$hash->{ActiveCommand} = "";

# Done initialising, begin polling for status
ESCVP21_GetStatus($hash);
      }
    } elsif($line eq ":") {
      # When we get a colon prompt, the current command finished
      $hash->{ActiveCommand} = "";
    }

    if($line eq "ERR" and not $last_command eq "getERR") {
      # Insert an error query into the queue
      ESCVP21_Queue($hash,"getERR",1);
    }

    if($line eq ":") {
      ESCVP21_IssueQueuedCommand($hash);
    }

    ESCVP21_ArmWatchdog($hash);
 
    ($line, $buffer) = ESCVP21_Parse($buffer);
  }

  $hash->{PARTIAL} = $buffer;
  Log 5, "ESCVP21_Read-Tail '$buffer'";
}

sub ESCVP21_Parse($@)
{
  my $msg = undef;
  my ($tail) = @_;
 
  if($tail =~ /^(.*?)(:|\x0d)(.*)$/s) {
    if($2 eq ":") {
      $msg = $1 . $2;
    } else {
      $msg = $1;
    }
    $tail = $3;
  }

  return ($msg, $tail);
}


sub ESCVP21_GetStatus($)
{
  my ($hash) = @_;
  my $name = $hash->{NAME};

  Log 5, "ESCVP21_GetStatus called for $name";

  RemoveInternalTimer("getStatus:".$name);
 
  # Only queue commands when the queue is empty, otherwise, try again in a few seconds
  if(!$hash->{CommandQueue}) {
    InternalTimer(gettimeofday()+$hash->{Timer}, "ESCVP21_GetStatus_t", "getStatus:".$name, 0);

    ESCVP21_QueueGet($hash,"VOL");
    ESCVP21_QueueGet($hash,"SOURCE");
    ESCVP21_QueueGet($hash,"PWR");
    ESCVP21_QueueGet($hash,"MSEL");
    ESCVP21_QueueGet($hash,"MUTE");
    ESCVP21_QueueGet($hash,"LAMP");
    ESCVP21_QueueGet($hash,"ERR");
    ESCVP21_QueueGet($hash,"SNO");
    ESCVP21_QueueGet($hash,"ASPECT");
    ESCVP21_QueueGet($hash,"LUMINANCE");

  } else {
    InternalTimer(gettimeofday()+5, "ESCVP21_GetStatus_t", "getStatus:".$name, 0);
  }
}

sub ESCVP21_GetStatus_t($)
{
  my($in) = shift;
  my(undef,$name) = split(':',$in);
  my $hash = $defs{$name};
  ESCVP21_GetStatus($hash);
}

sub ESCVP21_Set($@)
{
  my ($hash, $name, $cmd, @args) = @_;

  Log 5, "ESCVP21_Set: $cmd";

  my ($do_mute, $do_unmute) = (0,0);

  if($cmd eq 'mute') {
    if($#args == -1) {
      if(defined($hash->{READINGS}{MUTE})) {
if($hash->{READINGS}{MUTE}{VAL} eq "OFF") {
  $do_mute = 1;
} else {
  $do_unmute = 1;
}
      } else {
$do_mute = 1;
      }
    } else {
      if($args[0] eq 'on') {
$do_mute = 1;
      } elsif($args[0] eq 'off') {
$do_unmute = 1;
      }
    }
  } elsif($cmd eq 'on') {
    ESCVP21_Queue($hash,"powerOn");
    ESCVP21_QueueGet($hash,"PWR");
  } elsif($cmd eq 'off') {
    ESCVP21_Queue($hash,"powerOff");
    ESCVP21_QueueGet($hash,"PWR");
  } elsif($cmd eq 'raw') {
    ESCVP21_Queue($hash,join(" ", @args));
  } elsif($cmd eq 'input') {
    if($args[0] eq 'MUTE') {
      $do_mute = 1;
    } else {
      ESCVP21_ChangeSource($hash, $args[0]);
    }
  } elsif($cmd =~ /^([^-]+)-(.*)$/) {
    my ($on,$muted) = (0,0);
    ($on, $muted) = (1, 0) if $1 eq 'on';
    ($on, $muted) = (0, 0) if $1 eq 'off';
    ($on, $muted) = (1, 1) if $1 eq 'mute';

    if($on) {
      ESCVP21_Queue($hash,"powerOn");
      ESCVP21_QueueGet($hash,"PWR");

      ESCVP21_ChangeSource($hash, $2);

      if($muted) {
$do_mute = 1;
      } else {
$do_unmute = 1;
      }

    } else {
      ESCVP21_Queue($hash,"powerOff");
      ESCVP21_QueueGet($hash,"PWR");
    }

  } elsif($cmd eq '?') {
    my %table = %{$hash->{SourceTable}};
    my @inputs = ("MUTE",);
    push @inputs, $table{$_} foreach (sort keys %table);
    return "Unknown argument ?, choose one of on off mute input:" . join(",",@inputs);
  }
 
  if($do_mute) {
    ESCVP21_Queue($hash,"muteOn");
    ESCVP21_QueueGet($hash,"MUTE");
  } elsif($do_unmute) {
    ESCVP21_Queue($hash,"muteOff");
    ESCVP21_QueueGet($hash,"MUTE");
  }

}

sub ESCVP21_ChangeSource($$)
{
  my ($hash, $source) = @_;
  my %table = %{$hash->{SourceTable}};
  my $done = 0;
  while( my ($key, $value) = each %table ) {
    if( lc($source) eq lc($value) ) {
      ESCVP21_Queue($hash,"SOURCE " . uc($key));
      $done = 1;
      last;
    }
  }

  unless($done) {
    if($source =~ /([0-9a-f]{2})(-unknown)?/i) {
      ESCVP21_Queue($hash,"SOURCE " . uc($1));
      $done = 1;
    }
  }

  if($done) {
    ESCVP21_QueueGet($hash,"SOURCE");
    ESCVP21_QueueGet($hash,"MUTE");
  }
}

sub ESCVP21_QueueGet($$)
{
  my ($hash,$param) = @_;
  ESCVP21_Queue($hash,"get".$param);
}

sub ESCVP21_Queue($@)
{
  my ($hash,$cmd,$prepend) = @_;
  if($hash->{CommandQueue}) {
    if($prepend) {
      $hash->{CommandQueue} = $cmd . "|" . $hash->{CommandQueue};
    } else {
      $hash->{CommandQueue} .=  "|" . $cmd;
    }
  } else {
    $hash->{CommandQueue} = $cmd
  }
 
  ESCVP21_IssueQueuedCommand($hash);
  ESCVP21_ArmWatchdog($hash);
}


sub ESCVP21_IssueQueuedCommand($)
{
  my ($hash) = @_;
  # If a command is still active we can't do anything
  if($hash->{ActiveCommand}) {
    return;
  }
 
  ($hash->{ActiveCommand}, $hash->{CommandQueue}) = split(/\|/, $hash->{CommandQueue}, 2);

  if($hash->{ActiveCommand}) {
    Log 4, "ESCVP21 executing ". $hash->{ActiveCommand};
   
    if($hash->{ActiveCommand} eq 'muteOn') {
      ESCVP21_Command($hash, "MUTE ON");
    } elsif($hash->{ActiveCommand} eq 'muteOff') {
      ESCVP21_Command($hash, "MUTE OFF");
    } elsif($hash->{ActiveCommand} eq 'powerOn') {
      ESCVP21_Command($hash, "PWR ON");
    } elsif($hash->{ActiveCommand} eq 'powerOff') {
      ESCVP21_Command($hash, "PWR OFF");
    } elsif($hash->{ActiveCommand} =~ /^get(.*)$/) {
      ESCVP21_Command($hash, $1."?");
    } else {
      # Assume a raw command and hope the user knows what he or she's doing
      ESCVP21_Command($hash, $hash->{ActiveCommand});
    }
  }

}

sub ESCVP21_UpdateState($)
{
  my ($hash) = @_;
  my $state = undef;
  my $onoff = 0;
  my $source = "unknown";
  my %table = %{$hash->{SourceTable}};

  if(defined($hash->{READINGS}{SOURCE})){
    $source = $hash->{READINGS}{SOURCE}{VAL} . "-unknown";
    while( my ($key, $value) = each %table ) {
      if( lc($hash->{READINGS}{SOURCE}{VAL}) eq lc($key) ) {
$source = $value;
last;
      }
    }
  }

  # If it's on or powering up, consider it on
  if($hash->{READINGS}{PWR}{VAL} eq '01' or $hash->{READINGS}{PWR}{VAL} eq '02') {
    if($hash->{READINGS}{MUTE}{VAL} eq 'ON') {
      $state = "mute";
    } else {
      $state = "on";
    }
    $onoff = 1;
    $state = $state . "-" . $source;
  } else {
    $state = "off";
    $onoff = 0;
  }

  readingsBulkUpdate($hash, "state", $state) unless $hash->{READINGS}{state}{VAL} eq $state;
  readingsBulkUpdate($hash, "onoff", $onoff) unless $hash->{READINGS}{onoff}{VAL} eq $onoff;
  readingsBulkUpdate($hash, "source", $source) unless $source eq "unknown" or $hash->{READINGS}{source}{VAL} eq $source;
}

sub ESCVP21_SourceTable($)
{
  my ($hash) = @_;
  my %table = ();
  my @available;
  my @override;

  foreach (@ESCVP21_SOURCES_AVAILABLE) {
    my ($modelre, $available_list) = @$_;
    if( $hash->{Model} =~ /^$modelre$/i ) {
      Log 4, "ESCVP21: Available sources defined by " . $modelre;
      @available = @$available_list;
      last;
    }
  }

  foreach (@ESCVP21_SOURCES_OVERRIDE) {
    my ($modelre, $override_list) = @$_;
    if( $hash->{Model} =~ /^$modelre$/i ) {
      Log 4, "ESCVP21: Override defined by " . $modelre;
      @override = @$override_list;
      last;
    }
  }
 
  foreach (@ESCVP21_SOURCES) {
    my ($code, $name) = @$_;
    if( (!@available) || ($code ~~ @available)) {
      $table{lc($code)} = lc($name);
      if(@override) {
foreach (@override) {
  my ($code_o, $name_o) = @$_;
  if(lc($code_o) eq lc($code)) {
    $table{lc($code)} = lc($name_o);
  }
}
      }
      Log 4, "ESCVP21: " . $code . " is mapped to " . $table{lc($code)};
    }
  }

  return %table;
}

sub ESCVP21_RemoteTable($)
{
  my ($hash) = @_;
  my %table = ();
  my @available;
  my @override;

  foreach (@ESCVP21_REMOTE_AVAILABLE) {
    my ($modelre, $available_list) = @$_;
    if( $hash->{Model} =~ /^$modelre$/i ) {
      Log 4, "ESCVP21: Available Remote keys defined by " . $modelre;
      @available = @$available_list;
      last;
    }
  }

  foreach (@ESCVP21_REMOTE_OVERRIDE) {
    my ($modelre, $override_list) = @$_;
    if( $hash->{Model} =~ /^$modelre$/i ) {
      Log 4, "ESCVP21: Override defined by " . $modelre;
      @override = @$override_list;
      last;
    }
  }
 
  foreach (@ESCVP21_REMOTE) {
    my ($code, $name) = @$_;
    if( (!@available) || ($code ~~ @available)) {
      $table{lc($code)} = lc($name);
      if(@override) {
foreach (@override) {
  my ($code_o, $name_o) = @$_;
  if(lc($code_o) eq lc($code)) {
    $table{lc($code)} = lc($name_o);
  }
}
      }
      Log 4, "ESCVP21: " . $code . " is mapped to " . $table{lc($code)};
    }
  }

  return %table;
}


sub ESCVP21_Command($$)
{
  my ($hash,$command) = @_;
  DevIo_SimpleWrite($hash,$command."\x0d",'');
}

1;

=pod
=begin html

<a name="ESCVP21"></a>
<h3>ESCVP21</h3>
<ul>

  Many EPSON projectors (both home and business) have a communications interface
  for remote control and status reporting. This can be in the form of a serial
  port (RS-232), a USB port or an Ethernet port. The protocol used on this port
  most often is ESC/VP21. This module supports control of simple functions on the
  projector through ESC/VP21. It has only been tested with EH-TW3000 over RS-232.
  The network protocol is similar and may be supported in the future.

  <a name="ESCVP21define"></a>
  <b>Define</b>
  <ul>
    <code>define &lt;name&gt; ESCVP21 &lt;device&gt; [&lt;model&gt; [&lt;timer&gt;]]</code> <br>
    <br>
    USB or serial devices-connected devices:<br><ul>
      &lt;device&gt; specifies the serial port to communicate with the projector.
      The name of the serial-device depends on your distribution and several
      other factors. Under Linux it's usually something like /dev/ttyS0 for a
      physical COM port in the computer, /dev/ttyUSB0 or /dev/ttyACM0 for USB
      connected devices (both USB projector or serial projector using USB-serial
      converter). The numbers may differ, check your kernel log (using the dmesg
      command) soon after connecting the USB cable. Many distributions also offer
      a consistent naming in /dev/serial/by-id/, check there.<br><br>

      You can also specify a baudrate if the device name contains the @
      character, e.g.: /dev/ttyACM0@9600, though this should usually always
      be 9600.<br><br>

      If the baudrate is "directio" (e.g.: /dev/ttyACM0@directio), then the
      perl module Device::SerialPort is not needed, and fhem opens the device
      with simple file io. This might work if the operating system uses sane
      defaults for the serial parameters, e.g. some Linux distributions and
      OSX.  <br><br>

    </ul>
    Network-connected devices:<br><ul>
    Not supported currently.
    </ul>
    <br>

    If a model name is specified (case insensitive, without the "emp-" or "eh-"
    prefix), it is used to limit the possible input source values to the ones
    supported by the projector (if known) and may be used to map certain source
    values to better symbolic names. If the model name isn't specified it defaults
    to "unknown".

    The projector must be queried for readings changes, and the time between
    queries in seconds is specified by the optional timer argument. If it isn't
    specified it defaults to 30.

    Examples:
    <ul>
      <code>define Projector_Living_Room ESCVP21 /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0 tw3000</code><br>
    </ul>


  </ul>
  <br>

  <a name="ESCVP21set"></a>
  <b>Set </b>
  <ul>
    <li>on<br>
Switch the projector on.
</li><br>
    <li>off<br>
Switch the projector off.
</li><br>
    <li>mute [on|off]<br>
'Mute' the projector output, e.g. display a black screen.
If no argument is given, the mute state will be toggled.
</li><br>
    <li>input &lt;source&gt;.<br>
Switch the projector input source. The names are the same as
reported by the 'source' reading, so if in doubt look there.
A raw two character hex code may also be specified.
</li><br>
    <li>&lt;state&gt;-&lt;source&gt;<br>
Switch state ("on", "off" or "mute") and source in one command.
The source is ignored if the new state is off.
</li><br>

  </ul>

  <a name="ESCVP21get"></a>
  <b>Get</b>
  <ul>N/A</ul>

  <a name="ESCVP21attr"></a>
  <b>Attributes</b>
  <ul>
    <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  </ul>
  <br>
</ul>

=end html
=begin html_DE

<a name="ESCVP21"></a>
<h3>ESCVP21</h3>
<ul>

  Viele EPSON-Projektoren sind mit einem Anschluss f&uuml;r die Fernbedienung von einem
  Computer ausgestattet. Das ist entweder ein serieller Anschluss (RS-232), ein
  USB-Anschluss, oder ein Ethernet-Anschluss. Das verwendete Protokoll ist h&auml;ufig
  ESC/VP21. Dieses Modul unterst&uuml;tzt grundlegende Steuerungsfunktionen des Projektors
  &uuml;ber ESC/VP21 f&uuml;r Projektoren mit USB- (ungestet) und RS/232-Anschluss. Das
  Netzwerkprotokoll ist &auml;hnlich und k&ouml;nnte evt. in der Zukunft unterst&uuml;tzt werden.

  <a name="ESCVP21define"></a>
  <b>Define</b>
  <ul>
    <code>define &lt;name&gt; ESCVP21 &lt;device&gt; [&lt;model&gt; [&lt;timer&gt;]]</code> <br>
    <br>
    Per USB oder seriell angeschlossene Ger&auml;te:<br><ul>
      &lt;device&gt; gibt den seriellen Port an, an dem der Projektor angeschlossen
      ist. Der Name des Ports h&auml;ngt vom Betriebssystem bzw. der Distribution un
      anderen Faktoren ab. Unter Linux ist es h&auml;ufig etwas &auml;hnliches wie /dev/ttyS0
      bei einem fest installierten seriellen Anschluss, oder /dev/ttyUSB0 oder
      /dev/ttyACM0 bei einem per USB angeschlossenem Ger&auml;t (entweder der Projektor
      &uuml;ber USB, oder ein serieller Projektor mit einem USB-RS-232-Wandler). Die
      Zahl kann abweichen, genaue Angaben sollten im Kernel-Log zu finden sein (mit
      dem dmesg-Befehl anzusehen), nachdem das USB-Kabel verbunden wurde. Viele
      Distributionen bieten ausserdem ein konsistentes Namensschema (&uuml;ber symlinks)
      in /dev/serial/by-id/ an.<br><br>
     
      Zus&auml;tzlich kann eine Baudrate angegeben werden, durch Verwendung des @-Zeichens
      in der device-Angabe, z.B. /dev/ttyACM0@9600. Das sollte allerdings eigentlich
      immer 9600 sein.<br><br>

      Wenn die Baudrate als "directio" angegeben wird (z.B. /dev/ttyACM0@directio),
      dann wird das Perl-Modul Device::SerialPort nicht ben&ouml;tigt und fhem spricht
      das Ger&auml;t mit einfacher Datei-I/O an. Das kann funktionieren, wenn das
      Betriebssystem sinnvolle Standardwerte f&uuml;r die seriellen Parameter verwendet,
      z.B. unter einigen Linux-Distributionen und OSX.<br><br>

    </ul>
    Per Netzwerk angeschlossene Ger&auml;te:<br><ul>
    Zur Zeit nicht unterst&uuml;tzt
    </ul>
    <br>

    Wenn der Modellname angegeben wird (majuskelignorant, ohne das Pr&auml;fix "emp-"
    oder "eh-"), wird er benutzt, um die Liste der Eing&auml;nge auf die tats&auml;chlich
    vorhandenen zu reduzieren (falls bekannt) und unter Umst&auml;nden auch, um manche
    Eing&auml;nge auf bessere Namen umzubenennen. Wenn das Projektormodell nicht
    angegeben wird, wird standardm&auml;&szlig;ig "unknown" angenommen.<br><br>


    Der Projektor wird von einem internen Timer regelm&auml;&szlig;ig nach Status&auml;nderungen
    gepollt. Die Zeit zwischen zwei Abfragen, in Sekunden, wird mit dem optionalen
    timer-Argument angegeben. Wenn es nicht spezifiziert wird, wird standardm&auml;&szlig;ig
    30 angenommen.<br><br>

    Beispiele:
    <ul>
      <code>define Beamer_Wohnzimmer ESCVP21 /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0 tw3000</code><br>
    </ul>


  </ul>
  <br>

  <a name="ESCVP21set"></a>
  <b>Set </b>
  <ul>
    <li>on1<br>
Schaltet den Projektor an.
</li><br>
    <li>off<br>
Schaltet den Projektor aus.
</li><br>
    <li>mute [on|off]<br>
Abschalten der Ausgabe, also zum Beispiel durch Anzeigen eines
schwarzen Bildschirms.
Wenn kein Argument angegeben wird, wird der Abschaltungszustand
invertiert.
</li><br>
    <li>input &lt;source&gt;.<br>
&Auml;ndern des Projektoreingangs. Die Namen stammen aus der Dokumentation
und sind dieselben die im "source"-Reading ausgegeben werden.
Der Eingang kann auch direkt als zwei-Zeichen Hexcode angegeben werden.
</li><br>
    <li>&lt;state&gt;-&lt;source&gt;<br>
&Auml;ndert den Projektorzustand ("on", "off", oder "mute") und den
gew&auml;hlten Eingang in einem einzigen Kommando. Der Eingang wird
ignoriert, wenn der neue Zustand "off" ist.
</li><br>

  </ul>

  <a name="ESCVP21get"></a>
  <b>Get</b>
  <ul>N/A</ul>

  <a name="ESCVP21attr"></a>
  <b>Attributes</b>
  <ul>
    <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  </ul>
  <br>
</ul>

=end html_DE
=cut


gibnix

Zitat von: Jumbo am 24 Januar 2015, 10:36:51
Weiss niemand wie man das ganze per Netzwerk einbinden kann ? respektive das Modul mit Netzwerk fertigstellen kann ?

Danke

Ich weiß, die Frage ist schon 1,5 Jahre alt. Trotzdem hier die Antwort für Suchfunktionsbenutzer  ;)

Das ganze funktioniert analog zu CUL per Netzwerk, erst den RS232-Server einrichten wie unter http://www.fhemwiki.de/wiki/CUL_ueber_Netz beschrieben.

Danach den Beamer definieren:

define Beamer ESCVP21 192.168.0.1:2323

(ip und port an eigenes Netzwerk anpassen)


Owel

Hallo, bin gerade über das Modul gestolpert und möchte auch gern meinen eh-tw4400 über fhem steuern. Habe dazu schon 2 versciedene rs232-<usb Adapter bestellt. Aber kein scheint so richtig zu funkionieren (Weder am Windows Laptop noch am Raspi)
Welchen rs232 Adapter könnt ihr empfehlen?
(Muss nicht unbedingt usb sein, kann auch direkt an die GPIO gehen von mir aus)

Owel

Hat jetzt für mich funktioniert. Beide Adapter funktionieren.
Hatte auf der Schnittstelle eine 'hello message' erwartet, sprich nen prompt, aber kommt ja nichts...

Aber wenn ich Befehle hinschicke, dann kommt was zurück.
funktioniert also!

Jetzt versuche ich dann noch das Modul hier zum laufen zu bekommen. Wo bekomme ich ein akutelles release her? Scheint ja jetzt doch nicht maintained zu sein...


Owel

Wieder eine Erfolgsmeldung!

Habe das Modul aus Git geladen, und die Abfrage vor dem Split eingefügt.
Es funktioniert tadellos!

Nur jetzt habe ich das nächste Problem.
Ich habe zwei Fhem installationen...
Fhem A: Hauptfhem, hier läuft alles!
Fhem B: hier ist nur das Epson Modul, da ich kein Kabel bis Fhem A legen kann...

Wie kann ich nun den Beamer von Fhem A zugreifbar machen?
Any ideas?


hachinga

Hallo zusammen,

Danke erstmal für das Modul, genau danach habe ich gesucht! Leider bekomme ich es mit meinem Epson EH-TW3200 nicht zum laufen. Das Modul versucht ständig eine Verbindung aufzubauen, es kommt aber anscheinend keine Rückmeldung vom Beamer. Mehrfache Neustarts und ein Kabelwechsel haben nichts gebracht. Auch eine Ansteuerung über minicom klappt nicht. Kann es sein, dass man die RS232 Schnittstelle erst im Beamer aktivieren muss? Im Menü des Beamers kann ich leider nichts finden, in der Anleitung steht zum Thema RS232 gar nichts. Kann mir jemand helfen?

Danke & Gruß

Thorsten

eldrik

#33
Moin,

Ich hebe den Thread einmal nach oben, bin seit kurzem Besitzer eines TW5650 und mit ein wenig Recherche konnte ich die integrierte Webschnittstelle (WLAN Anbindung) zur Steuerung des Beamers, wie sie auch die Espon iprojection App verwendet, anzapfen.

Bei Interesse kann ich gerne die Python Datei posten, die ich bei meiner Suche gefunden habe und um weitere Aufrufsoptionen erweitert habe.

Vielleicht hat ja auch jemand Lust und den Skill dies in das Fhem Modul einzupflegen als weitere Schnittstellenvariante für die Moduldefinition?

Greetz
Eldrik

dathu

Hallo Elderik,

ich würde auch gerne meinen TW6700 einbinden und dabei auf eine IR Lösung verzichten.
Ich hatte zunächst gehofft den Beamer über USB steuern zu könne.

Bezüglich der WLAN Schnittstelle konnte ich leider nicht so viel finden. Könntest du mir deine Python Datei zu Verfügung stellen?

Grüße,
David

Mickey Mouse

also wenn es eine Möglichkeit gäbe z.B. einen Speicher per (W)LAN direkt aufzurufen, dann wäre ich auch sehr interessiert!

zur Zeit mache ich das über ein "Makro" in FHEM das über den Harmony Hub per IR Kommandos die Sache aufruft (eine normale "Eingabe" simuliert: Mem, down, down, OK, down, down, ...). Das funktioniert zwar im Prinzip, ist aber nicht besonders elegant.
erstmal muss man mit ein paar dummy ESC "klare Verhältnisse schaffen" (falls gerade ein Menü offen ist) und viel ärgerlicher: das ganze dauert doch eine ganze Weile (zu schnell kann ich die Kommandos nicht senden, dann wird immer mal eins verschluckt) und wenn sich z.B. die Auflösung gerade ändert (man hat gerade das Menü verlasen und den Film gestartet) dann nimmt der Epson (hier 9300) keine Befehle an.

eldrik

Zitat von: dathu am 21 Februar 2018, 15:42:20
Hallo Elderik,

ich würde auch gerne meinen TW6700 einbinden und dabei auf eine IR Lösung verzichten.
Ich hatte zunächst gehofft den Beamer über USB steuern zu könne.

Bezüglich der WLAN Schnittstelle konnte ich leider nicht so viel finden. Könntest du mir deine Python Datei zu Verfügung stellen?

Grüße,
David

Hi,

anbei der Code für das Python Skript

#!/usr/bin/python3

import requests
import re
import time
import sys

projectorAddress = 'http://IPAdresse'
username = 'EPSONMOBILE'
password = ''

auth = requests.auth.HTTPBasicAuth(username, password)
headers= {'Referer': projectorAddress + '/cgi-bin/webconf'}

def getRequest(url):
  return requests.get(projectorAddress + url, auth = auth, headers = headers)

def postRequest(url, data):
  return requests.post(projectorAddress + url, data = data, auth = auth,
                       headers = headers)

def projectorIsOn():
  r = postRequest('/cgi-bin/webconf', {'page': '03'}) # Get info page
  retval = r.text.find('The projector is currently on standby.<BR>') == -1
  print(retval)
  return retval

def turnProjectorOn():
  if not projectorIsOn():
    getRequest('/cgi-bin/directsend?KEY=3B')

def turnProjectorOff():
  if projectorIsOn():
    getRequest('/cgi-bin/directsend?KEY=3B')
    time.sleep(0.3)
    getRequest('/cgi-bin/directsend?KEY=3B')

argument = sys.argv[1] or ''
if sys.argv[1] == 'on':
  turnProjectorOff()
elif sys.argv[1] == 'off':
  turnProjectorOff()
elif sys.argv[1] == 'hdmi1':
  getRequest('/cgi-bin/directsend?KEY=4D')
elif sys.argv[1] == 'hdmi2':
  getRequest('/cgi-bin/directsend?KEY=40')
elif sys.argv[1] == 'pc':
  getRequest('/cgi-bin/directsend?KEY=44')
elif sys.argv[1] == 'lan':
  getRequest('/cgi-bin/directsend?KEY=53')
elif sys.argv[1] == 'usb':
  getRequest('/cgi-bin/directsend?KEY=85')
elif sys.argv[1] == 'screenmirror':
  getRequest('/cgi-bin/directsend?KEY=56')
elif sys.argv[1] == 'mute':
  getRequest('/cgi-bin/directsend?KEY=3E')
elif sys.argv[1] == 'volumeDown':
  getRequest('/cgi-bin/directsend?KEY=57')
elif sys.argv[1] == 'volumeUp':
  getRequest('/cgi-bin/directsend?KEY=56')
elif sys.argv[1] == 'longforward':
  getRequest('/cgi-bin/directsend?KEY=D5')
elif sys.argv[1] == 'forward':
  getRequest('/cgi-bin/directsend?KEY=D7')
elif sys.argv[1] == 'longrewind':
  getRequest('/cgi-bin/directsend?KEY=D4')
elif sys.argv[1] == 'rewind':
  getRequest('/cgi-bin/directsend?KEY=D6')
elif sys.argv[1] == 'play':
  getRequest('/cgi-bin/directsend?KEY=D1')
elif sys.argv[1] == 'pause':
  getRequest('/cgi-bin/directsend?KEY=D3')
elif sys.argv[1] == 'stop':
  getRequest('/cgi-bin/directsend?KEY=D2')
else:
  print("Run script with parameter 'on' or 'off'")
  sys.exit(1)

sys.exit(0)


Aufruf erfolgt über ein Notify auf einen Dummy, ich schalte damit AN, AUS, HDMI1, HDMI2


dummy_beamer_wohnz:* {
system "python /opt/fhem/tw5650.py $EVTPART0 &";
}


Greetz
Eldrik

rocknob

was viele hier suchen kann man mit pyjector und pyjector_controller erreichen, momentan teste ich das noch serial (netzwerk wäre natürlich besser), ich finde das epsonprotokoll ja äußerst schrecklich aber was solls.

mal ein paar beispiele

./pyjector_controller epson -v "/dev/ttyUSB0" power status
1553320678.996861 INFO send: 'PWR?\r'
1553320680.999521 INFO recv: 'PWR=00\r:'

./pyjector_controller epson -v "/dev/ttyUSB0" lampcount status
1553322535.985180 INFO send: 'LAMP?\r'
1553322537.987681 INFO recv: 'LAMP=8\r:'

man muss "nur" sich die schreckliche doku durchlesen, ein json file anlegen und dort kann man die schritte hinterlegen. so wie ich das sehe gibt es aber beim lensmemory keine möglichkeit zu sagen "fahre an position x" oder ich begreife es nur nicht :( das INC und DEC bewegt zwar die linse aber nur in Einerschritten...

pyjector gibt es via "pip install pyjector" (achtung ich hatte probleme und musste pyserial via apt nachinstallieren), den controller findet man dann hier https://github.com/JohnBrodie/pyjector/blob/master/pyjector_controller

anbei mal mein jsonfile, das ist nicht zu 100% getestet, aber was schon geht ist memory lesen/lensmemory/an/aus/status

Astrofreak85

Ich hab folgendes Problemmit dem Modul,

da ich meinen Beamer über IP Steckdose immer nach einiger Zeot komplett vom Netz trenne hab ich imFHEM Log tausende dieser Meldungen,
mit einer Änderung des verbose-levels des Moduls verschwindet das nur leide rnicht, wie kann ich das verhindern?

ESCVP21_Watchdog: called for command 'init', resetting communication

MaJu

Auch ich nutze bisher den Umweg über Harmony-Infrarot, um meinen Epson EH-TW650 ein- und auszuschalten.
Eine RS232-Verbindung ist bei mir aufgrund der Gegenbenheiten ausgeschlossen, nun suche ich eine Lösung über WLAN.

Ist es schon jemandem erfolgreich geglückt?
Erlebnisreiche Grüße aus Leipzig!

eldrik

#40
Moin Maju,

hast du einmal hier geschaut?

https://forum.fhem.de/index.php/topic,13097.msg771364.html#msg771364

Greetz
Eldrik

MaJu

Vielen Dank.

Bisher habe ich noch nicht mit Python gearbeitet, da fehlt mir leider jegliches Basiswissen und es ist schwer, da rein zu kommen.

Das ist nach erstem Blick das gleiche Python-Script wie eine Seite zuvor. Mit dem hatte ich es bereits probiert, hatte aber keinen Erfolg. Das liegt aber vermutlich eher an mir, als am Script ...
Ich werden es nochmal testen.
Erlebnisreiche Grüße aus Leipzig!

fheminist

#42
Hallo,

erst einmal vorab: VIIIIIIEEEELLLEN Dank für das Python-Script!
Das lief bis heute zwei Jahre für meinen Epson tw650.  Vor einem Monat hat mein Beamer angefangen zu flackern und er war zur Reparatur bei 3 Firmen....
(voll Katastrophe, daher auch vor einem Monat kaputt und heute aus der Reparatur zurück .... )

Der Beamer hat nun eine neue Birne und ein FW-update erhalten. Blöd war nur, dass das P-Script nicht mehr passt... Daher wollte ich mit Euch die Anpassungen teilen.
Auch sei damit noch einmal erwähnt, dass das Skript trotz des 'alters' immer noch für die neuen Epson-Beamer super läuft.

#!/usr/bin/python3

## -- ------------------------------------------------------------ --
## C.H @ Marl
##  funktioniert mit Epson TW650
##  20210429: neue FW nach Reparatur, daher pfad von /cgi-bin/directsend
##      auf /cgi-bin/Remote/directsend angepasst
##      aktuelle FW vom Beamer: 0900 8864 CZK 2V 115
## -- ------------------------------------------------------------ --

import requests
import re
import time
import sys

projectorAddress = 'http://192.168.179.48'
username = 'EPSONWEB'
password = 'mySuperSecretPW'

auth = requests.auth.HTTPBasicAuth(username, password)
headers= {'Referer': projectorAddress + '/cgi-bin/webconf'}

def getRequest(url):
  return requests.get(projectorAddress + url, auth = auth, headers = headers)

def postRequest(url, data):
  return requests.post(projectorAddress + url, data = data, auth = auth, headers = headers)

def projectorIsOn():
    r = postRequest('/cgi-bin/webconf', {'page': '03'}) # Get info page
    retval = r.text.find('Der Projektor befindet sich im Standby-Modus.') == -1  ## ergibt immer no auth..
    print(retval)
    return retval


def turnProjectorOn():
  if projectorIsOn():
      getRequest('/cgi-bin/Remote/directsend?KEY=3B')
     
def turnProjectorOff():
  if projectorIsOn():
      getRequest('/cgi-bin/Remote/directsend?KEY=3B')
      time.sleep(0.3)
      getRequest('/cgi-bin/Remote/directsend?KEY=3B')

argument = sys.argv[1] or ''
if sys.argv[1] == 'on':
  turnProjectorOn()
elif sys.argv[1] == 'off':
  turnProjectorOff()
elif sys.argv[1] == 'hdmi1':
  getRequest('/cgi-bin/Remote/directsend?SOURCE=30')
elif sys.argv[1] == 'hdmi2':
  getRequest('/cgi-bin/Remote/directsend?SOURCE=A0')
elif sys.argv[1] == 'pc':
  getRequest('/cgi-bin/Remote/directsend?KEY=44')
elif sys.argv[1] == 'lan':
  getRequest('/cgi-bin/Remote/directsend?KEY=53')
elif sys.argv[1] == 'usb':
  getRequest('/cgi-bin/Remote/directsend?KEY=85')
elif sys.argv[1] == 'screenmirror':
  getRequest('/cgi-bin/Remote/directsend?KEY=56')
elif sys.argv[1] == 'mute':
  getRequest('/cgi-bin/Remote/directsend?KEY=3E')
elif sys.argv[1] == 'volumeDown':
  getRequest('/cgi-bin/Remote/directsend?KEY=57')
elif sys.argv[1] == 'volumeUp':
  getRequest('/cgi-bin/Remote/directsend?KEY=56')
elif sys.argv[1] == 'longforward':
  getRequest('/cgi-bin/Remote/directsend?KEY=D5')
elif sys.argv[1] == 'forward':
  getRequest('/cgi-bin/Remote/directsend?KEY=D7')
elif sys.argv[1] == 'longrewind':
  getRequest('/cgi-bin/Remote/directsend?KEY=D4')
elif sys.argv[1] == 'rewind':
  getRequest('/cgi-bin/Remote/directsend?KEY=D6')
elif sys.argv[1] == 'play':
  getRequest('/cgi-bin/Remote/directsend?KEY=D1')
elif sys.argv[1] == 'pause':
  getRequest('/cgi-bin/Remote/directsend?KEY=D3')
elif sys.argv[1] == 'stop':
  getRequest('/cgi-bin/Remote/directsend?KEY=D2')
else:
  print("cmd not found .... Run script with parameter eg with 'on' or 'off'")
  sys.exit(1)

sys.exit(0)



Hier ein doif mit dem ich die hdmi-Kanäle und on/off schaltet. Für das Einschalten muss dieses Setting aktiv sein --> Eco / Standby-Modus / Komunik.ein
Meinen DIY-Lift fahre ich erst ganz rein, wenn der Beamer kalt ist. Das ist hier auch zum Teil abgebildet. Der Rest der Steuerung ist in der 'großen' TV-Scene.

([Switch_Beamer:state] eq "on")
## 1 on
({ system("python /opt/fhem/erna_cfg/bin/epson_tw650.py on") })
(setreading $SELF BeamerSTATUS warm)

DOELSEIF ([Switch_Beamer:state] eq "off")
## 2 off
({ system("python /opt/fhem/erna_cfg/bin/epson_tw650.py off") })
(setreading $SELF BeamerSTATUS kuehlen)


DOELSEIF ( [$SELF:BeamerSTATUS] eq "kuehlen" and  [TempBeamer_esp67:temperature] < ([TempWoZi_esp67:temperature]+3) )
## 3 kalt
(setreading $SELF BeamerSTATUS kalt)



DOELSEIF ([Scene_TV_Eingang:state] eq "laptop")
## 4 hdmi 2 = 5.Wege switch
## Y-Peitsche @teufel daher kodi mute ...
(set ErnaMC4_Wozi mute on, set ErnaMC4_Wozi stop all)
(set WoZi_HDMIswitch on)
(setreading $SELF BeamerINPUT HDMI2)
({ system("python /opt/fhem/erna_cfg/bin/epson_tw650.py hdmi2") })

DOELSEIF ([Scene_TV_Eingang:state] eq "playsi")
## 4 hdmi 2 = 5.Wege switch
## Y-Peitsche @teufel daher kodi mute ...
(set ErnaMC4_Wozi mute on, set ErnaMC4_Wozi stop all)
(set PlayStation on, set WoZi_HDMIswitch on)
(setreading $SELF BeamerINPUT HDMI2)
({ system("python /opt/fhem/erna_cfg/bin/epson_tw650.py hdmi2") })

DOELSEIF ([Scene_TV_Eingang:state] eq "tv")
## 5 hdmi 1 = tv@kodi
(set PlayStation off, set WoZi_HDMIswitch off)
({ system("python /opt/fhem/erna_cfg/bin/epson_tw650.py hdmi1") })
(setreading $SELF BeamerINPUT HDMI1)
(set ErnaMC4_Wozi mute off)






Vielen Dank noch einmal und ich hoffe es hilft jemandem.


 
3*FB-Mesh ,FHEM+MariaDB+TVH+TriaxSatIPGrafana@Docker/DS220+, 6*Kodi-RPis, EpsonTW650+DIY-Lift, 3*IPCam@TVH, 2*AI@EspCAM, Robo.S6
6*Maxcio bulbs, 15*Nodemcu&WemosD1, 20*GosundSP1, 25*Shelly, 8*MC400A, 7*CometDect, abgelöst: diyCurls, 433Mhz, JeeLink, DenonAVR, FS20, HM ...

Frank_Huber

#43
Moin,

Ich bin auch gerade das Heimkino am fertigstellen.
Der Epson eb2250u läuft 1a mit dem ursprünglichen Script.
Ich überlege aber ob es sich nicht auch mit einem HTTPMOD abbilden lassen würde. Damit könnte man auch den Status abfragen ob an oder aus.
Das fehlt mir bei dem Script.
Ich versuche mich mal daran und geb hier wieder laut wenn es läuft. 😉
Schönen Feiertag noch!

Frank_Huber

#44
So, habe das mit dem HTTPMOD aufgegeben. Der Epson kann aber auch das pjlink Protokoll. damit hab ich es jetzt gelöst.

Infos: https://www.heimkino-praxis.de/pjlink-projektor-steuerung/
Install auf Raspi: https://pypi.org/project/pypjlink/
sudo pip install pypjlink

Abfragen sind dann möglich:
root@pi4-octoprint:~# pjlink -p 192.168.12.95 info
Name: BEAMER_KINO
Manufacturer: EPSON
Product Name: EPSON 2250U
Other Info: 111.111.---
root@pi4-octoprint:~# pjlink -p 192.168.12.95 lamps
Lamp 1: off (6 hours)
root@pi4-octoprint:~# pjlink -p 192.168.12.95 power
off
root@pi4-octoprint:~# pjlink -p 192.168.12.95 power on
root@pi4-octoprint:~# pjlink -p 192.168.12.95 power
warm-up
root@pi4-octoprint:~# pjlink -p 192.168.12.95 power
on
root@pi4-octoprint:~# pjlink -p 192.168.12.95 power off
root@pi4-octoprint:~# pjlink -p 192.168.12.95 power
cooling
root@pi4-octoprint:~#


in FHEM habe ich zwei CustomReadings angelegt:
defmod Beamer CustomReadings
attr Beamer interval 15
attr Beamer readingDefinitions PowerState:qx(pjlink -p 192.168.12.95 power)
attr Beamer stateFormat PowerState

defmod BeamerLampe CustomReadings
attr BeamerLampe interval 3600
attr BeamerLampe readingDefinitions Lamp:qx(pjlink -p 192.168.12.95 lamps), LampState:{(split " ", (ReadingsVal("$name","Lamp","")))[2]}, LampHours:{my $v=(split " ",(ReadingsVal("$name","Lamp","")))[3];;;;$v =~ s/^.//;;;;return $v;;;;}
attr BeamerLampe stateFormat Lamp

zum schalten hab ich ein DOIF welches ich mit einem Dummy GPIO über meine Handy App NetIO toggle:
defmod Beamer_OnOff DOIF ([GPIO_IN_dummy5:"^on$"] and [Beamer:PowerState] eq "off") {system "pjlink -p 192.168.12.95 power on &";;;;return undef}\
DOELSEIF ([GPIO_IN_dummy5:"^on$"] and [Beamer:PowerState] eq "on") {system "pjlink -p 192.168.12.95 power off &";;;;return undef}
attr Beamer_OnOff cmdState on|off
attr Beamer_OnOff do always
attr Beamer_OnOff webCmd on:off


Hoffe es hilft jemandem. Für mich funktioniert das jetzt so wie ich es mir vorstelle.

fheminist

#45
Hallo zusammen,

habe nun den Epson TW750, da der TW650 anscheinend auf dem Versandweg beschädigt wurde...
Bei dem Epson TW750 wurde die Authentifizierung vom "Epson Web Control" auf "digest" Authentifizierung umgestellt....

Die get-Request-Commants sind gleich geblieben (also wie beim TW650 mit aktualisierter FW).


Hier das angepasste python-Skript:

#!/usr/bin/python3

## -- ------------------------------------------------------------ --
## C.H @ Marl
##  funktioniert mit Epson TW650
##  20210429: neue FW nach Reparatur, daher pfad von /cgi-bin/directsend
##      auf /cgi-bin/Remote/directsend angepasst
##      aktuelle FW vom Beamer: 0900 8864 CZK 2V 115
##  20210506 ab Epson tw750 wurde die Auth-Methode geändert...
##       nicht mehr HTTPBasicAuth (alt) sondern... HTTPDigestAuth (neu)
## -- ------------------------------------------------------------ --

import requests
import re
import time
import sys
from requests.auth import HTTPDigestAuth    ## 20210506 auth neu ab tw750

projectorAddress = 'http://192.168.179.48'
username = 'EPSONWEB'
password = 'admin'


## auth = requests.auth.HTTPBasicAuth(username, password)   ## 20210506 bis tw650 geht das hier
auth = requests.auth.HTTPDigestAuth(username, password)     ##    ab epson tw750 geht nur diese zeile...
headers= {'Referer': projectorAddress + '/cgi-bin/webconf'}

def getRequest(url):
    return requests.get(projectorAddress + url, auth = auth, headers = headers)

def postRequest(url, data):
  return requests.post(projectorAddress + url, data = data, auth = auth, headers = headers)

def projectorIsOn():
    r = postRequest('/cgi-bin/webconf', {'page': '03'}) # Get info page
    retval = r.text.find('Der Projektor befindet sich im Standby-Modus.') == -1  ## klappt nun auch...
    print(retval)
    return retval


def turnProjectorOn():
  if not projectorIsOn():
      getRequest('/cgi-bin/Remote/directsend?KEY=3B')
     
def turnProjectorOff():
  if projectorIsOn():
      getRequest('/cgi-bin/Remote/directsend?KEY=3B')
      time.sleep(0.3)
      getRequest('/cgi-bin/Remote/directsend?KEY=3B')
     
argument = sys.argv[1] or ''
if sys.argv[1] == 'on':
  turnProjectorOn()
elif sys.argv[1] == 'off':
  turnProjectorOff()
elif sys.argv[1] == 'hdmi1':
    getRequest('/cgi-bin/Remote/directsend?SOURCE=30')
elif sys.argv[1] == 'hdmi2':
  getRequest('/cgi-bin/Remote/directsend?SOURCE=A0')
elif sys.argv[1] == 'pc':
  getRequest('/cgi-bin/Remote/directsend?KEY=44')
elif sys.argv[1] == 'lan':
  getRequest('/cgi-bin/Remote/directsend?KEY=53')
elif sys.argv[1] == 'usb':
  getRequest('/cgi-bin/Remote/directsend?KEY=85')
elif sys.argv[1] == 'screenmirror':
  getRequest('/cgi-bin/Remote/directsend?KEY=56')
elif sys.argv[1] == 'mute':
  getRequest('/cgi-bin/Remote/directsend?KEY=3E')
elif sys.argv[1] == 'volumeDown':
  getRequest('/cgi-bin/Remote/directsend?KEY=57')
elif sys.argv[1] == 'volumeUp':
  getRequest('/cgi-bin/Remote/directsend?KEY=56')
elif sys.argv[1] == 'longforward':
  getRequest('/cgi-bin/Remote/directsend?KEY=D5')
elif sys.argv[1] == 'forward':
  getRequest('/cgi-bin/Remote/directsend?KEY=D7')
elif sys.argv[1] == 'longrewind':
  getRequest('/cgi-bin/Remote/directsend?KEY=D4')
elif sys.argv[1] == 'rewind':
  getRequest('/cgi-bin/Remote/directsend?KEY=D6')
elif sys.argv[1] == 'play':
  getRequest('/cgi-bin/Remote/directsend?KEY=D1')
elif sys.argv[1] == 'pause':
  getRequest('/cgi-bin/Remote/directsend?KEY=D3')
elif sys.argv[1] == 'stop':
  getRequest('/cgi-bin/Remote/directsend?KEY=D2')
else:
  print("cmd not found .... Run script with parameter eg with 'on' or 'off'")
  sys.exit(1)

sys.exit(0)



Pypjlink hat bei mir leider nicht geklappt... Das hatte ich zwischenzeitlich auch mal probiert. Entweder ich hab die Installation verbockt, oder evtl. schlägt hier auch die auth ins leere.

VG


3*FB-Mesh ,FHEM+MariaDB+TVH+TriaxSatIPGrafana@Docker/DS220+, 6*Kodi-RPis, EpsonTW650+DIY-Lift, 3*IPCam@TVH, 2*AI@EspCAM, Robo.S6
6*Maxcio bulbs, 15*Nodemcu&WemosD1, 20*GosundSP1, 25*Shelly, 8*MC400A, 7*CometDect, abgelöst: diyCurls, 433Mhz, JeeLink, DenonAVR, FS20, HM ...

Frank_Huber

Zitat von: fheminist am 06 Mai 2021, 20:44:01
Pypjlink hat bei mir leider nicht geklappt... Das hatte ich zwischenzeitlich auch mal probiert. Entweder ich hab die Installation verbockt, oder evtl. schlägt hier auch die auth ins leere.

Wenn Du PJLink im Beamer Menü hast kannst Du dort die Auth abschalten. (ist per Default ohne Passwort)

Wenn Du keine Einstellungen dafür findest kann er es vermutlich nicht.

fheminist

Hallo Frank,

ne die Einstellung habe ich nicht, dann ist zumindest klar, warum es bei mir nicht geklappt hat.

Danke für den Tipp.
3*FB-Mesh ,FHEM+MariaDB+TVH+TriaxSatIPGrafana@Docker/DS220+, 6*Kodi-RPis, EpsonTW650+DIY-Lift, 3*IPCam@TVH, 2*AI@EspCAM, Robo.S6
6*Maxcio bulbs, 15*Nodemcu&WemosD1, 20*GosundSP1, 25*Shelly, 8*MC400A, 7*CometDect, abgelöst: diyCurls, 433Mhz, JeeLink, DenonAVR, FS20, HM ...

hapege

#48
Hallo,

Ich steuere meinen Epson Beamer aktuell auch über ein eigenes Python Script. Aber nachdem mir das Handling mit externen Bibliotheken und Skripten doch ein wenig umständlich scheint, und die das vorhandene Modul 70_ESCVP21 kein LAN "spricht", habe ich mal ein wenig rumgespielt und mir ein Modul für die Ansteuerung via VP.net über (W)Lan gebaut. Das muss doch auch eleganter gehen als mit Konvertern und externen Tools :-)
Ich bin kein Experte, aber habe versucht mich an die fhem Entwicklungsrichtlinien zu halten - die Fachleute mögen mir eventuelle Verbrechen gegen diese oder Perl bitte beratend verzeihen ;-)

Das neue Modul läuft bei mir mit einem Epson TW5650 aktuell stabil in Test- und Produktivsystem - hat jemand Lust und Interesse das mal auszuprobieren? Die commands sind ja offenbar bei allen Epsons grundsätzlich gleich.

CU,

Hermann
Developer: 70_ESCVP21net.pm, 70_SVDRP.pm
Mitglied FHEM e.V.

Frank_Huber

Zitat von: hapege am 17 Januar 2022, 13:47:45
Ich steuere meinen Epson Beamer aktuell auch über ein eigenes Python Script. Aber nachdem mir das Handling mit externen Bibliotheken und Skripten doch ein wenig umständlich scheint, und die das vorhandene Modul 70_ESCVP21 kein LAN "spricht", habe ich mal ein wenig rumgespielt und mir ein Modul für die Ansteuerung via VP.net gebaut. Das muss doch auch eleganter gehen als mit Konvertern und externen Tools :-)
Ich bin kein Experte, aber habe versucht mich an die fhem Entwicklungsrichtlinien zu halten - die Fachleute mögen mir eventuelle Verbrechen gegen diese oder Perl bitte beratend verzeihen ;-)

Das neue Modul läuft bei mir mit einem Epson TW5650 aktuell stabil in Test- und Produktivsystem - hat jemand Lust und Interesse das mal auszuprobieren? Die commands sind ja offenbar bei allen Epsons grundsätzlich gleich.

Mahlzeit,

Ich stehe sehr gerne zum testen bereit. :-)

Grüße
Frank

hapege

Developer: 70_ESCVP21net.pm, 70_SVDRP.pm
Mitglied FHEM e.V.

Frank_Huber


hapege

Hi,
Hast Du eine Doku zu den VP21 commands für den 2250U?
Ich habe im Netz einiges gefunden (siehe anbei), aber nicht spezifisch für den 2250U.
Standards wie PWR, LAMP, SOURCE etc sollten aber hoffentlich generisch sein...
Developer: 70_ESCVP21net.pm, 70_SVDRP.pm
Mitglied FHEM e.V.

hapege

Hab was gefunden, anbei. Der VP21 Befehlssatz ist übersichtlich ;-) Ich probiere mal ob ich das mit einer Modellauswahl einbauen kann.
PWR und MUTE gehen out-of-the-box :-)
Developer: 70_ESCVP21net.pm, 70_SVDRP.pm
Mitglied FHEM e.V.

Frank_Huber

Ich habe nie groß gesucht da das mit dem pjlink soweit funktioniert. :-)

Was ich nutze ist:
- Überwachung an/aus.
- an/aus schalten
- Info Lampenstunden

hapege

- ein/aus (PWR) sollte auch per VP21 gehen
- Lampenstunden (LAMP - mein zweiter Hauptanwendungszweck ;-) ) ist beim EB-2250U nicht explizit genannt, taucht aber eigentlich bei allen Projektoren aus --> let's test...
- was meinst Du mit "Überwachung"?
Developer: 70_ESCVP21net.pm, 70_SVDRP.pm
Mitglied FHEM e.V.

Frank_Huber

Zitat von: hapege am 17 Januar 2022, 15:41:34
- was meinst Du mit "Überwachung"?
Na zu wissen ob er an oder aus ist. ;)

defmod Beamer CustomReadings
attr Beamer event-on-change-reading .*
attr Beamer group Beamer
attr Beamer interval 15
attr Beamer readingDefinitions PowerState:qx(pjlink -p 192.168.12.95 power)
attr Beamer stateFormat PowerState

hapege

OK, das ist ein Argument ;-) Ich prüfe aktuell nur die IP Verbindung, weil ich meinen Beamer nach dem Herunterfahren vom Strom nehme. Aber so ein periodischer Check macht Sinn...ich schau mal was mir dazu einfällt.
Developer: 70_ESCVP21net.pm, 70_SVDRP.pm
Mitglied FHEM e.V.

hapege

#58
Update 2022-01-26

  • Version 1.01.02
  • Unterstützung mehrerer Devices
  • debug Attribut (blendet im Normalbetrieb unnötige sets aus)
  • Code cleanup


Update 2022-01-21

  • Version 1.01.01
  • rescheduling aufeinanderfolgender set commands
  • TW6100 hinzugefügt
  • modellspezifische Results eingebaut


Update 2022-01-19

  • Version 0.3
  • Optimierung der "disconnect" Erkennung
  • Neues Attribut "statusOfflineMessage" (Text im Reading statusCheckCmd [default: PWR] der bei STATE=disconnected agesetzt wird [default: "offline"])
  • Helptext hinzugefügt


Helptext

ESCVP21net implements Epson VP21 controlvia (W)LAN, uses VP.net.
Define
define <name> ESCVP21net <IP_Address> <port> <[model]>
       
This module controls Epson Seiko Devices via TCP, using VP.net and ESC/VP21 commands.
For the time being, only Epson initilization is implemented (needs a special initialization string "ESC/VP.net").

  • "IP_Address" is the IP Address of the projector
  • "port" is ... guess? Yes, the port (Epson standard is 3629)
  • model defines your type of projector. It is used for loading a suitable pre-defined command set. No parameter or default; will provide you with a limit "set" (PWR, MUTE, LMP, KEY, GetAll). You can try TW5650; to get a nearly full set of implemented commands. Providing the maintainer with a suitable set for your projector will extend the module's capabilities ;-)
    Individually supported by now: TW5650, EB2250U, TW6100
    "Hidden Feature:" Type "Scotty" will give you everything (as he does always ;) ). Not every command will work for you. You are the Captain, so decide wisely what to choose...
Example: define EPSON ESCVP21net 10.10.0.1 3629 TW5650


Set
set <name> <option> <value>
Available set commands depend on your model, see above.
For the predefined commands, "nice" names will be shown in the readings, e.g. for PWR: Standby (Net on) instead of the boring PWR=04 (which is the device's answer if the projector is in Standby with LAN on).
Default set commands are

  • PWR
    on or off to switch power, get to query current value
  • MUTE
    on or off to mute video signal (i.e. blank screen), get to query current state
  • LAMP
    get to query lamp hours
  • KEY
    sends the value you enter to the projector.
    E.g.KEY 03 should open the OSD menu, KEY 05 should close it.
  • GetAll
    This is a little bit special - it does not send just one command to the projector, but will select every command defined which has a get option, send it to the projector and update the correspnding reading. If a command gives no result or an error, this will be suppressed, the old value is silently kept.
    The status of GetAll is shown in the GetAll reading. It will either show the read commands, or inform if an error was received.
  • reRead
    Also "special". Will just restore the available set commands for your projector type in case they got "lost" (which will happen if you e.g. reload the module...)

Attributes
attr <name> <attribute> <value>
Use those Attributes to control the behaviour of your device.

  • Manufacturer: Epson|default
    Is not used currently.
  • AdditionalSettings: cmd1:val_1,...,val_n cmd2:val_1,...,val_n
    You can specify own set commands here, they will be added to the set list.
    Multiple own sets can be specified, separated by a blank.
    command and values are separated by ":", values are separated by ",".
    Example: ASPECT:get,10,20,30 SN:noArg
    Each command with get will we queried when doing set <name> GetAll
  • connectionCheck: off|(value in seconds)
    value defines the intervall in seconds to perform an connection check. This is required, since the standard connection handling of fhem (DevIo) will not detect an broken TCP connection, so the state disconnected; will only trigger after TCP timeout (60-90 minutes). If you are ok with this, just set it to off.
    Default value is 60 seconds.
  • statusCheckIntervall: off|(value in seconds)
    value defines the intervall in seconds to perform an status check. Each interval the projector is queried with the command defined by statusCheckCmd (default: PWR to get power status).
    Default value is 60 seconds.
  • statusCheckCmd: (any command you set)
    Defines the command used by statusCheckIntervall. Default: PWR to get power status.
  • statusOfflineMsg: (any message text you set)
    Defines the message to set in the Reading related to statusCheckCmd when the device goes offline. Status of device will be checked after each statusCheckIntervall (default: 60s), querying the statusCheckCmd command (default: PWR), and if STATE is disconnected the Reading of statusCheckCmd will be set to this message. Default: "offline".



Hi,

OK ... dann lasse ich meine Gehversuche mal auf die fhem Welt los :-)

Ein bisschen Erklärung:

Das Modul "ESCVP21net":


       
  • nutzt DevIO für ein Monitoren der Verbindung. Ich habe es nicht geschafft, via DevIo direkt Kommandos an den socket des Eson zu schicken oder von dort empfangen, nutze es als nur zum non-blocking Prüfen der TCP Verbindung (hab ich bei 70_STV abgeschaut, mein Samsung Receiver hört auch nur auf direkte sockets)
  • die Kommunikation mit dem Beamer läuft deshalb über einen im Modul gesteuerten Socket
  • das ganze passiert damit non-blocking, da ein ausgeschalteter Beamer zwecks Timeout fhem sonst für ein paar Sekunden blockiert
  • Das interne Absetzen von commands ist ebenfalls non-blocking implementiert, da die Antwort vom Epson wohl auch mal ein paar Sekunden dauern kann. Ist evtl. unnötig, aber sicher ist sicher ;-)
  • das Modul kommt mit einem Basis-Set an Kommandos (Power, Mute, Lamp, Key)...
  • ...sowie einem "GetAll", welches alle commands abfragt die ein "get" enthalten (z.B. PWR:get,on,off in der internen setList)
  • über attr "AdditionalSettings" kann man, getrennt durch blanks, eigene Set-Kommandos dazufügen:
    <cmd1>:[get|noArg],<val1>,...,<valn> <cmd2>:[get|noArg],<val1>,...,<valn>
  • ich kann auch im Modul Sub-sets für betimmte Projektortypen anlegen, z.B. für Kommandos die nur ein bestimmter Typ beherrscht; diese würden dann aktiviert wenn bei der Definition des Devices der entsprechende Typ angegeben sind (momentan kennt das Modul nur 2 Typen: TW5650 und EB-2250U ;-), der TW5650 hat das umfangreichere set)
  • DevIo bekommt nicht von selbst mit, wenn der Projektor stromlos geschaltet wird, i.e. die TCP Verbindung stirbt. Erst nach einem ca 60 minütigen Timeout geht der Status auf "disconnected". Deshalb gibts attr "connectionCheck", um ein KeepAlive Intervall anzugeben. Es wird dann über einen internen Timer regelmäßg via DevIo geprüft ob der Beamer noch erreichbar ist. Der Timer "stirbt" praktischerweise bei einem "disconnect" und erwacht wieder bei "connected".
  • Zur Überwachung gibt's auf besonderen Wunsch das attr "statusCheckInterval". Ist es gesetzt, wird alle <n> Sekunden ein Wert vom Beamer abgefragt. Default wird "PWR" benutzt, das kann per attr "statusCheckCmd" angepasst werden.
  • Das attr "Manufacturer" wird aktuell nicht abgefragt, wird evtl gebraucht wenn mal z.B. ein Seiko Beamer (der auch VP21 spricht) einen andren Initialisierungsstring bräuchte.
  • via set "GetAll" werden alle Werte vom Beamer abgefragt, die ein "get" definiert haben. Im Reading "GetAll" werden dann jeweils die letzen geschickten commands angezeigt.
Definition des Devices via

define <Name> ESCVP21net <ip> <port> [<model>]


Port ist normalerweise 3629. Ohne Angabe von <model> wird "default" genommen. Ich empfehle zum Testen TW5650.

Da fehlt sicher noch einiges, bin aufs Feedback gespannt. Was ich nicht hinbekomme ist die "Device Specific help". Im Modul hab ich die html section gefüllt (nur mit "Teiltexten"), aber sie wird nicht angezeigt. Vielleicht kann mir jemand einen Tipp geben was ich hier falsch mache, oder ob ich die Help noch irgendwo eintragen muss...

Feedback, Kommentare, Hilfen wie es besser oder sauberer geht jederzeit gerne - wie gesagt, ich bin kein Experte...

CU,

Hermann
Developer: 70_ESCVP21net.pm, 70_SVDRP.pm
Mitglied FHEM e.V.

eldrik

Ich teste auch einmal etwas, ich habe auch einen TW5650.

Positiv ist mir bereits aufgefallen, dass der Standby erkannt wird, bisher ermittle ich dieses über httpmod und dem auslesen der im Stb. verfügbaren Website.

Source, Mute, Volume, on/off steuere ich derzeit über ein python Skript an (hier im Thread verlinkt) mal sehen ob ich dieses mit dem Modul elegant abgelöst bekomme.

Greetz
Eldrik

hapege

ZitatSource, Mute, Volume, on/off steuere ich derzeit über ein python Skript an (hier im Thread verlinkt) mal sehen ob ich dieses mit dem Modul elegant abgelöst bekomme.

Genau das ist der Zweck des Moduls - ich will von den externen Skripten weg  ;D
Developer: 70_ESCVP21net.pm, 70_SVDRP.pm
Mitglied FHEM e.V.

hapege

Developer: 70_ESCVP21net.pm, 70_SVDRP.pm
Mitglied FHEM e.V.

laserrichi

da hat man seit Jahren einen EH-TW6100 hängen und ist garnicht auf die Idee gekommen das zu machen, ist ja eigentlich nur Bildwiedergabe und man macht nur An Aus...

Jetzt hab ich lust das zu testen, zumal ich auch bei Epson die ganze Protokolldoku gefunden habe und sehe das man da noch im Modul bissl Projektoren ergänzen kann.

Idee: ESPEasy durch den USB gespeist und auf den Seriellen Port zum steuern und über WLAN an Fhem die Serielle durchgereicht.

RaspberryPi 4 Bullseye,Homematic,Z-Wave,Rademacher Duofern,Signalduino,Fritz7590,ESPEasy,Tasmota,Robonect,Kameras,1-Wire,Modbus,Solar,Maranz,VU+,ulanzi tc001 mit awtrix light

hapege

Ich hab das vor Jahren beim Vorgänger-Beamer tatsächlich per Raspi mal so ähnlich verwendet - war ziemlich schick umständlich ;-)
Wenn Du mir das, was Du drin haben willst, für den TW6100 zur Verfügung stellst (am liebsten gleich als hash "ESCVP21net_TW6100sets" ;), sonst einfach per Text) bau ich das gerne mit ein.
Die Typenauswahl ist noch nicht so "rund" wie ich mir das vorstelle, funktioniert aber  ;)
Developer: 70_ESCVP21net.pm, 70_SVDRP.pm
Mitglied FHEM e.V.

laserrichi

also der USB hat im Ausgeschalteten Zustand keine Spannung, also müste man von innen für den esp was abgreifen.
Hab am PC mit Seriell schon mal probiert, reagiert auf Befehle :-)  Ich brauch erst noch einen max3232  also Pegelanpassung für die Serielle das ich mit dem ESP da ran kann.

Die Doku über viele Beamer habe ich hier gefunden:
https://download.epson-europe.com/pub/download/6332/epson633270eu.xlsx
RaspberryPi 4 Bullseye,Homematic,Z-Wave,Rademacher Duofern,Signalduino,Fritz7590,ESPEasy,Tasmota,Robonect,Kameras,1-Wire,Modbus,Solar,Maranz,VU+,ulanzi tc001 mit awtrix light

hapege

Ja, das Excel kenne ich (hatte ich ein paar Posts vorher mal hier hochgeladen ;) )
Ich habe das so gelöst, dass ich den Beamer über eine Sonoff mit Strom versorge, und übers Menü kann man ja einstellen dass er hochfährt sobald er Strom hat. Ab dann ist er seriell oder eben komfortabler per LAN ansteuerbar. Fürs ausschalten einfach "set Beamer PWR off", und entweder ein paar Minuten später die Sonoff per fhem aus oder, sicherer, eine Sonoff mit Leistungsmessung und bei <50W erst ausschalten. Funktioniert prima :-)

Die VP21 commands beim TW6100 sind sehr ähnlich zum TW5650, ein/aus geht auf jeden Fall. SOURCE hat ein paar andere Werte, kann ich einbauen :)
Developer: 70_ESCVP21net.pm, 70_SVDRP.pm
Mitglied FHEM e.V.

hapege

Update:

  • rescheduling aufeinanderfolgender set commands
  • TW6100 hinzugefügt
  • modellspezifische Results eingebaut

Download aktualisiert:
https://forum.fhem.de/index.php/topic,13097.msg1201440.html#msg1201440
Developer: 70_ESCVP21net.pm, 70_SVDRP.pm
Mitglied FHEM e.V.

hapege

Developer: 70_ESCVP21net.pm, 70_SVDRP.pm
Mitglied FHEM e.V.

Astrofreak85

Hi,

ich hab mit dem ursprünglichen Modul für RS232 jetzt nachdem es ewig funktioniert hat seit einem Server-neustart das problem, dass ich den Beamer nicht mehr steuern kann, es werden scheinbar keine befehle mehr übertragen, hab schon prbiert das Device zu ändern (/dev/serial/by-id) da sich nach dem neustart der port von  /dev/ttyUSB0 auf  /dev/ttyUSB1 geändert hatte, aber auch das alles kein Erfolg...

Jemand eine Idee?