[SOLVED] openHAB 1 -> 2 migration - voice recognition

I have set up a pretty long rule file which was allowing me to have some basic voice recognition using the Androind client.
The import section of the openHAB 1 rule file looks like this:

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.openhab.core.types.Command
import org.openhab.core.items.GenericItem

Now when I want to use this same file in openHAB 2 the Designer complains about the wildcards and about not finding
Command & GenericItem.

Without Command my whole rule would not work as I define a variable on it:

var Command      myCommand = null

and then define what command I want to send:

/* this is the important part - only 1 line with a sendCommand */
if (myItem != null && myCommand != null) myItem.sendCommand(myCommand)

Does anyone know what to import now?

Thanks.

See the migration docs:

http://docs.openhab.org/tutorials/migration.html#rules

Do you really need this command type variable, as I understand it in habdrold the recognised string is put into the “VoiceCommand” text item.

OK - I of course did read the migration guide and the issues occurs after I did what the migration guide is saying.
For your better understanding here is the complete rule file content:

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.openhab.core.types.Command
import org.openhab.core.items.GenericItem

/**********************************************
 * This rules file just contains the rule for
 * voice control - evaluating the string that
 * was sent from Habdroid
 **********************************************/


rule VoiceControl
 when
    Item VoiceCommand received command
 then
    val txt = VoiceCommand.toString.toLowerCase
    var Command      myCommand = null
    var GenericItem     myItem = null
    /* set the command first */

    // in order to avoid that a syllable like "an" is part of a different word
    // an causes a wrong command to be set I switched to matches for those short words
    if(txt.matches(".*\\ban\\b.*") || txt.contains("anschalten") || txt.contains("anmachen")) myCommand = ON
    //if(txt.contains("an") || txt.contains("anschalten"))                           myCommand = ON
    if(txt.contains("aus")|| txt.contains("ausschalten") || txt.contains("ausmachen"))        myCommand = OFF
    if(txt.contains("auf") || txt.contains("rauf") || txt.contains("herauf") 
    	|| txt.contains("hoch") || txt.contains("öffnen") || txt.contains("oben"))           myCommand = UP
    if(txt.contains("ab") || txt.contains("runter")|| txt.contains("herunter")
    	|| txt.contains("schlieĂźen") || txt.contains("unten"))                               myCommand = DOWN
    /* Dimmer 
    myCommand = INCREASE
    myCommand = DECREASE
    */
    /* now define which item should get a command */
    // erdgeschoss
    if(txt.contains("heizung") || txt.matches(".*\\bhar\\b.*")) 
    {
        if(txt.contains("licht")) {
        	myItem = Licht_EG_HAR_LED_Strahler
        	//	Licht_OG_Kueche_Eingang.sendCommand(myCommand)
        }
    }
    else if(txt.contains("garage")) 
    {
        if(txt.contains("licht") || txt.contains("decke")) {
        	myItem = Licht_EG_Garage_Decke
        	//	Licht_OG_Kueche_Eingang.sendCommand(myCommand)
        }
    }
    else if(txt.contains("gästebad") || (txt.contains("bad") && (txt.contains("unten") || txt.contains("erdgescho")) ) ) 
    {
        if(txt.contains("licht")) {
        	myItem = Licht_EG_Gaestebad_Decke
        }
    }
    else if(txt.contains("gästezimmer")) 
    {
        if(txt.contains("licht") || txt.contains("decke")) {
        	myItem = Licht_EG_Gaestezimmer_Decke
        }
    }
    // obergeschoss
     else if(txt.contains("kĂĽche")) 
    {
        if(txt.contains("eingang")) {
        	myItem = Licht_OG_Kueche_Eingang
        	//	Licht_OG_Kueche_Eingang.sendCommand(myCommand)
        }
        else if(txt.contains("fenster")) {
        	myItem = Licht_OG_Kueche_Fenster
        }
        else if(txt.contains("rolläden") || txt.contains("rollläden") || txt.contains("rolladen") || txt.contains("rollladen") || txt.contains("rollo") || txt.contains("rollos")) {
        	myItem = Rollladen_OG_Kueche_Buero
        }
    }
    else if(txt.contains("wohnzimmer") || txt.contains("kino")) 
    {
        if(txt.contains("dimmer") || txt.contains("decke")) {
        	myItem = Licht_OG_Wohnzimmer_Sofa_Dimmer
        }
        else if((txt.contains("led") || txt.contains("dreier")) && (txt.contains("eins") || txt.contains("kaltweiĂź"))) {
        	myItem = Licht_OG_Wohnzimmer_3er_1
        }
        else if((txt.contains("led") || txt.contains("dreier")) && (txt.contains("zwei") || txt.contains("warmweiĂź"))) {
        	myItem = Licht_OG_Wohnzimmer_3er_2
        }
        else if(txt.contains("led")) {
        	myItem = Licht_OG_Wohnzimmer_LED
        }
        else if(txt.contains("rolläden") || txt.contains("rollläden") || txt.contains("rolladen") || txt.contains("rollladen") || txt.contains("rollo") || txt.contains("rollos")) {
        	myItem = Rollladen_OG_Wohnzimmer_Tuer
        }
        else if(txt.contains("kino") || txt.contains("leinwand") || txt.contains("beamer")) {
        	myItem = Szene_OG_Wohnzimmer_Kino
        	// in jedem Fall nochmal das Kommando ĂĽberschreiben, da hier "hoch" und "runter" die Kino Szene starten bzw. beenden
        	if(txt.contains("los") || txt.contains("starten") || txt.contains("start") || txt.contains("runter") ) myCommand = ON
        	if(txt.contains("ende") || txt.contains("hoch") || txt.contains("rauf") ) myCommand = OFF
        }
    }
    else if(txt.contains("bĂĽro")) 
    {
        if(txt.contains("licht") || txt.contains("decke")) {
        	myItem = Licht_OG_Buero_Decke
        	//	Licht_OG_Kueche_Eingang.sendCommand(myCommand)
        }
        else if(txt.contains("rolläden") || txt.contains("rollläden") || txt.contains("rolladen") || txt.contains("rollladen") || txt.contains("rollo") || txt.contains("rollos")) {
        	myItem = Rollladen_OG_Kueche_Buero
        }
    }
    // dachgeschoss
    else if(txt.matches(".*\\bbad\\b.*") && (!txt.contains("unten") || txt.contains("erdgescho"))) 
    {
        if(txt.contains("decke")) {
        	myItem = Licht_DG_Bad_Decke
        	//	Licht_OG_Kueche_Eingang.sendCommand(myCommand)
        }
        else if(txt.contains("halogen") || txt.contains("dreier")) {
        	myItem = Licht_DG_Bad_Halogen
        }
        else if(txt.contains("dusche")) {
        	myItem = Licht_DG_Bad_Dusche
        }
        else if(txt.contains("rolläden") || txt.contains("rollläden") || txt.contains("rolladen") || txt.contains("rollladen") || txt.contains("rollo") || txt.contains("rollos")) {
        	myItem = Rollladen_DG_Bad
        }
    }
    else if(txt.contains("schlafzimmer")) 
    {
        if(txt.contains("led")) {
        	myItem = Licht_DG_Schlafzimmer_LED
        }
        if(txt.contains("links")) {
        	myItem = Licht_DG_Schlafzimmer_Neon_Links
        }
        if(txt.contains("rechts")) {
        	myItem = Licht_DG_Schlafzimmer_Neon_Rechts
        }
        if(txt.contains("wandschrank")) {
        	myItem = Licht_DG_Schlafzimmer_Wandschrank
        }
        else if(txt.contains("rolläden") || txt.contains("rollläden") || txt.contains("rolladen") || txt.contains("rollladen") || txt.contains("rollo") || txt.contains("rollos")) {
        	myItem = Rollladen_DG_Schlafzimmer_Tuer
        }
    }
    // flur
     else if(txt.contains("flur") || txt.contains("floor") || txt.contains("garderobe")) 
    {
        if(txt.contains("eingang") || txt.contains("haustĂĽr")) {
        	myItem = Licht_EG_Flur_Eingang
        }
        else if(txt.contains("garderobe")) {
        	myItem = Licht_EG_Flur_Garderobe
        }
        else if(txt.contains("podest") && !txt.contains("led")) {
        	myItem = Licht_EG_Flur_Podest
        }
        else if(txt.contains("decke")) {
        	myItem = Licht_OG_Flur_Decke
        }
        else if(txt.contains("led")) {
        	myItem = Licht_OG_Flur_LED_Podest
        }
        else if(txt.contains("treppe")) {
        	myItem = Licht_DG_Flur_Decke
        }
        else if(txt.contains("rolläden") || txt.contains("rollläden") || txt.contains("rolladen") || txt.contains("rollladen") || txt.contains("rollo") || txt.contains("rollos")) {
        	myItem = Rollladen_Flure
        }
    }
    /* Steckdosen fĂĽr Stereoanlage */
    else if(txt.contains("mediacenter") || txt.contains("anlage")){ 
    	myItem = Steckdose_OG_Wohnzimmer_MC1_g_b_s 
   	}
   	/* Steckdosen fĂĽr Computer im Heizraum */
   	else if(txt.contains("computer")) {
   			myItem = Steckdose_EG_HAR_Schaltschrank_Rechts		
   	}
       
    /* this is the important part - only 1 line with a sendCommand */
    if (myItem != null && myCommand != null) myItem.sendCommand(myCommand)
  

    /*val myVoiceCommand = receivedCommand.toString
    sendXMPP(XMPP_Receiver, myVoiceCommand) */
 end


