[SOLVED] FritzBox TR064 - Rule to determine incoming Calls wont work with oH2

Hi there,

i finally had the time to migrate from oH 1.8.3 to the latest oH 2 (openhabian) release.
I started to migrate rules without physial objects first and so i reached the FritzBox TR064 binding and the corresponding rules.
One of my TR064 rules checks for a new call and then processes the informations from the binding into items and Telegram messages.
But this rule isn´t working under oH 2 like it did under oH 1.8.3.
I´m pretty sure it´s just some typo or something very simple that changed between the rule engine…

fritzboxtr064.cfg

url=https://192.168.2.1:49443
refresh=60000
user=pi.openHAB
pass=Thisisasecurepassword

FritzBox.items

/* Anwesenheit iPhones MAP(presence.map): */
Contact fbUserA "UserA [MAP(presence.map):%s]" <presence> {fritzboxtr064="maconline:AA-BB-CC-DD-EE-FF"}
Contact fbUserB "UserB [MAP(presence.map):%s]" <presence> {fritzboxtr064="maconline:AA-BB-CC-DD-EE-FF"}
Contact fbGuest "Guest [MAP(presence.map):%s]" <presence> {fritzboxtr064="maconline:AA-BB-CC-DD-EE-FF"}
Contact fbBusiness "Business [MAP(presence.map):%s]" <presence> {fritzboxtr064="maconline:AA-BB-CC-DD-EE-FF"}

/* Fritz!Box */
Switch fbKlingel "Telefon klingelt [%s]" <phone> {fritzboxtr064="callmonitor_ringing"}
Call fbAnruf "Anruf von [%1$s]" <phone> {fritzboxtr064="callmonitor_ringing"}
Call fbAnrufName "Anruf von [%1$s]" <phone> {fritzboxtr064="callmonitor_ringing:resolveName"}
String fbWANIp "IP-Adresse [%s]" <fritzbox> {fritzboxtr064="externalWanip"}
String fbLastNumber "Letzter Anrufer [%s]" <phone>
String fbLastName "Letzter Anrufer [%s]" <phone>

default.sitemap

			Text item=fbWANIp
			Text item=fbLastNumber visibility=[itmExpert == ON]
			Text item=fbLastName visibility=[itmExpert == ON]

fbLastCall.rules

import org.openhab.library.tel.types.CallType

rule "Eingehender Anruf"

when

	Item fbKlingel changed from OFF to ON

