Anbindung Android-Tabs via EventGhost (Android-Version)

hm, ich komme hier ins Grübeln. Das ist ja nett mit dem Angebot, aber wenn ich mir meinen aktuellen Stand anschaue:

[ul][li]ich habe eine Kommunikations-App auf den Devices, die einen soliden Eindruck macht, sehr stabil läuft und bei mir bereits implementiert und konfiguriert ist (EventGhost)[]ich habe auf der IPS-Seite eine fertige Logik, die nicht nur Bidi kommunizieren kann, sondern auch ein Error-Management beinhaltet[]ich habe auf den 8 Androiden weiterhin eine äusserst verbreitete, erprobte und stabile Lösung, die die Hard- und Software auf den Devices steuern kann, die bereits implementiert und konfiguriert ist(Tasker)
[/li][/ul]

Jetzt sagst Du, Du würdest eine neue Android-App bauen, die mit IPS kommunziert und das Device (oder eine weitere App?) ein- und ausschalten können würde? -> die quasi EventGhost (und Tasker?) ersetzt?

Da kann ich im Moment für mich (nicht nur für mich) kaum einen Vorteil erkennen (ganz abgesehen von einer erneuten Implementierung auf der IPS-Seite, die ich erneut durchführen müsste -denn das fällt ja durch eine solche App nicht weg) - weil das gibts ja alles schon und läuft.
Und etwas Aufwand wird man vermutlich auch für die Entwicklung der Android-App benötigen - nicht nur der, der entwickelt, sondern auch die, die testen.
Ich würde daher sagen: wenn ich mit meiner Lösung nicht weiter komme, komm ich nochmal auf das Angebot zurück, ok?

Und hier sollte dann auch bzgl. Fremd-Apps die es vielleicht schon gibt oder geben wird auch Schluß sein.

Hier geht es einzig um Raketenschnecke´s Weg von IPS->Android<-IPS und sonst um nichts.

Sollte jemand was Eigenes machen so steht im der Weg in einem eigenen Beitrag offen.

Bitte berücksichtigen!

habe heute eine ganz witzige Alternative zu EventGhost auf Android gefunden: terRemote. Hierbei handelt es sich ebenfalls um einen EG-Client für Android, nur kann dieser Client etwas mehr: z.B. text to speech (englisch ist ok, deutsch nicht wirklich), kann selbst Applikationen starten, zu jedem Event können beliebige Aktionen hinzugefügt werden.

Die Anbindung an IPS erfolgt analog zum bisherigen EG-Client, d.h. ich kann bei gleicher Konfig einfach zwischen beiden Apps switchen. In IPS braucht nichts geändert werden

Erste Versuche eben machen Lust auf mehr…bei mir.

Servus RaketenSchnecke,

hab grad mal in deinen alten Sripten gewildert und mir daraus was eigenes für die native IPS -> terRemote -> Tasker Fernsteuerung für meine Android Tabs gebaut.
Am Basteltisch funktioniert das astrein.

Ich bemerke aber das nach jedem erfolgreich gesendetem String die ClientSocket Verbindung kurz eine graues Icon bekommt. Nach 2-3 Sekunden wirds wieder grün.
Im Log taucht dazu jeweils ein Socket:Getrennt Socket:Verbunden Meldungspaar auf.
Weißt du was dazu ? Schlimm ? Ist das bei dir auch so ?
Aktiv trenne ich im Script keinen Socket.

Zum Text to Speech: Wenns anstatt der Google Engine Die SVOX TTS mit der Stimme „Petra“ installierst kommt das sehr viel besser rüber. Die App ist kostenpflichtig, die paar Euro sind gut investiert.

Ansonsten kann ich dir voll zustimmen, die Lösung macht echt Lust auf mehr. Kann die langen kalten Herbst Bastelnächte kaum erwarten.

mit aufrechtem Gruß
bb

Hi Raketenschnecke

Tolle Sache mit den Androiden, versuche auch dies einzurichten. Kannst Du mir da die Scripte zur Verfügung stellen? Habe nur das zum Empfangen gefunden in diesem Thread.

Gruss und vielen dank

Dani

Hi dake,
eigentlich kein Problem, aber das ist alles Andere als Plug-and-play. Und dirty Code. und nicht dokumentiert… willst du wirklich?

