NLSP - Stage 1 Working - English Natural Language Voice Control Rule

NOTE:

This currently does not figure out the command, which should be easy I just havnt gotten to it yet. Currently this takes the command and figures out the most likely item as a target for that voice command

My naming scheme for groups and items is as follows.

Main group = floor
secondary group = floor_room
item name = floor_room_item

Example:
All

->upstairs
---->upstairs_lights
------->upstairs_bedroom_one_light
------->upstairs_kitchen_light
---->upstairs_bedroom_one
------->upstairs_bedroom_one_light
---->upstairs_kitchen

->downstairs
---->downstairs_bedroom_one
---->downstairs_bathroom

->garage
->lights
->general

At the moment it just prints out the most likely items after it is done processing.

The process

  1. chops up voice command
  2. searches top level groups and assigns points for each word in voice command found in group name
  3. most like groups then get searched - all members - and points are assigned to each item for each word in the command it contains
  4. the most likely items or groups are added to a hashmap - as long as they do not appear in the defined ignored items list
  5. the items in the previous hashmap then have their groups searched, assigning points for each word in the voice command found - using .groupNames
  6. The most likely candidates are then added to the final map and currently their names are - sorry for this in advance - println to the console.

here is the rule

some of the imports arent used… i think

This was and continues to be my everest, when I am finished it will be flawless I promise. Also please if you have any suiggestions are any ways the code can be cleaned up please do feel free to comment, it will only make it better.

import org.joda.time.*
import org.eclipse.xtext.xbase.lib.*
import org.openhab.core.persistence.*
import org.openhab.core.items.*
import org.openhab.core.library.types.*
import org.openhab.core.library.types.PercentType
import org.openhab.core.library.items.SwitchItem
import org.openhab.core.library.items.NumberItem
import org.openhab.core.library.items.GroupItem
import org.openhab.core.library.items.DimmerItem
import org.openhab.core.library.items.StringItem
import org.openhab.model.script.actions.*
import org.openhab.model.script.actions.Timer
import java.util.HashMap
import java.util.LinkedHashMap
import java.util.List
import java.util.ArrayList
import java.util.Map 
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock

val ArrayList<String> ignoredItems = newArrayList("upstairs_bathroom_light_state", "upstairs_kitchen_light_state", "bedroom_one_light_state", "upstairs_bathroom_light_manual_switch", "upstairs_kitchen_light_manual_override") 

rule "VoiceCommand"
when
Item VoiceCommand received command
then

var String comm = "what is the temperature of the bedroom upstairs" 
		var String command = " " + comm + " "
		//Split the voice command into an array or the different words
		var String[] arr = command.replace(" in ", " ").replace(" the ", " ").replace(" on ", " ").trim.split(" ")
	
		//Hashmap that will be used to store the points for likelyhood for each item
		val HashMap<String, LinkedHashMap<String, Object>> possibleItems = new HashMap<String, LinkedHashMap<String, Object>>()
		var aMembers = All?.members.map[it]
		//Loop through each word in the voice command word array
		for(member : aMembers) {
			val LinkedHashMap<String, Object> temp1 = new LinkedHashMap<String, Object>()
			for(String word : arr) {
				if(member.name.contains(word)) {
					if(possibleItems.get(member.name) == Uninitialized || possibleItems.get(member.name) == null) {
						temp1.put("item", member)
						temp1.put("possibility", 1)
						possibleItems.put(member.name, temp1)
					} else {
						temp1.put("item", member)
						var Number poss = possibleItems.entrySet().get(member.name).get("possibility")
						temp1.put("possibility", poss + 1)
						possibleItems.put(member.name, temp1)
					}
					
				}
			}
		}
		val HashMap<String, Object> possibleItemsB = new HashMap<String, Object>()
		for(memberB : possibleItems.entrySet()) { 
			val GroupItem hh = memberB.getValue().get("item") as GroupItem
			hh.allMembers.forEach[e | 
				possibleItemsB.put(e.name, e)
			]
		}
		val HashMap<String, LinkedHashMap<String, Object>> possibleItemsC = new HashMap<String, LinkedHashMap<String, Object>>()
		for(memberC : possibleItemsB.keySet()) {
			val LinkedHashMap<String, Object> temp2 = new LinkedHashMap<String, Object>()
			for(String word2 : arr) {
				if(memberC.contains(word2)) {
					
					if(possibleItemsC.get(memberC) == Uninitialized || possibleItemsC.get(memberC) == null) {
					
						temp2.put("item", possibleItemsB.get(memberC))
						temp2.put("possibility", 1)
						possibleItemsC.put(memberC, temp2)
					
					} else {
						
						temp2.put("item", possibleItemsB.get(memberC))
						val Number poss = possibleItemsC.get(memberC).get("possibility")
					
						temp2.put("possibility", (poss))
						possibleItemsC.put(memberC, temp2)
						//println(possibleItemsC)
					}
				}
			}
		}
		var HashMap<String, String> winnerMap = new HashMap<String, String>()
		val Number highCount = 0
		val String winner = ""
		for(key : possibleItemsC.keySet()) {
			var Number finalPoss= possibleItemsC.get(key).get("possibility")
			
			var Number check = 1
			for(String a : ignoredItems) {
				if(a.trim == key.trim) {
					check = 0
				}
			}
			
			if(check == 1) {
				var itemasstring = possibleItemsC.get(key).get("item").toString
					
					if(itemasstring.contains("NumberItem")) {
						var NumberItem itemasitem = possibleItemsC.get(key).get("item") as NumberItem
						for(String word3 : arr) {
						
							if(itemasitem.groupNames.toString.contains(word3.trim)) {
							 	finalPoss = finalPoss + 1
							}
						}
					} else if(itemasstring.contains("StringItem")) {
						val StringItem itemasitem = possibleItemsC.get(key).get("item") as StringItem
						for(String word3 : arr) {
						
							if(itemasitem.groupNames.toString.contains(word3.trim)) {
							 	finalPoss = finalPoss + 1
							}
						}
					} else if(itemasstring.contains("DimmerItem")) {
						var DimmerItem itemasitem =  possibleItemsC.get(key).get("item") as DimmerItem
						for(String word3 : arr) {
							if(itemasitem.groupNames.toString.contains(word3.trim)) {
							 	finalPoss = finalPoss + 1
							}
						}
					} else if(itemasstring.contains("SwitchItem")) {
						var SwitchItem itemasitem =  possibleItemsC.get(key).get("item") as SwitchItem
						for(String word3 : arr) {
						
							if(itemasitem.groupNames.toString.contains(word3.trim)) {
							 	finalPoss = finalPoss + 1
							}
						}
					} else {
						//println(possibleItemsB.get(memberC))
					
					}
					
					
				if(finalPoss > highCount) {
					highCount = finalPoss
					winnerMap = new HashMap<String, String>()
					winnerMap.put(key, finalPoss)
				} else if(finalPoss == highCount){
					winnerMap.put(key, finalPoss)
				}
			}
		}
		for(key : winnerMap.keySet()) {
			println(key)	
		}

end
1 Like