then

	// Daten des CallType auslesen
	val CallType call = fbAnruf.state as CallType

	// Die Variablen anlegen und mit der Nummer bzw. Namen des Anrufers füllen
	val String LastCallNumber = call.destNum.toString()
	var String LastCallName   = fbAnrufName.state.toString()

	// Prüfen ob es sich um ein Fax handelt
	if(LastCallName.startsWith("1237891##"))
	{
		return (false)
	}

	// Prüfen ob der Anruf privat ist und zur weiteren Identifizierung markieren
	if(LastCallName.startsWith("7891237##"))
	{
		LastCallName = LastCallName.removeStart("7891237##")
		LastCallName = "Privat: " + LastCallName
	}


	// Prüfen ob der Anruf beruflich ist und zur weiteren Identifizierung markieren
	if(LastCallName.startsWith("4561237##"))
	{
		LastCallName = LastCallName.removeStart("4561237##")
		LastCallName = "Arbeit: " + LastCallName
	}

	// Prüfen ob der Anrufer unbekannt ist und entsprechend markieren
	if(LastCallName.startsWith("Arbeit: Name not found for") || LastCallName.startsWith("Privat: Name not found for"))
	{
		if(LastCallName.startsWith("Arbeit"))
		{
			LastCallName = "Arbeit: Unbekannt"
		}

		if(LastCallName.startsWith("Privat"))
		{
			LastCallName = "Privat: Unbekannt"
		}
	}

	// Entfernt die Info des Telefonbucheintrags
	if(LastCallName.endsWith("(Work)") || LastCallName.endsWith("(Mobile)"))
	{
		LastCallName = LastCallName.removeEnd(" (Mobile)")
		LastCallName = LastCallName.removeEnd(" (Work)")
	}

	// Die Daten in die Items eintragen
	if(LastCallName.startsWith("Privat"))
	{
		LastCallName = LastCallName.removeStart("Privat: ")
		postUpdate(fbLastNumber, LastCallNumber)
		postUpdate(fbLastName, LastCallName)
		logDebug("RuleLastCall", "Der Anruf von " + LastCallNumber + " (" + LastCallName + ")" + " wurde als Letzter Anrufer gespeichert.")
	}

	// Eine E-Mail versenden wenn der Anruf beruflich war
	if(LastCallName.startsWith("Arbeit"))
	{
		logDebug("RuleLastCall", "Der Anruf war beruflich, es wird eine E-Mail versendet")
		LastCallName = LastCallName.removeStart("Arbeit: ")
		sendMail("myname@business.com", "Verpasster Anruf von " + LastCallNumber + " (" + LastCallName + ")", "Hallo Michael,\r\nfolgender Anruf wurde verpasst: " + LastCallNumber + " (" + LastCallName +")" + "\r\n\r\nFreundliche Grüße\r\nopenHAB")

	}
	// Prüfen ob Michael zuhause ist
	if(fbMichael.state == CLOSED)
	{
		// Nur über private Anrufe benachrichtigen
		if(LastCallName.startsWith("Arbeit"))
		{
			logDebug("RuleLastCall", "Der Anruf war beruflich, es wird eine E-Mail versendet")
		}
		else
		{
			logDebug("RuleLastCall", "Es wird eine Nachricht an Michael versendet.")
			LastCallName = LastCallName.removeStart("Privat: ")
			var LastCallTextDoor = "Folgender Anruf wurde verpasst: "
			LastCallTextDoor = LastCallTextDoor + LastCallNumber + " (" + LastCallName + ")"
			sendTelegram("bot1", LastCallTextDoor)
		}
	}

	// Prüfen ob Johanna zuhause ist
	if(fbJohanna.state == CLOSED)
	{
		// Nur über private Anrufe benachrichtigen
		if(LastCallName.startsWith("Arbeit"))
		{
			logDebug("RuleLastCall", "Der Anruf war beruflich, es wird keine Nachricht versendet")
			return (false)
		}
		else
		{
			logDebug("RuleLastCall", "Es wird eine Nachricht an Johanna versendet.")
			LastCallName = LastCallName.removeStart("Privat: ")
			var LastCallTextDoor = "Folgender Anruf wurde verpasst: "
			LastCallTextDoor = LastCallTextDoor + LastCallNumber + " (" + LastCallName + ")"
			sendTelegram("bot2", LastCallTextDoor)
		}
	}

end

Logfile

2018-07-15 12:10:18.061 [INFO ] [tzboxtr064.internal.PhonebookManager] - Trying to resolve number 0123456789 to name comparing 7 characters

2018-07-15 12:10:18.067 [INFO ] [tzboxtr064.internal.PhonebookManager] - found name match Michael Bredehorn in phonebook by comparing 987654 321 94+ with 987654 

==> /var/log/openhab2/events.log <==

2018-07-15 12:10:18.119 [vent.ItemStateChangedEvent] - fbAnruf changed from  to 7891237,0123456789

2018-07-15 12:10:18.141 [vent.ItemStateChangedEvent] - fbAnrufName changed from  to 7891237,Michael  (Mobile)

2018-07-15 12:10:18.146 [vent.ItemStateChangedEvent] - fbKlingel changed from OFF to ON

==> /var/log/openhab2/openhab.log <==

2018-07-15 12:10:19.344 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Eingehender Anruf': Could not cast 1379060,01728158771 to void; line 12, column 22, length 25

==> /var/log/openhab2/events.log <==

2018-07-15 12:10:23.201 [vent.ItemStateChangedEvent] - fbAnruf changed from 7891237,0123456789 to 

2018-07-15 12:10:23.206 [vent.ItemStateChangedEvent] - fbAnrufName changed from 7891237,Michael  (Mobile) to 

2018-07-15 12:10:23.212 [vent.ItemStateChangedEvent] - fbKlingel changed from ON to OFF

The code in line 12 is:

	val CallType call = fbAnruf.state as CallType

Any ideas why this rule isn´t working in oH2 but is still working in my oH 1.8.3 environment?