Hi Dani

würdest mir ggfls. etwas beim testen helfen ?

Ich verfolge hier nämlich einen etwas einfacheren Ansatz als Raketenschnecke.
Installation ist daher ganz einfach, Code ist auch dokumentiert.

Bei mir läufts seit einigen Tagen stabil, da ich mich aber erst seit kurzem damit beschäftige hab ich noch keine Langzeiterfahrung, auch noch keine Idee wie es auf den verschiedensten Androiden tut.

gruß
bb

Hi

@bbernhard

würdest mir ggfls. etwas beim testen helfen ?

Ich verfolge hier nämlich einen etwas einfacheren Ansatz als Raketenschnecke.
Installation ist daher ganz einfach, Code ist auch dokumentiert.

Bei mir läufts seit einigen Tagen stabil, da ich mich aber erst seit kurzem damit beschäftige hab ich noch keine Langzeiterfahrung, auch noch keine Idee wie es auf den verschiedensten Androiden tut.

gruß
bb

Kann ich gerne machen, wenn Du mir die Sachen zukommen lässt. Die erste Hürde habe ich nach Stunden geschaft; Custom Firmware für das Acer A500 um mit USB-LAN Adapter arbeiten zu können. Nun geht es an die Steuerung.

@Raketenschnecke

Hi dake,
eigentlich kein Problem, aber das ist alles Andere als Plug-and-play. Und dirty Code. und nicht dokumentiert… willst du wirklich?

Code wäre halt gut um zu sehen wie Du das eine oder andere gelöst hast. Du hast geschrieben das die Erreichbarkeit nicht immer 100% ist. Ist dieses Problem hauptsächlich wegen der WLAN-Verbindung (wo ich dann wohl nicht hätte mit LAN/USB Adapter) oder ist es mehr wegen dem zusammespiel Tablet/EG/Tasker?

Gruss
Dani

Servus

zzt. ich hätt ich da zwei Varianten am Start.
Die erste ist sehr simpel gestrickt und eignet sich daher gut um das Prinzip zu verstehen.
Sie ist aber nur brauchbar für einzelne EG-Messages.
Wenn EG-Messages schneller angeliefert werden als sie vom Script bzw. Client verarbeitet werden dann machts irgendwann die möglichen PHP Tasks zu.
Es ist auch nicht sichergestellt das wartende EG-Messages auch in der richtigen Reihenfolge beim Clinten ankommen.
Das könnte man zwar abfangen, ich hab den Ansatz dann aber nicht mehr weiterverfolgt.

Die zweite Variante ist im Scriptaufbau etwas komplexer, dafür aber auch sehr viel robuster.
Sie hat am Eingang eine Art Messagequeue in welche EG-Kommandos beliebig schnell und in beliebiger Menge abgeliefert werden können.
Die Scriptlogik sorgt dafür das diese immer in der richtigen Reihenfolge an den Client gesendet werden.
Weiters werden Befehle welche nicht quittiert wurden nochmals gesendet.

Als Vorbereitung stelle bitte sicher das der Android EG mit der Desktop EG Version sauber kommuniziert.

  • d.h. IP Adressen und Post stimmen, keine Firewall dazwischenspukt und am Android die Verbindung EG zum Tasker (sofern du ihn verwenden willst) klappt.

Hier mal Version1


$Id_ClientSocket = IPS_GetParent($_IPS['SELF']);
$IDRegVar = @IPS_GetObjectIDByName("regVarDataBuffer", $Id_ClientSocket);
$IDtempVar = @IPS_GetObjectIDByName("tempVar", $Id_ClientSocket);
$IDlockVar = @IPS_GetObjectIDByName("lockFlag", $Id_ClientSocket);