As you can see I create the command dynamically by parsing the words contained in the received voice command, so I need the Command object. But the SmartHome Designer complains when I remove the org.openhab.core… imports “Command cannot be resolved to a type.”.

Is this a SmartHome Designer bug and everything will work or is it an different import I now need?
(I can’t test the rule at this time, this is why I ask for the correct import statement.)

Thanks

I found a way to test and now get this error when the VoiceRule gets executed:

An error occurred during the script execution: The name ’ != ’ cannot be resolved to an item or type.

Looking at your code, I see no reason why “myCommand” could not be a String variable.

Thanks! There is really something with the Command which does not work anymore. I changed to String and added a little logging and got it working. Changing this working rule back to Command caused the same error again. So I now leave it as a String.

For anymone interested this is a working version now:


import org.eclipse.smarthome.core.items.GenericItem


/**********************************************
 * This rules file just contains the rule for
 * voice control - evaluating the string that
 * was sent from Habdroid
 **********************************************/


rule VoiceControl
 when
    Item VoiceCommand received command
 then
    val txt = VoiceCommand.toString.toLowerCase
    //var Command      myCommand = null
    var String      myCommand = null
    var GenericItem     myItem = null
    /* log the received voice commend text */
    logInfo("Voice Command String", txt)
    /* set the command first */
 
    // in order to avoid that a syllable like "an" is part of a different word
    // an causes a wrong command to be set I switched to matches for those short words
    if(txt.matches(".*\\ban\\b.*") || txt.contains("anschalten") || txt.contains("anmachen")) myCommand = "ON"
    //if(txt.contains("an") || txt.contains("anschalten"))                           myCommand = ON
    if(txt.matches(".*\\baus\\b.*")|| txt.contains("ausschalten") || txt.contains("ausmachen"))        myCommand = "OFF"
    if(txt.contains("auf") || txt.contains("rauf") || txt.contains("herauf") || txt.contains("hoch") || txt.contains("öffnen") || txt.contains("oben")) myCommand = "UP"
    if(txt.matches(".*\\bab\\b.*") || txt.contains("runter")|| txt.contains("herunter") || txt.contains("schlieĂźen") || txt.contains("unten")) myCommand = "DOWN"
    /* Dimmer 
    myCommand = INCREASE
    myCommand = DECREASE
    */
    /* now define which item should get a command */
    // erdgeschoss
    if(txt.contains("heizung") || txt.matches(".*\\bhar\\b.*")) 
    {
        if(txt.contains("licht")) {
        	myItem = Licht_EG_HAR_LED_Strahler
        	//	Licht_OG_Kueche_Eingang.sendCommand(myCommand)
        }
    }
    else if(txt.contains("garage")) 
    {
        if(txt.contains("licht") || txt.contains("decke")) {
        	myItem = Licht_EG_Garage_Decke
        	//	Licht_OG_Kueche_Eingang.sendCommand(myCommand)
        }
        else if(txt.contains("rolläden") || txt.contains("rollläden") || txt.contains("rolladen") || txt.contains("rollladen") || txt.contains("rollo") || txt.contains("rollos")) {
        	myItem = Rollladen_EG_Garage
        }
    }
    else if(txt.contains("gästebad") || (txt.contains("bad") && (txt.contains("unten") || txt.contains("erdgescho")) ) ) 
    {
        if(txt.contains("licht")) {
        	myItem = Licht_EG_Gaestebad_Decke
        }
    }
    else if(txt.contains("gästezimmer")) 
    {
        if(txt.contains("licht") || txt.contains("decke")) {
        	myItem = Licht_EG_Gaestezimmer_Decke
        }
    }
    // obergeschoss
     else if(txt.contains("kĂĽche")) 
    {
        if(txt.contains("eingang")) {
        	myItem = Licht_OG_Kueche_Eingang
        	//	Licht_OG_Kueche_Eingang.sendCommand(myCommand)
        }
        else if(txt.contains("fenster")) {
        	myItem = Licht_OG_Kueche_Fenster
        }
        else if(txt.contains("rolläden") || txt.contains("rollläden") || txt.contains("rolladen") || txt.contains("rollladen") || txt.contains("rollo") || txt.contains("rollos")) {
        	myItem = Rollladen_OG_Kueche_Buero
        }
    }
    else if(txt.contains("wohnzimmer") || txt.contains("kino")) 
    {
        if(txt.contains("dimmer") || txt.contains("decke")) {
        	myItem = Licht_OG_Wohnzimmer_Sofa_Dimmer
        }
        else if((txt.contains("led") || txt.contains("dreier")) && (txt.contains("eins") || txt.contains("kaltweiĂź"))) {
        	myItem = Licht_OG_Wohnzimmer_3er_1
        }
        else if((txt.contains("led") || txt.contains("dreier")) && (txt.contains("zwei") || txt.contains("warmweiĂź"))) {
        	myItem = Licht_OG_Wohnzimmer_3er_2
        }
        else if(txt.contains("led")) {
        	myItem = Licht_OG_Wohnzimmer_LED
        }
        else if(txt.contains("rolläden") || txt.contains("rollläden") || txt.contains("rolladen") || txt.contains("rollladen") || txt.contains("rollo") || txt.contains("rollos")) {
        	myItem = Rollladen_OG_Wohnzimmer_Tuer
        }
        else if(txt.contains("kino") || txt.contains("leinwand") || txt.contains("beamer")) {
        	myItem = Szene_OG_Wohnzimmer_Kino
        	// in jedem Fall nochmal das Kommando ĂĽberschreiben, da hier "hoch" und "runter" die Kino Szene starten bzw. beenden
        	if(txt.contains("los") || txt.contains("starten") || txt.contains("start") || txt.contains("runter") ) myCommand = "ON"
        	if(txt.contains("ende") || txt.contains("hoch") || txt.contains("rauf") ) myCommand = "OFF"
        }
    }
    else if(txt.contains("bĂĽro")) 
    {
        if(txt.contains("licht") || txt.contains("decke")) {
        	myItem = Licht_OG_Buero_Decke
        	//	Licht_OG_Kueche_Eingang.sendCommand(myCommand)
        }
        else if(txt.contains("rolläden") || txt.contains("rollläden") || txt.contains("rolladen") || txt.contains("rollladen") || txt.contains("rollo") || txt.contains("rollos")) {
        	myItem = Rollladen_OG_Kueche_Buero
        }
    }
    // dachgeschoss
    else if(txt.matches(".*\\bbad\\b.*") && (!txt.contains("unten") || txt.contains("erdgescho"))) 
    {
        if(txt.contains("decke")) {
        	myItem = Licht_DG_Bad_Decke
        	//	Licht_OG_Kueche_Eingang.sendCommand(myCommand)
        }
        else if(txt.contains("halogen") || txt.contains("dreier")) {
        	myItem = Licht_DG_Bad_Halogen
        }
        else if(txt.contains("dusche")) {
        	myItem = Licht_DG_Bad_Dusche
        }
        else if(txt.contains("rolläden") || txt.contains("rollläden") || txt.contains("rolladen") || txt.contains("rollladen") || txt.contains("rollo") || txt.contains("rollos")) {
        	myItem = Rollladen_DG_Bad
        }
    }
    else if(txt.contains("schlafzimmer")) 
    {
        if(txt.contains("led")) {
        	myItem = Licht_DG_Schlafzimmer_LED
        }
        if(txt.contains("links")) {
        	myItem = Licht_DG_Schlafzimmer_Neon_Links
        }
        if(txt.contains("rechts")) {
        	myItem = Licht_DG_Schlafzimmer_Neon_Rechts
        }
        if(txt.contains("wandschrank")) {
        	myItem = Licht_DG_Schlafzimmer_Wandschrank
        }
        else if(txt.contains("rolläden") || txt.contains("rollläden") || txt.contains("rolladen") || txt.contains("rollladen") || txt.contains("rollo") || txt.contains("rollos")) {
        	myItem = Rollladen_DG_Schlafzimmer_Tuer
        }
    }
    // flur
     else if(txt.contains("flur") || txt.contains("floor") || txt.contains("garderobe")) 
    {
        if(txt.contains("eingang") || txt.contains("haustĂĽr")) {
        	myItem = Licht_EG_Flur_Eingang
        }
        else if(txt.contains("garderobe")) {
        	myItem = Licht_EG_Flur_Garderobe
        }
        else if(txt.contains("podest") && !txt.contains("led")) {
        	myItem = Licht_EG_Flur_Podest
        }
        else if(txt.contains("decke")) {
        	myItem = Licht_OG_Flur_Decke
        }
        else if(txt.contains("led")) {
        	myItem = Licht_OG_Flur_LED_Podest
        }
        else if(txt.contains("treppe")) {
        	myItem = Licht_DG_Flur_Decke
        }
        else if(txt.contains("rolläden") || txt.contains("rollläden") || txt.contains("rolladen") || txt.contains("rollladen") || txt.contains("rollo") || txt.contains("rollos")) {
        	myItem = Rollladen_Flure
        }
    }
    /* Steckdosen fĂĽr Stereoanlage */
    else if(txt.contains("mediacenter") || txt.contains("anlage")){ 
    	myItem = Steckdose_OG_Wohnzimmer_MC1_g_b_s 
   	}
   	/* Steckdosen fĂĽr Computer im Heizraum */
   	else if(txt.contains("computer")) {
   			myItem = Steckdose_EG_HAR_Schaltschrank_Rechts		
   	}
    
    /* this is the important part - only 1 line with a sendCommand */
    if (myItem != null && myCommand != null) 
    {
    	logInfo("Voice Item:", myItem.toString)
    	logInfo("Voice Command:", myCommand)
    	myItem.sendCommand(myCommand)
    	}
    	
    
  

    /*val myVoiceCommand = receivedCommand.toString
    sendXMPP(XMPP_Receiver, myVoiceCommand) */
 end