kind regards
Michael

  • Platform information:
    • Hardware: Raspberry Pi 3 Model B Plus Rev 1.3
    • OS: Raspbian GNU/Linux 9 (stretch) / Linux 4.14.52-v7+
    • Java Runtime Environment:
      openjdk version “1.8.0_152”
      OpenJDK Runtime Environment (Zulu Embedded 8.25.0.76-linux-aarch32hf) (build 1.8.0_152-b76)
      OpenJDK Client VM (Zulu Embedded 8.25.0.76-linux-aarch32hf) (build 25.152-b76, mixed mode, Evaluation)
    • openHAB version: openHAB 2.3.0-1 (Release Build)

I found some confusing informations about the CallType in oH2.
In one thread there´s a comment linked from @Kai that CallType doesn´t exist anymore but CallItem is now part of ESH.

The solution was val incCall = fboxIncomingCallResolved.state as StringListType.
When i´m using StringListType my ESH Designer says StringListType cannot be resolved to a type.

The rule still starts working and i found alot of things to change between the oH1 CallType and oH2 (not)CallType(butstillCallItem).

While trying to rebuild the rule i got some new errors in my log:

2018-07-15 21:58:36.043 [WARN ] [ab.action.telegram.internal.Telegram] - Transport error: {}

java.net.SocketTimeoutException: Read timed out

	at java.net.SocketInputStream.socketRead0(Native Method) ~[?:?]

	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) ~[?:?]

	at java.net.SocketInputStream.read(SocketInputStream.java:171) ~[?:?]

	at java.net.SocketInputStream.read(SocketInputStream.java:141) ~[?:?]

	at sun.security.ssl.InputRecord.readFully(InputRecord.java:465) ~[?:?]

	at sun.security.ssl.InputRecord.read(InputRecord.java:503) ~[?:?]

	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983) ~[?:?]

	at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:940) ~[?:?]

	at sun.security.ssl.AppInputStream.read(AppInputStream.java:105) ~[?:?]

	at java.io.BufferedInputStream.fill(BufferedInputStream.java:246) ~[?:?]

	at java.io.BufferedInputStream.read(BufferedInputStream.java:265) ~[?:?]

	at org.apache.commons.httpclient.HttpParser.readRawLine(HttpParser.java:78) ~[?:?]

	at org.apache.commons.httpclient.HttpParser.readLine(HttpParser.java:106) ~[?:?]

	at org.apache.commons.httpclient.HttpConnection.readLine(HttpConnection.java:1116) ~[?:?]

	at org.apache.commons.httpclient.HttpMethodBase.readStatusLine(HttpMethodBase.java:1973) ~[?:?]

	at org.apache.commons.httpclient.HttpMethodBase.readResponse(HttpMethodBase.java:1735) ~[?:?]

	at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1098) ~[?:?]

	at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398) ~[?:?]

	at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) ~[?:?]

	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) ~[?:?]

	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) ~[?:?]

	at org.openhab.action.telegram.internal.Telegram.sendTelegram(Telegram.java:96) ~[?:?]

	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]

	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]

	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]

	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:1085) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:1060) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1046) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:991) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:143) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:446) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:463) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:243) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:446) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:459) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:243) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:446) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:189) ~[?:?]

	at org.eclipse.smarthome.model.script.runtime.internal.engine.ScriptImpl.execute(ScriptImpl.java:82) ~[?:?]

	at org.eclipse.smarthome.model.rule.runtime.internal.engine.RuleEngineImpl.lambda$2(RuleEngineImpl.java:345) ~[?:?]

	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:?]

	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]

	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [?:?]

	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [?:?]

	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]

	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]

	at java.lang.Thread.run(Thread.java:748) [?:?]

Okay Telegram is now working (just did a reboot) but i´m getting double Mails from sendMail and double messages from sendTelegram.
I already found a thread about this issue: Rule with Telegram notification sends 3 messages

As i´m using the ESH Designer i´m not sure where the issue is coming from…

The even more confusing part is that i´m getting an E-Mail and Telegram message for business calls.
The rules should not send a Telegram message when the LastCallName starts with “Arbeit:”.
And guess what? It starts with “Arbeit”…

Part of the rule:

	// Prüfen ob Michael zuhause ist
	if(fbMichael.state == CLOSED)
	{
		logInfo("LastCall9", "LastCallNumber: " + LastCallNumber)
		logInfo("LastCall9", "LastCallName: " + LastCallName)
		// Nur über private Anrufe benachrichtigen
		if(LastCallName.startsWith("Arbeit"))
		{
			logInfo("RuleLastCall", "Der Anruf war beruflich, es wird eine E-Mail versendet")
		}
		else
		{
			logInfo("RuleLastCall", "Es wird eine Nachricht an Michael versendet.")
			LastCallName = LastCallName.removeStart("Privat: ")
			var LastCallTextDoor = "Folgender Anruf wurde verpasst: "
			LastCallTextDoor = LastCallTextDoor + LastCallNumber + " (" + LastCallName + ")"
			sendTelegram("bot1", LastCallTextDoor)
		}
	}