Switch ($_IPS['SENDER'])
	{

	Case "RunScript":
	break;

	Case "Execute":
	// reserved for debug
	break;

	Case "TimerEvent":
	// reserved for future use
	Break;

   Case "WebFront":
  	// reserved for future use
	break;

	Case "Variable":
	// wait until Interface idle
		while (GetValue($IDlockVar)== true) {
		sleep(1);
		 echo "Command wait";  // debug
		}
		SetValueBoolean($IDlockVar,true);


		SetValue($IDtempVar,$_IPS['VALUE']);

		if (IPS_GetInstance($Id_ClientSocket)['InstanceStatus'] != 102) {// Check if Socket is Active
   	CSCK_SetOpen($Id_ClientSocket,true);
   	IPS_ApplyChanges($Id_ClientSocket);
   	if (IPS_GetInstance($Id_ClientSocket)['InstanceStatus'] != 102) {
 			 SetValueBoolean($IDlockVar,false);
     		echo "Keine Verbindung zu ".IPS_GetName($Id_ClientSocket);
			Return;  // Stop in case Socket Open fail
			}
	}

	RegVar_SendText($IDRegVar, "quintessence
\r"); // initiate handshake
	break;


	Case "RegisterVariable":
		$data = $IPS_VALUE;
		$data = trim($data);
	//	echo $data;

		Switch ($data) {
		Case "accept":    // ready to send data
      	 RegVar_SendText($IDRegVar,GetValueString($IDtempVar)."
\r");  //here the data is sent
      	 SetValueBoolean($IDlockVar,false);
		break;

		case "close":     // data successfull received
			CSCK_SetOpen($Id_ClientSocket,false);
      	SetValueBoolean($IDlockVar,false);
	   break;

  		case "declined":     // any problem
  		// todo: add logic to retry
			CSCK_SetOpen($Id_ClientSocket,false);
      	SetValueBoolean($IDlockVar,false);
	   break;

		Default:       // handshake
			$data .= ":";
     		$hash = md5($data);
     		$hash .= "
";
         RegVar_SendText($IDRegVar, $hash);
		Break;
		}

}

?>

Einzurichten ist das ganze so:

Wichtig: Die Namen der Objekte unter dem Client Socket MÜSSEN exakt so heisen wie im Screenshot. Oder im Script die ersten vier Zeilen entsprechend anpassen.

Die RegisterVariable MUSS mit dem ClientSocket verknüpft sein und „sendData“ als Zielscript eingetragen haben.

Weiters brauchst noch eine Stringvariable in welche du die zu sendenden Messages schreibst. Das Script sendData MUSS durch „bei Änderung“ dieser Stringvariable getriggert werden.
In meinem Screenshot heist diese ComtoSend, der Name ist aber egal.

Wie gesagt, zum ersten probieren ists ganz gut da leicht zu lesen und zu debuggen.

Für produktive Verwendung hab ich was besseres.
Da muß ich aber vorher noch ein paar hardgecodete ID rasuschmeißen und den Code bisl aufräumen.

viel Erfolg
bb

Vielen dank für das Script, bin schon mal fleissig am einrichten. Die Kommunikation EG-PC zu Device/Tasker läuft schon mal.

Folgendes realisiere ich aber erst jetzt. Auf dem PC muss ja Eventghost auch laufen. Standardmässig läuft dies aber nicht als Dienst (gibt wohl einige Tools die sowas können). Habe einen WHS wo ich normalerweise nicht angemeldet bin, müsste dann ja was mit Autologin oder so machen. Wie hast Du dies gelöst?

Dann können ja anscheinend auch LCD’s „einbrennen“ wenn längere Zeit das gleiche Bild (Webfront) vorhanden ist. Wie löst Du dies?

Gruss
Dani

Hi Dani,

ich hab bb’s Lösung nicht im Detail studiert, aber auf dem Server brauchst du keine EG-Installation. Der Android-EG Client spricht direkt mit IPS

Hi Raketenschnecke

Ok danke, das habe ich falsch intepretiert. Hab nur gesehen das EG Android mit EG PC kommunizieren will, aber IPS kann dies ja auch. Bin ich schon mal froh. Was machst Du wegen Einbrennen? Ist bei Dir der Bildschirm dauernd an wenn Anwesend / den Tag durch?

Gruss
Dani

Ich hab nen Server, da ist der Bildschirm nur im Notfall an. Die Android-Tabs schalte ich via EG/Tasker bei Abwesenheit aus. Aber unabhängig davon sehe ich das Risiko zumindest bei den Androiden nicht

Hi Dani

Schnecke war schneller, EG muß am Server nicht laufen.
Es ist nur zur Ersteinrichtung hilfreich um mal zu sehen ob denn grundsätzlich am Client/Firewall ect. alles paßt.

Ich verwende EG neben anderen Dingen eben dafür um das Display am Android an/abzuschalten.
Obs wirklich notwendig ist kann ich nicht sagen, wohl eher nur nice to have.

Im übrigen lief bis dato das WF seit gut einem Jahr 0/24 auf einem billig China Tablett ohne Abschaltung. Bis jetzt kann ich kein einbrennen erkennen.
Im Gegensastz dazu habe ich inder Firma immer wieder normale PC Bildschirme an denen schon nach einigen Monaten die Bildschirmeingabemaske irgendwie eingebrannt zu sehen ist.

Die besser Variante meines Scripts mit Message Queue und konfigurierbarem Errorhandling stell ich heute oder morgen mal rein. zzt. läufts noch im Probebetrieb.

gruß
bb

Ok, vielen dank für die Infos, bleibe dran und melde mich wie es mit dem einrichten klappt.

Gruss
Dani

Soderla

sofern nicht noch irgendwelche Bugs auftreten ist das mal meine Final Version.

Da ist nun die angekündigte Message Queue drinnen mit der sowohl sichergestellt wird das im Problemfall kein Kommando verlorengeht, und diese auch immer in der richtigen Reihenfolge ausgeliefert werden.
Befüllen kann man die Queue in beliebiger Geschwindigkeit. Man muß nicht auf den langsamen Droid Rücksicht nehmen.

Fehlerhandling und Recovery hab ich wesentlich verbessert und teilweise konfigurierbar gemacht.

Wie schon gesagt, Langzeiterfahrungen fehlen noch, soweit schauts aber gut aus.
Wäre nett wennst testen und ggfls. mitdebuggen könntest.

Hier das schon teilweise bekannte „sendData“ Script. Dieses übernimmt auslesen der MessageQueue und versenden an den Droid.
Errorrecovery, Timeouts, und Open/Close Client Socket werden darin komplett erledigt.

Installation:
1)ClientSocket anlegen, IP und Port Eintragen
2) unter Client Socket eine Registervariable mit Namen „regVarDataBuffer“ anlegen. Name MUSS mit Line 2 im Script übereinstimmen.
3)unter ClientSocket ein Script mit Namen „sendData“ anlegen den unteren Inhalt reinkopieren. Auch der Name des Scripts MUSS exakt so geschrieben sein.

  1. Sript einmal ausführen, weitere Variablen werden automatisch angelegt