Clearly, you didn’t because if you had you would have read:

All references to org.openhab.core.* in imports and class references should be removed. All of these classes are automatically included and have moved.

in the Necessary Changes: Rules section.

This is likely an ESH Designer issue. There are a lot of things that ESH Designer doesn’t (and probably never will) support. References to Command in specific is rarely done in Rules with people typically referencing the specific state Type since all States are Commands. So perhaps it isn’t in it’s list of “known” objects. But it should work just fine.

But you should be able to use State instead of Command from what I can see of the rule with a quick scan. It isn’t super easy though (please use code fences).

```php
code goes here
```

Other things that won’t work in Designer:

  • Items defined using PaperUI or the REST API
  • Installed Actions
  • Channel rule triggers
1 Like

Sorry to go back on this, but you may not have read the whole text of my post or I have been unclear in which rule I pasted in the post. It was the old openHAB1 rule which I tried to convert to openHAB2, I thought it may make sense to give the full old picture to get a better response because the cumminity can understand my problem better.
Besides the error in the Designer I got also an error on the execution side.

Nevertheless thanks to the help of JĂĽrgen Baginski I moved to String and now everything is working.

Have edited the rules above with code fences - thanks for the tip.

I appreciate everyones input and think this issue is solved from my side.

Thanks.

It’s most helpful to post the rule that doesn’t work rather than the old 1.x rule so we can see exactly what you are using. And some of the errors reported are related to imports so it looked very much like you were trying to use that OH 1.x rule with 1.x imports in OH 2.

If your issue is solved you are free to mark any post in the thead as the solution, that way<the topic will be marked “Solved”.