Log:

2018-07-15 22:16:27.358 [INFO ] [pse.smarthome.model.script.LastCall9] - LastCallNumber: 0123456789

2018-07-15 22:16:27.361 [INFO ] [pse.smarthome.model.script.LastCall9] - LastCallName: Arbeit: Michael Bredehorn

2018-07-15 22:16:27.364 [INFO ] [.smarthome.model.script.RuleLastCall] - Der Anruf war beruflich, es wird eine E-Mail versendet

So the part logInfo("RuleLastCall", "Es wird eine Nachricht an Michael versendet.") isn´t getting triggered but sendTelegram("bot1", LastCallTextDoor) still get´s executed.

With this sort of problems i´m going to need a few month for my whole migration…

You should not use ESH Designer any longer, instead search the forum for VS Code.

As i´m no developer VS is not really my prefered way to design oH rules.
The Mac version doesn´t event find the openhab extension and won´t accept it as a file.
The Windows version also doesn´t find the extension when searching for online extensions.
The link from the Microsoft Store doesn´t get opened in VS.
EDIT: Okay there´s not just Visual Studio but four different versions of this tool. Hell yeah, all non developers definitely know this!

I´m sorry to say that but oH 2 did a great step backwards for non developers…
First the oH Designer got killed and now we shouldn´t use the ESH Designer.

By the way: I´m still getting double messages and mails…

EDIT2: Even with return; the sendTelegram gets executed.
I think my rule engine is a little bit crazy…
The log says “Der Anruf war beruflich, es wird eine E-Mail versendet” so the if in if(LastCallName.startsWith("Arbeit")) is working fine but the rule engine still executes the else

EDIT3: After deleting the rules, restarting the hole Pi3 and setting up the correct permissions i finally got the rule working like in oH 1.8.3.

Finale rule for oH 2:

rule "Eingehender Anruf"

when

	Item fbKlingel changed from OFF to ON