$Id_ClientSocket = IPS_GetParent($_IPS['SELF']);
$IDRegVar = @IPS_GetObjectIDByName("regVarDataBuffer", $Id_ClientSocket);

$maxRetry = 10;  // retries until giveup und clear buffer, further error processing
$socketReadyDelay = 10; //delay in sec if socket not ready
$msgDelay = 5;  // delay in sec until command is resent

// Nothing to configure below this line

$IDBuffer = CreateVariableByName($Id_ClientSocket, 'BufferToSend', 3);
$IDerrorCount = CreateVariableByName($Id_ClientSocket, 'errorCount', 1);

Switch ($_IPS['SENDER'])
	{
  	Case "Execute":
	// reserved for debug
	//break;

	Case "RunScript":
	if (IPS_GetInstance($Id_ClientSocket)['InstanceStatus'] != 102) {// Check if Socket is Active
   	CSCK_SetOpen($Id_ClientSocket,true);
   	IPS_ApplyChanges($Id_ClientSocket);
   	if (IPS_GetInstance($Id_ClientSocket)['InstanceStatus'] != 102) {
 			 IPS_SetScriptTimer($IPS_SELF, $socketReadyDelay);  //arm Timer for retry
     		echo "Keine Verbindung zu ".IPS_GetName($Id_ClientSocket);
			Return;  // Stop in case Socket Open fail
			}
	}
	RegVar_SendText($IDRegVar, "quintessence
\r"); //  start handshake
	break;


   Case "WebFront":
  	// reserved for future use
	break;

	Case "TimerEvent":
	    IPS_SetScriptTimer($IPS_SELF, 0);  //arm Timer for retry
		$errorCount=GetValue($IDerrorCount);
      $errorCount=$errorCount+1;
      if ($errorCount < $maxRetry) {
         SetValue($IDerrorCount,$errorCount);
     		IPS_RunScript($_IPS['SELF']);// Run next try
			}
		else {
        SetValue($IDerrorCount,0);
        SetValueString($IDBuffer,"nothing to send");
			// todo: add additional error processing there
			}
  	break;
	
	Case "Variable":
		
	break;


	Case "RegisterVariable":
		$data = $IPS_VALUE;
		$data = trim($data);

		Switch ($data) {
		Case "accept":    // ready to send data
		      $buffer=GetValueString($IDBuffer);  //re-read in case modified meanwhile
		  		$data_to_send= substr($buffer,0,strpos ($buffer ,"_+_"));
		   	 RegVar_SendText($IDRegVar,$data_to_send."
\r");  //here the data is sent
		   	  IPS_SetScriptTimer($IPS_SELF, $msgDelay);  //arm Timer for retry if Fail
 		break;

		case "close":     // data successfull send
		   IPS_SetScriptTimer($IPS_SELF, 0);  //Send Ok, stop Timer
            SetValue($IDerrorCount,0);
			CSCK_SetOpen($Id_ClientSocket,false);
      	$buffer=GetValueString($IDBuffer);  //re-read in case modified meanwhile
			if (substr_count ($buffer,"_+_")> 1) {
   			$pos_next =strpos ($buffer ,"_+_");
            SetValueString($IDBuffer,substr($buffer,$pos_next+3,strlen($buffer))); //update
				sleep(1);  //  todo: find minimum delay
				IPS_RunScript($_IPS['SELF']); // re-run to process next command
				}
			else{
				SetValueString($IDBuffer,"nothing to send");
			}
			
	   break;

  		case "declined":     // any problem
  		// todo: add logic to recover,
			CSCK_SetOpen($Id_ClientSocket,false);
         IPS_SetScriptTimer($IPS_SELF, 1);  //arm Timer for retry
			
	   break;

		Default:       // handshake
			$data .= ":";
     		$hash = md5($data);
     		$hash .= "
";
         RegVar_SendText($IDRegVar, $hash);
		Break;
		}

}


function CreateVariableByName($id, $name, $type)
{
   global $IPS_SELF;
   $vid = @IPS_GetVariableIDByName($name, $id);
   if($vid===false) {
 		$vid = IPS_CreateVariable($type);
      IPS_SetParent($vid, $id);
      IPS_SetName($vid, $name);
      IPS_SetInfo($vid, "This Variable was created by Script #$IPS_SELF");
		}
	return $vid;
   
}


Weiters benötigst noch die Function „SendtoDroid“ welche das Befüllen und Handling der Message Queue aus einem beliebigen eigenen Script übernimmt.

Wie diese Funktion aussieht wie sie aufzurufen ist und eine primitive Impementierung ist hier zu sehen:


$IDCSDroid_1 = 35066 /*[Client Socket Haustür Tablett]*/ ;
$IDBuffer_1 = @IPS_GetObjectIDByName("BufferToSend", $IDCSDroid_1);
$IDsendScript_1 = @IPS_GetObjectIDByName("sendData", $IDCSDroid_1);

SendtoDroid($IDBuffer_1,$IDsendScript_1,'DisplayOn');
SendtoDroid($IDBuffer_1,$IDsendScript_1,'showIPSWF');
SendtoDroid($IDBuffer_1,$IDsendScript_1,'sayGutenMorgen');
sleep(5);
SendtoDroid($IDBuffer_1,$IDsendScript_1,'DisplayOff');


//$IDCSDroid_2 = 'xxxxxx' /*[ClientSocket ID of your second Droid*// ;
//$IDBuffer_2 = @IPS_GetObjectIDByName("BufferToSend", $IDCSDroid_2);
//$IDsendScript_2 = @IPS_GetObjectIDByName("sendData", $IDCSDroid_2);
//SendtoDroid($IDBuffer_2,$IDsendScript_2,'DisplayOn');





//----------------------------------------------------------------------
// Call this function to add new command to ClientSocket message queue
// Args[$IDBuffer = ID of Buffer variable] [$new... command to be send]
function SendtoDroid($IDBuffer,$IDsendScript,$new) {
$maxQueueLenght = 20;  // max Commands in Queue
$old = GetValueString($IDBuffer);

// cleanup queue if too much commands pending
if (substr_count ($old,"_+_")> $maxQueueLenght) {
   $old ='nothing to send';    //todo: add error processing if required
    }

if ($old =='nothing to send') {
   SetValue($IDBuffer,$new."_+_");
   IPS_RunScript($IDsendScript);
	}
	else {
	SetValue($IDBuffer,$old.$new."_+_");
	}
}

viel Glück
bb

So, habe Deine Variante 2 mal eingerichtet. Irgendwas klappt aber noch nicht; die Queue wird immer länger mit jedem Befehl, gesendet wird nicht. Muss morgen mal genau schauen ob ich es rauskriege woran es liegt, ist jetzt schon zu spät.

Gruss
Dani

Hallo zusammen, ich habe das Thema Android auch verfolgt und ein bischen getestet. Bei mir läuft die Variante 2 von bb auf anhieb. Alle Befehle werden sauber abgearbeitet. Vielen Dank an bb fürs Einstellen und die Mühe, ich bin immer wieder begeistert was man alles mit dem IPS machen kann.

Ich habe bei mir allerdings festgestellt, das öfter mal der „close“ Befehl, am Ende der Kette, nicht bei IPS ankommt, was dann dazu führt, das der Befehl wiederholt ausgeführt wird. Aber der eigentliche Befehl, kam am Android Endgerät an und wird durch das 2 senden dann ein zweites mal ausgeführt. Das kann z.B. bei Sprachausgabe dann auf dauer etwas nerven… bei den meisten anderen Befehlen würde das keine Rolle spielen.
Kommt das bei anderen auch vor? Oder woran könnte es liegen das der close Befehl irgendwo im System verschwindet?

Servus

danke für die positive Rückmeldung.
Ich sehe den Thread hier etwas als Beta Test, wenns dann mal stabil läuft stell ichs nochmal mit besserer Doku im Scripte Bereich ein.

Zu dem verlorene Stop Befehl: Such mal bitte die Zeile: sleep(1); // todo: find minimum delay
und erhöhe auf sleep(2) oder so.
Wirds besser ?

Das ist die Zeit welche IPS auf die „Close“ Antwort wartet. Wenn das Pad beschäftgt ist ist sie vieleicht etwas zu kurz.

schöne grüße
bb

hi @ll,
das mit der Kommunikation Android <-> IPS ist scheinbar der Knackpunkt schlechthin.
Ich habe 2 Lenovo A1 im Einsatz, die mich extrem enttäuscht haben (Abstürze, nicht erreichbar, ließen sich teilweise nicht mehr einschalten). Nun habe ich einen Tipp von drapple bekommen (riesen Dank dafür), dass es für die Lenovos einen halboffizielles Update auf Android 4.0.4 gibt (die beiden Droiden hatten Android 2.3.x).
Am 30. 08. habe ich den Beiden auf Android 4.0.4 gebracht.

Nun zum eigentlichen Thema:
ich habe probehalber die Kommunikation der Befehle zwischen IPS und den Droiden aufgezeichnet. Auch in meiner Script-Lösung gibts ein Errorhandling auf der IPS-Seite, welches einen Befehl bis zu 8 Mal nochmals versendet, wenn er vom Device nicht bestätigt wurde. Die Anzahl der „Wahlwiederholungen“ sieht man in beiden Charts (alles nördlich der Roten Linie sind Fehler) Im Ersten Bild der Monat August, die fehler dürften nicht zu übersehen sein.
im 2. Bild das verhalten im September (selbes Device), mit Android 4.0.4. Es dürfte auffallen, das kaum noch Fehler auftreten.

als Hauptursache meine ich eine Instabilität der WLAN-Connection im Stanby ausgemacht zu haben. Auch bei den anderen Devices (Acer, Asus) zeigt sich hier eine wesentliche Verbesserung ab Android 4.x.
Was kann man hier tun:
bei mir hat sich bewährt, eine feste IP einzustellen, weiterhin gibts noch ein paar Kleinigkeiten, die ich grad nicht im Kopf habe.
Aber so richtig 100%ig läuft es nicht.