Skip to content

Commit c8b6141

Browse files
author
respeaker
committed
script commit
1 parent 1a41e2b commit c8b6141

File tree

1 file changed

+202
-0
lines changed

1 file changed

+202
-0
lines changed

action-switch.py

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
import configparser
5+
from hermes_python.hermes import Hermes
6+
from hermes_python.ffi.utils import MqttOptions
7+
from hermes_python.ontology import *
8+
import io
9+
import requests
10+
# import urllib2
11+
import json
12+
import jellyfish
13+
14+
MAX_JARO_DISTANCE = 0.4
15+
16+
CONFIGURATION_ENCODING_FORMAT = "utf-8"
17+
CONFIG_INI = "config.ini"
18+
19+
class SnipsConfigParser(configparser.SafeConfigParser):
20+
def to_dict(self):
21+
return {section : {option_name : option for option_name, option in self.items(section)} for section in self.sections()}
22+
23+
24+
def read_configuration_file(configuration_file):
25+
try:
26+
with io.open(configuration_file, encoding=CONFIGURATION_ENCODING_FORMAT) as f:
27+
conf_parser = SnipsConfigParser()
28+
conf_parser.readfp(f)
29+
return conf_parser.to_dict()
30+
except (IOError, configparser.Error) as e:
31+
return dict()
32+
33+
#def subscribe_intent_callback(hermes, intentMessage):
34+
# conf = read_configuration_file(CONFIG_INI)
35+
# action_wrapper(hermes, intentMessage, conf)
36+
37+
def subscribe_intent_callback(hermes, intentMessage):
38+
conf = read_configuration_file(CONFIG_INI)
39+
print(conf)
40+
print(hermes)
41+
print(intentMessage)
42+
# a=IntentClassifierResult(intentMessage).intent_name
43+
# hermes.publish_end_session(intentMessage.session_id, u"Ok, das mache ich.")
44+
hermes.publish_continue_session(intentMessage.session_id, u"Ok,",["ryanrudak:switch","ryanrudak:verschiedene"])
45+
#hermes.publish_continue_session(intentMessage.session_id, "Ok",texte)
46+
47+
if len(intentMessage.slots.verschiedene) > 0:
48+
print('---------diverse direkt----------')
49+
action_wrapperOrdreDirect(hermes, intentMessage, conf)
50+
else:
51+
print('---------diverse Aktionen----------')
52+
action_wrapperOrdre(hermes, intentMessage, conf)
53+
54+
55+
def action_wrapperOrdre(hermes, intentMessage, conf):
56+
myListSceneOrSwitch=dict()
57+
print(" - action_wrapperOrdre - - - Scenen ermitteln")
58+
myListSceneOrSwitch= getSceneNames(conf,myListSceneOrSwitch)
59+
print("Schalter ermitteln")
60+
myListSceneOrSwitch= getSwitchNames(conf,myListSceneOrSwitch)
61+
intentSwitchActionList=BuildActionSlotList(intentMessage)
62+
# print(" - action_wrapperOrdre intentSwitchActionList: "+intentSwitchActionList)
63+
actionText=""
64+
myAction = True
65+
for intentSwitchAction in intentSwitchActionList:
66+
#print("intentSwitchAction: "+intentSwitchAction)
67+
Match= ActionneEntity(intentSwitchAction["Name"],intentSwitchAction["State"],myListSceneOrSwitch,conf)
68+
#print("Match: "+Match)
69+
DomoticzRealName=Match[1]
70+
print("DomoticzRealName: "+DomoticzRealName)
71+
myAction=myAction and Match[0]
72+
if intentSwitchAction["State"]=="On":
73+
texte = u"Einschalten"
74+
else:
75+
texte = u"Ausschalten"
76+
# actionText=u'{}, {} {}'.format(actionText,texte,str(DomoticzRealName))
77+
if myAction and len(intentSwitchActionList)>0:
78+
hermes.publish_end_session(intentMessage.session_id, actionText)
79+
else:
80+
hermes.publish_end_session(intentMessage.session_id, u"Entschuldigung, ich habe es nicht verstanden.")
81+
82+
83+
def getSceneNames(conf,myListSceneOrSwitch):
84+
# response = urllib2.urlopen(global_conf.get("secret").get("hostname")+'/json?type=scenes')
85+
# jsonresponse = json.load(response)
86+
myURL="http://"+conf['secret'].get("username")+':'+conf.get('secret').get("passwd")+'@'+conf['secret'].get("hostname")+':'+conf.get('secret').get("port")+"/json.htm?type=scenes"
87+
response = requests.get(myURL)
88+
jsonresponse = response.json()
89+
#jsonresponse = json.load(response)
90+
for scene in jsonresponse["result"]:
91+
myName=scene["Name"].encode('utf-8')
92+
myListSceneOrSwitch[(scene["idx"])] = {'Type':'switchscene','Name':myName}
93+
print('---------SceneName----------')
94+
return myListSceneOrSwitch
95+
96+
97+
def getSwitchNames(conf,myListSceneOrSwitch):
98+
# response = urllib2.urlopen(global_conf("secret").get("hostname")+'/json?type=command&param=getlightswitches')
99+
# jsonresponse = json.load(response)
100+
myURL='http://'+conf['secret'].get("username")+':'+conf.get('secret').get("passwd")+'@'+conf['secret'].get("hostname")+':'+conf['secret'].get("port")+'/json.htm?type=command&param=getlightswitches'
101+
response = requests.get(myURL)
102+
jsonresponse = response.json()
103+
# json.load(response)
104+
for sw in jsonresponse["result"]:
105+
myName=sw["Name"].encode('utf-8')
106+
myListSceneOrSwitch[(sw["idx"])] = {'Type':'switchlight','Name':myName}
107+
print('---------SwitchName----------')
108+
return myListSceneOrSwitch
109+
110+
def BuildActionSlotList(intent):
111+
intentSwitchList=list()
112+
intentSwitchActionList=list()
113+
intentSwitchState='None' #by default if no action
114+
for (slot_value, slot) in intent.slots.items():
115+
print("Slot_value: "+slot_value)
116+
if slot_value=="action" or slot_value=="switch":
117+
for slot_value2 in slot.all():
118+
print("Slot_Value2: "+slot_value2.value)
119+
print("---------------------------------")
120+
for (slot_value, slot) in intent.slots.items():
121+
print('Slot {} -> Raw: {} Value: {}'.format(slot_value, slot[0].raw_value, slot[0].slot_value.value.value))
122+
# print('Slot {} -> Raw: {} Value: {}'.format(slot_value, slot[0].raw_value, slot[0].slot_value.value.value))
123+
print(" BuildActionSlotList - action: "+slot_value)
124+
print(" slot_value: "+slot_value)
125+
if slot_value=="switch":
126+
#NLU parsing does not preserve order of slot, thus it is impossible to have different action ON and OFF in the same intent=> keep only the first:
127+
print(" - BuildAcitionSlotList - slot[0].slot_value.value.value: "+slot[0].slot_value.value.value)
128+
if slot[0].slot_value.value.value=="TurnOn":
129+
intentSwitchState='On'
130+
print(" - Wenn TurnOn, dann: "+intentSwitchState)
131+
else :
132+
intentSwitchState='Off'
133+
print(" - ansonsten, dann: "+intentSwitchState)
134+
print(" - SchalterStatus: "+intentSwitchState)
135+
elif slot_value=="action":
136+
for slot_value2 in slot.all():
137+
intentSwitchList.append(slot_value2.value)
138+
print(" - Slotvalue: "+slot_value2.value)
139+
140+
# wenn intentSwitchState nicht 'None' enthält, dann mySwitch zusammenstellen
141+
if not intentSwitchState=='None':
142+
for mySwitch in intentSwitchList:
143+
intentSwitchActionList.append({'Name':mySwitch,'State':intentSwitchState})
144+
print(mySwitch+"------>"+intentSwitchState)
145+
return intentSwitchActionList
146+
147+
def curlCmd(idx,myCmd,myParam,conf):
148+
command_url="http://"+conf['secret'].get("username")+':'+conf.get('secret').get("passwd")+'@'+conf.get("secret").get("hostname")+':'+conf.get("secret").get("port")+'/json.htm?type=command&param='+myParam+'&idx='+str(idx)+'&switchcmd='+myCmd
149+
ignore_result = requests.get(command_url)
150+
151+
152+
def ActionneEntity(name,action,myListSceneOrSwitch,conf):
153+
#derived from nice work of https://github.com/iMartyn/domoticz-snips
154+
lowest_distance = MAX_JARO_DISTANCE
155+
lowest_idx = 65534
156+
lowest_name = "Unknown"
157+
MyWord=name
158+
DomoticzRealName=""
159+
print(" - ActionneEntity: "+MyWord)
160+
for idx,scene in myListSceneOrSwitch.items():
161+
print("Scene/Schalter: "+str(scene['Name'],'utf-8')+" idx: "+idx)
162+
distance = 1-jellyfish.jaro_distance(str(scene['Name'],'utf-8'), MyWord)
163+
print(" Distance is "+str(distance))
164+
if distance < lowest_distance:
165+
print(" Low enough and lowest!")
166+
lowest_distance = distance
167+
lowest_idx = idx
168+
lowest_name = scene['Name']
169+
lowest_Type= scene['Type']
170+
if lowest_distance < MAX_JARO_DISTANCE:
171+
print(" - ActionneEntity - lowest_Type: "+lowest_Type)
172+
DomoticzRealName=str(lowest_name,'utf-8')
173+
print(" - ActionneEntity - DomoticzRealName: "+DomoticzRealName)
174+
print(" - ActionneEntity - lowest_idx: "+lowest_idx)
175+
curlCmd(lowest_idx,action,lowest_Type,conf)
176+
return True,DomoticzRealName
177+
hermes.publish_end_session(intent_message.session_id, "Einschalten "+lowest_name)
178+
else:
179+
return False,DomoticzRealName
180+
181+
182+
def action_wrapperOrdreDirect(hermes, intentMessage, conf):
183+
myListSceneOrSwitch=dict()
184+
myListSceneOrSwitch= getSceneNames(conf,myListSceneOrSwitch)
185+
actionText = u"{}".format(str(intentMessage.slots.OrdreDivers.first().value))
186+
print("actionText "+actionText)
187+
DomoticzRealName=""
188+
MyAction=ActionneEntity(actionText,'On',myListSceneOrSwitch,conf)
189+
result_sentence = u"OK. Du hast {} angefordert.".format(str(MyAction[1])) # The response that will be said out loud by the TTS engine.
190+
if MyAction[0] :
191+
hermes.publish_end_session(intentMessage.session_id, result_sentence)
192+
else:
193+
print(" - action_wrapperOrdreDirect - keine Action:")
194+
hermes.publish_end_session(intentMessage.session_id, u"Entschuldigung, es ist etwas schief gegangen.")
195+
196+
197+
if __name__ == "__main__":
198+
mqtt_opts = MqttOptions()
199+
with Hermes(mqtt_options=mqtt_opts) as h:
200+
h.subscribe_intent("ryanrudak:switch", subscribe_intent_callback)\
201+
.subscribe_intent("ryanrudak:verschiedene", subscribe_intent_callback)\
202+
.start()

0 commit comments

Comments
 (0)