then

	// Daten des CallType auslesen
	val incCall = fbAnruf.state as StringListType

	// Die Variablen anlegen und mit der Nummer bzw. Namen des Anrufers füllen
	var String LastCallNumber = incCall.getValue(1)
	var String LastCallName = fbAnrufName.state.toString
	
	logInfo("LastCall1", "LastCallNumber: " + LastCallNumber)
	logInfo("LastCall1", "LastCallName: " + LastCallName)

	// Prüfen ob es sich um ein Fax handelt
	if(LastCallName.startsWith("4561237"))
	{
		return;
	}

	// Prüfen ob der Anruf privat ist und zur weiteren Identifizierung markieren
	if(LastCallName.startsWith("1237894"))
	{
		LastCallName = LastCallName.removeStart("1237894,")
		LastCallName = "Privat: " + LastCallName
		logInfo("LastCall2", "LastCallNumber: " + LastCallNumber)
		logInfo("LastCall2", "LastCallName: " + LastCallName)
	}


	// Prüfen ob der Anruf beruflich ist und zur weiteren Identifizierung markieren
	if(LastCallName.startsWith("7891234"))
	{
		LastCallName = LastCallName.removeStart("7891234,")
		LastCallName = "Arbeit: " + LastCallName
		logInfo("LastCall3", "LastCallNumber: " + LastCallNumber)
		logInfo("LastCall3", "LastCallName: " + LastCallName)
	}

	// Prüfen ob der Anrufer unbekannt ist und entsprechend markieren
	if(LastCallName.startsWith("Arbeit: Name not found for") || LastCallName.startsWith("Privat: Name not found for"))
	{
		if(LastCallName.startsWith("Arbeit"))
		{
			LastCallName = "Arbeit: Unbekannt"
			logInfo("LastCall4", "LastCallNumber: " + LastCallNumber)
			logInfo("LastCall4", "LastCallName: " + LastCallName)
		}

		if(LastCallName.startsWith("Privat"))
		{
			LastCallName = "Privat: Unbekannt"
			logInfo("LastCall5", "LastCallNumber: " + LastCallNumber)
			logInfo("LastCall5", "LastCallName: " + LastCallName)
		}
	}

	// Entfernt die Info des Telefonbucheintrags
	if(LastCallName.endsWith("(Work)") || LastCallName.endsWith("(Mobile)"))
	{
		LastCallName = LastCallName.removeEnd(" (Mobile)")
		LastCallName = LastCallName.removeEnd(" (Work)")
		logInfo("LastCall6", "LastCallNumber: " + LastCallNumber)
		logInfo("LastCall6", "LastCallName: " + LastCallName)
	}

	// Die Daten in die Items eintragen
	if(LastCallName.startsWith("Privat"))
	{
		var LastCallSitemap = LastCallName
		LastCallSitemap = LastCallSitemap.removeStart("Privat: ")
		postUpdate(fbLastNumber, LastCallNumber)
		postUpdate(fbLastName, LastCallSitemap)
		logDebug("RuleLastCall", "Der Anruf von " + LastCallNumber + " (" + LastCallName + ")" + " wurde als Letzter Anrufer gespeichert.")
		logInfo("LastCall7", "LastCallNumber: " + LastCallNumber)
		logInfo("LastCall7", "LastCallName: " + LastCallName)
	}

	// Eine E-Mail versenden wenn der Anruf beruflich war
	if(LastCallName.startsWith("Arbeit"))
	{
		logDebug("RuleLastCall", "Der Anruf war beruflich, es wird eine E-Mail versendet")
		var LastCallWork = LastCallName
		LastCallWork = LastCallWork.removeStart("Arbeit: ")
		sendMail("myname@business.com", "Verpasster Anruf von " + LastCallNumber + " (" + LastCallWork + ")", "Hallo Michael,\r\nfolgender Anruf wurde verpasst: " + LastCallNumber + " (" + LastCallWork +")" + "\r\n\r\nFreundliche Grüße\r\nopenHAB")
		logInfo("LastCall8", "LastCallNumber: " + LastCallNumber)
		logInfo("LastCall8", "LastCallName: " + LastCallWork)

	}
	// Prüfen ob Michael zuhause ist
	if(fbMichael.state == CLOSED)
	{
		logInfo("LastCall9", "LastCallNumber: " + LastCallNumber)
		logInfo("LastCall9", "LastCallName: " + LastCallName)
		// Nur über private Anrufe benachrichtigen
		if(LastCallName.startsWith("Arbeit"))
		{
			logInfo("RuleLastCall", "Der Anruf war beruflich, es wird eine E-Mail versendet")
		}
		else
		{
			logInfo("RuleLastCall", "Es wird eine Nachricht an Michael versendet.")
			LastCallName = LastCallName.removeStart("Privat: ")
			var LastCallTextDoor = "Folgender Anruf wurde verpasst: "
			LastCallTextDoor = LastCallTextDoor + LastCallNumber + " (" + LastCallName + ")"
			sendTelegram("bot1", LastCallTextDoor)
		}
	}

	// Prüfen ob Johanna zuhause ist
	if(fbJohanna.state == CLOSED)
	{
		logInfo("LastCall10", "LastCallNumber: " + LastCallNumber)
		logInfo("LastCall10", "LastCallName: " + LastCallName)
		// Nur über private Anrufe benachrichtigen
		if(LastCallName.startsWith("Arbeit"))
		{
			logInfo("RuleLastCall", "Der Anruf war beruflich, es wird keine Nachricht an Johanna versendet")
		}
		else
		{
			logInfo("RuleLastCall", "Es wird eine Nachricht an Johanna versendet.")
			LastCallName = LastCallName.removeStart("Privat: ")
			var LastCallTextDoor = "Folgender Anruf wurde verpasst: "
			LastCallTextDoor = LastCallTextDoor + LastCallNumber + " (" + LastCallName + ")"
			sendTelegram("bot2", LastCallTextDoor)
		}
	}

end

That’s why I recommended to search the forum for VS Code.
There is no further development on the Designer, but VS Code has way more potential and features, like a tree view for your rules.
And this is definitely no backstep for non developers, it is a great step forward.

Visual Studio is not VSCode.

VSCode is an open source editor and not available on the Windows Store. If you looked for just Visual Studio, you found the wrong thing.

ESH Designer was basically dead as of OH 2.0. It was never fully updated to OH 2.0 and certainly has been kept up to date. For the most part, VSCode works pretty much the same as ESH Designer did. Once you install and configure the extension you just open your conf folder and you get your various files list on the left, text editor in the middle, and list of problems on the bottom. Only with VSCode you now get much more specific information about problems, you have a realtime preview of the sitemap that works, it will always be up to date in terms of syntax checking since all that is now performed on your OH server instead, it’s way faster, way less memory hungry, and it has a terminal

It didn’t get killed so much as a problem that was very difficult to fix was encountered and a better option came along.

I did and found the VS Code Category with threads about problems and some release threads. Inside the release threads you only find a link to extension but not to VS code itself.
So i searched for Visual Studio and found a Microsoft page with four different variants.
Again, i‘m no developer so i choosed what seems to the right.
Some of the documentations for oH are only clear to developers and miss some more clear informations for non developers.

Now i know the difference.
It‘s just another editor but has the same name as the Microsoft developing environment.
It‘s not a oH fault but it‘s not really clear for a non developer like me.

I finally found the right Visual Studio Code application and was able to install the extension.

It‘s not very helpful that some pretty basic things (the oH things and other things) changed betwern oH 1.8.3 and oH 2.
It‘s like getting started again because i can‘t just migrate my rules because of changes in the bindings and values…

As always, we welcome any PRs you or any other user is willing to submit.

OH 2 is a nearly complete rewrite and some pretty basic things changed to enable some pretty major new capabilities.

You can if you stick to just the OH 1.x version bindings. As recommended in the Migration from 1.x to 2.x Tutorial you can do just that. If you are using all the same 1.x bindings, the amount of changes required in Rules or anywhere else is relatively minimal. However when you move to a 2.x version binding, they are a completely newly written binding to take advantage of the new features of the OH 2.x architecture (Things, Channels, etc). That is why the Migration Tutorial is written to first get your OH 1.x setup working largely unchanged and then start to migrate to 2.x bindings, if desired, one at a time.

I found the discussion about CallType.
It‘s not in oH2 because oH2 is based on Eclipse and some people didn‘t want specialized things in eclipse.
Found in: https://github.com/eclipse/smarthome/pull/236

But where?
There‘s no direct contact feature under a documentation like in many other projects.
Just create another thread in the community?

This is at the bottom of almost every one of the docs pages right now:

Clicking the link will take you straight to the place where you can edit it.

If you want to discuss something or make larger changes then you can start a discussion on the forum or open an issue at https://github.com/openhab/openhab-docs.

And again: I‘m no developer…
I don‘t want to edit it, i just want to tell that there‘s an issue.

You don’t have to be a developer to edit docs. They are just text files. If only developers edit docs then the docs will continue to be “only clear to developers.” If you are not willing to contribute, that is perfectly fine. But unless some other contributor feels willing to donate their free time nothing will get done.

You’ve said nothing above that we don’t already know. You’ve said nothing above that hasn’t been brought up multiple times on this forum. Filing a well crafted issues may help document some ways to make it better. But if you and users like you are not willing to step up and help then don’t expect anything to come of it.

Please be

  • specific
  • provide actionable recomendations
  • smallish in scope unless you are willing to take on the work to make the changes.

“Your docs suck and I don’t understand them” isn’t going to go very far. “You should write the docs so no-programmers can understand them” isn’t going to accomplish much.

We can’t “fix” an issue like that. It is basically just a way for you to complain but it won’t make anything better.

All development and writing of the docs is performed by individuals who are donating their own free time to work on what they happen to want to work on. We can’t force anyone to work on anything they don’t want to. If you write an issue that will take hundreds of man hours to completely rework whole sections of the docs but are not willing to work on will probably just sit there awaiting someone who is willing to donate their time to work it. In other words, it will never get done.

1 Like

I already did in my other thread about the iCloud binding. But it seems like no one is reading it.
So please calm down a little bit…
It‘s not like i just said the docs are shit and didn‘t told someone what especially is wrong.

And it‘s not just „editing“ the docs…
You need to have a Github account (yeah perfectly normal for non developers to have an account on an developing dristribution platform), then fork something (forks belong to the kitchen), edit it and finally ask for a merge.
That‘s why developers and non developers have such a different view on things!
It‘s not just editing a document!
It‘s a whole process that might be perfectly clear to developers but not to users.

<plonk>