├── vocab ├── en-us │ ├── Dim.voc │ ├── Set.voc │ ├── Status.voc │ ├── item.entity │ ├── Humidity.voc │ ├── Increase.voc │ ├── Temperature.voc │ ├── Regulate.voc │ ├── WhatStatusKeyword.voc │ ├── DimmerStatusKeyword.voc │ ├── OnOffStatusKeyword.voc │ ├── ListItemsKeyword.voc │ ├── ThermostatStatusKeyword.voc │ ├── RefreshTaggedItemsKeyword.voc │ ├── requesttype.entity │ └── what.status.intent ├── es-es │ ├── Set.voc │ ├── Dim.voc │ ├── Status.voc │ ├── item.entity │ ├── Humidity.voc │ ├── Increase.voc │ ├── Temperature.voc │ ├── Regulate.voc │ ├── WhatStatusKeyword.voc │ ├── OnOffStatusKeyword.voc │ ├── DimmerStatusKeyword.voc │ ├── requesttype.entity │ ├── ThermostatStatusKeyword.voc │ ├── ListItemsKeyword.voc │ ├── RefreshTaggedItemsKeyword.voc │ └── what.status.intent ├── de-de │ ├── Dim.voc │ ├── Set.voc │ ├── Status.voc │ ├── item.entity │ ├── Increase.voc │ ├── Humidity.voc │ ├── Temperature.voc │ ├── Regulate.voc │ ├── WhatStatusKeyword.voc │ ├── DimmerStatusKeyword.voc │ ├── OnOffStatusKeyword.voc │ ├── ListItemsKeyword.voc │ ├── ThermostatStatusKeyword.voc │ ├── RefreshTaggedItemsKeyword.voc │ ├── requesttype.entity │ └── what.status.intent └── it-it │ ├── Dim.voc │ ├── Set.voc │ ├── item.entity │ ├── Humidity.voc │ ├── Status.voc │ ├── Increase.voc │ ├── Temperature.voc │ ├── Regulate.voc │ ├── DimmerStatusKeyword.voc │ ├── OnOffStatusKeyword.voc │ ├── WhatStatusKeyword.voc │ ├── ListItemsKeyword.voc │ ├── ThermostatStatusKeyword.voc │ ├── requesttype.entity │ ├── RefreshTaggedItemsKeyword.voc │ └── what.status.intent ├── dialog ├── de-de │ ├── Degree.dialog │ ├── Status.dialog │ ├── Humidity.dialog │ ├── Percentage.dialog │ ├── Temperature.dialog │ ├── FoundItems.dialog │ ├── StatusDimmer.dialog │ ├── RefreshTaggedItems.dialog │ ├── CommunicationError.dialog │ ├── ItemNotFoundError.dialog │ ├── GetItemsListError.dialog │ ├── ErrorDialog.dialog │ ├── TempHumStatus.dialog │ ├── StatusOnOff.dialog │ ├── ConfigurationNeeded.dialog │ └── ThermostatStatus.dialog ├── en-us │ ├── Degree.dialog │ ├── Status.dialog │ ├── Humidity.dialog │ ├── Percentage.dialog │ ├── Temperature.dialog │ ├── StatusDimmer.dialog │ ├── FoundItems.dialog │ ├── GetItemsListError.dialog │ ├── ItemNotFoundError.dialog │ ├── CommunicationError.dialog │ ├── RefreshTaggedItems.dialog │ ├── ErrorDialog.dialog │ ├── TempHumStatus.dialog │ ├── StatusOnOff.dialog │ ├── ConfigurationNeeded.dialog │ └── ThermostatStatus.dialog ├── es-es │ ├── Degree.dialog │ ├── Status.voc │ ├── Humidity.dialog │ ├── Percentage.dialog │ ├── Temperature.dialog │ ├── StatusDimmer.dialog │ ├── FoundItems.dialog │ ├── ErrorDialog.dialog │ ├── ItemNotFoundError.dialog │ ├── CommunicationError.dialog │ ├── GetItemsListError.dialog │ ├── RefreshTaggedItems.dialog │ ├── TempHumStatus.dialog │ ├── StatusOnOff.dialog │ ├── ConfigurationNeeded.dialog │ └── ThermostatStatus.dialog └── it-it │ ├── Degree.dialog │ ├── Status.dialog │ ├── Humidity.dialog │ ├── Percentage.dialog │ ├── Temperature.dialog │ ├── StatusDimmer.dialog │ ├── FoundItems.dialog │ ├── RefreshTaggedItems.dialog │ ├── ErrorDialog.dialog │ ├── CommunicationError.dialog │ ├── ItemNotFoundError.dialog │ ├── GetItemsListError.dialog │ ├── StatusOnOff.dialog │ ├── TempHumStatus.dialog │ ├── ConfigurationNeeded.dialog │ └── ThermostatStatus.dialog ├── .gitignore ├── requirements.txt ├── regex ├── es-es │ ├── onoff_command.rx │ ├── what_status.rx │ ├── set_temp_status.rx │ └── dimmer_command.rx ├── de-de │ ├── onoff_command.rx │ ├── what_status.rx │ ├── set_temp_status.rx │ └── dimmer_command.rx ├── it-it │ ├── onoff_command.rx │ ├── what_status.rx │ ├── set_temp_status.rx │ └── dimmer_command.rx └── en-us │ ├── onoff_command.rx │ ├── what_status.rx │ ├── set_temp_status.rx │ └── dimmer_command.rx ├── test └── intent │ └── RefreshItems.intent.json ├── crowdin.yml ├── settingsmeta.yaml ├── NOTICE ├── README.md ├── CONTRIBUTING.md ├── USAGE.md ├── LICENSE └── __init__.py /vocab/en-us/Dim.voc: -------------------------------------------------------------------------------- 1 | dim -------------------------------------------------------------------------------- /vocab/en-us/Set.voc: -------------------------------------------------------------------------------- 1 | set -------------------------------------------------------------------------------- /vocab/es-es/Set.voc: -------------------------------------------------------------------------------- 1 | pone -------------------------------------------------------------------------------- /vocab/de-de/Dim.voc: -------------------------------------------------------------------------------- 1 | dimme -------------------------------------------------------------------------------- /vocab/de-de/Set.voc: -------------------------------------------------------------------------------- 1 | setze -------------------------------------------------------------------------------- /vocab/de-de/Status.voc: -------------------------------------------------------------------------------- 1 | Status -------------------------------------------------------------------------------- /vocab/de-de/item.entity: -------------------------------------------------------------------------------- 1 | :0 -------------------------------------------------------------------------------- /vocab/en-us/Status.voc: -------------------------------------------------------------------------------- 1 | status -------------------------------------------------------------------------------- /vocab/en-us/item.entity: -------------------------------------------------------------------------------- 1 | :0 -------------------------------------------------------------------------------- /vocab/es-es/Dim.voc: -------------------------------------------------------------------------------- 1 | oscurece -------------------------------------------------------------------------------- /vocab/es-es/Status.voc: -------------------------------------------------------------------------------- 1 | estado -------------------------------------------------------------------------------- /vocab/es-es/item.entity: -------------------------------------------------------------------------------- 1 | :0 -------------------------------------------------------------------------------- /vocab/it-it/Dim.voc: -------------------------------------------------------------------------------- 1 | abbassa -------------------------------------------------------------------------------- /vocab/it-it/Set.voc: -------------------------------------------------------------------------------- 1 | imposta -------------------------------------------------------------------------------- /vocab/it-it/item.entity: -------------------------------------------------------------------------------- 1 | :0 -------------------------------------------------------------------------------- /dialog/de-de/Degree.dialog: -------------------------------------------------------------------------------- 1 | Grad -------------------------------------------------------------------------------- /dialog/de-de/Status.dialog: -------------------------------------------------------------------------------- 1 | Status -------------------------------------------------------------------------------- /dialog/en-us/Degree.dialog: -------------------------------------------------------------------------------- 1 | degree -------------------------------------------------------------------------------- /dialog/en-us/Status.dialog: -------------------------------------------------------------------------------- 1 | status -------------------------------------------------------------------------------- /dialog/es-es/Degree.dialog: -------------------------------------------------------------------------------- 1 | grados -------------------------------------------------------------------------------- /dialog/es-es/Status.voc: -------------------------------------------------------------------------------- 1 | estado -------------------------------------------------------------------------------- /dialog/it-it/Degree.dialog: -------------------------------------------------------------------------------- 1 | gradi -------------------------------------------------------------------------------- /dialog/it-it/Status.dialog: -------------------------------------------------------------------------------- 1 | stato -------------------------------------------------------------------------------- /vocab/de-de/Increase.voc: -------------------------------------------------------------------------------- 1 | erhöhe -------------------------------------------------------------------------------- /vocab/en-us/Humidity.voc: -------------------------------------------------------------------------------- 1 | humidity -------------------------------------------------------------------------------- /vocab/en-us/Increase.voc: -------------------------------------------------------------------------------- 1 | increase -------------------------------------------------------------------------------- /vocab/es-es/Humidity.voc: -------------------------------------------------------------------------------- 1 | humedad -------------------------------------------------------------------------------- /vocab/es-es/Increase.voc: -------------------------------------------------------------------------------- 1 | aumenta -------------------------------------------------------------------------------- /vocab/it-it/Humidity.voc: -------------------------------------------------------------------------------- 1 | l'umidità -------------------------------------------------------------------------------- /vocab/it-it/Status.voc: -------------------------------------------------------------------------------- 1 | lo stato -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | settings.json 3 | -------------------------------------------------------------------------------- /dialog/en-us/Humidity.dialog: -------------------------------------------------------------------------------- 1 | humidity -------------------------------------------------------------------------------- /dialog/es-es/Humidity.dialog: -------------------------------------------------------------------------------- 1 | humedad -------------------------------------------------------------------------------- /dialog/it-it/Humidity.dialog: -------------------------------------------------------------------------------- 1 | umidità -------------------------------------------------------------------------------- /dialog/it-it/Percentage.dialog: -------------------------------------------------------------------------------- 1 | percento -------------------------------------------------------------------------------- /vocab/de-de/Humidity.voc: -------------------------------------------------------------------------------- 1 | Feuchtigkeit -------------------------------------------------------------------------------- /vocab/de-de/Temperature.voc: -------------------------------------------------------------------------------- 1 | temperatur -------------------------------------------------------------------------------- /vocab/en-us/Temperature.voc: -------------------------------------------------------------------------------- 1 | temperature -------------------------------------------------------------------------------- /vocab/es-es/Temperature.voc: -------------------------------------------------------------------------------- 1 | temperatura -------------------------------------------------------------------------------- /vocab/it-it/Increase.voc: -------------------------------------------------------------------------------- 1 | incrementa -------------------------------------------------------------------------------- /dialog/de-de/Humidity.dialog: -------------------------------------------------------------------------------- 1 | Feuchtigkeit -------------------------------------------------------------------------------- /dialog/de-de/Percentage.dialog: -------------------------------------------------------------------------------- 1 | Prozentsatz -------------------------------------------------------------------------------- /dialog/de-de/Temperature.dialog: -------------------------------------------------------------------------------- 1 | temperatur -------------------------------------------------------------------------------- /dialog/en-us/Percentage.dialog: -------------------------------------------------------------------------------- 1 | percentage -------------------------------------------------------------------------------- /dialog/en-us/Temperature.dialog: -------------------------------------------------------------------------------- 1 | temperature -------------------------------------------------------------------------------- /dialog/es-es/Percentage.dialog: -------------------------------------------------------------------------------- 1 | porciento -------------------------------------------------------------------------------- /dialog/es-es/Temperature.dialog: -------------------------------------------------------------------------------- 1 | temperatura -------------------------------------------------------------------------------- /dialog/it-it/Temperature.dialog: -------------------------------------------------------------------------------- 1 | temperatura -------------------------------------------------------------------------------- /vocab/it-it/Temperature.voc: -------------------------------------------------------------------------------- 1 | la temperatura -------------------------------------------------------------------------------- /vocab/de-de/Regulate.voc: -------------------------------------------------------------------------------- 1 | reguliere 2 | stell 3 | pass -------------------------------------------------------------------------------- /vocab/en-us/Regulate.voc: -------------------------------------------------------------------------------- 1 | regulate 2 | adjust 3 | tune -------------------------------------------------------------------------------- /vocab/en-us/WhatStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | what is 2 | what's -------------------------------------------------------------------------------- /vocab/es-es/Regulate.voc: -------------------------------------------------------------------------------- 1 | regula 2 | ajusta 3 | afina -------------------------------------------------------------------------------- /vocab/it-it/Regulate.voc: -------------------------------------------------------------------------------- 1 | regola 2 | aggiusta 3 | metti -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests>=2.10.0 2 | rapidfuzz==0.7.6 -------------------------------------------------------------------------------- /vocab/de-de/WhatStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | was ist 2 | was ist 3 | -------------------------------------------------------------------------------- /vocab/es-es/WhatStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | qué es 2 | qué es 3 | -------------------------------------------------------------------------------- /dialog/en-us/StatusDimmer.dialog: -------------------------------------------------------------------------------- 1 | bright changed for {{item}} -------------------------------------------------------------------------------- /vocab/en-us/DimmerStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | set 2 | dim 3 | bright -------------------------------------------------------------------------------- /vocab/en-us/OnOffStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | turn 2 | switch 3 | put -------------------------------------------------------------------------------- /vocab/it-it/DimmerStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | imposta 2 | abbassa 3 | alza -------------------------------------------------------------------------------- /vocab/it-it/OnOffStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | imposta 2 | accendi 3 | metti -------------------------------------------------------------------------------- /vocab/it-it/WhatStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | quale è|qual'è|com'è|come è -------------------------------------------------------------------------------- /dialog/es-es/StatusDimmer.dialog: -------------------------------------------------------------------------------- 1 | brillo de {{item}} cambiado 2 | -------------------------------------------------------------------------------- /dialog/it-it/StatusDimmer.dialog: -------------------------------------------------------------------------------- 1 | intensità cambiata per {{item}} 2 | -------------------------------------------------------------------------------- /vocab/de-de/DimmerStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | setze 2 | dimme 3 | erhelle 4 | -------------------------------------------------------------------------------- /vocab/de-de/OnOffStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | schalte 2 | schalte 3 | mach 4 | -------------------------------------------------------------------------------- /vocab/es-es/OnOffStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | conmuta 2 | conmuta 3 | pon 4 | -------------------------------------------------------------------------------- /dialog/de-de/FoundItems.dialog: -------------------------------------------------------------------------------- 1 | Folgende Elemente gefunden: {{items}} 2 | -------------------------------------------------------------------------------- /dialog/de-de/StatusDimmer.dialog: -------------------------------------------------------------------------------- 1 | Helligkeit für {{item}} geändert 2 | -------------------------------------------------------------------------------- /dialog/en-us/FoundItems.dialog: -------------------------------------------------------------------------------- 1 | Found the following items: {{items}} 2 | -------------------------------------------------------------------------------- /dialog/en-us/GetItemsListError.dialog: -------------------------------------------------------------------------------- 1 | Sorry cannot get the items list. -------------------------------------------------------------------------------- /dialog/en-us/ItemNotFoundError.dialog: -------------------------------------------------------------------------------- 1 | Sorry. Item not found in open hab. -------------------------------------------------------------------------------- /dialog/it-it/FoundItems.dialog: -------------------------------------------------------------------------------- 1 | Ho trovato le seguenti cose: {{items}} 2 | -------------------------------------------------------------------------------- /regex/es-es/onoff_command.rx: -------------------------------------------------------------------------------- 1 | (?Penciende|apaga) (?P.*) 2 | -------------------------------------------------------------------------------- /vocab/es-es/DimmerStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | establece 2 | oscuro 3 | brillante 4 | -------------------------------------------------------------------------------- /dialog/en-us/CommunicationError.dialog: -------------------------------------------------------------------------------- 1 | Sorry. Some problems with the command. 2 | -------------------------------------------------------------------------------- /dialog/en-us/RefreshTaggedItems.dialog: -------------------------------------------------------------------------------- 1 | All right. I found {{number_item}} items. -------------------------------------------------------------------------------- /dialog/es-es/FoundItems.dialog: -------------------------------------------------------------------------------- 1 | Encontré los siguientes elementos: {{items}} 2 | -------------------------------------------------------------------------------- /dialog/it-it/RefreshTaggedItems.dialog: -------------------------------------------------------------------------------- 1 | OK, ho trovato {{number_item}} oggetti. 2 | -------------------------------------------------------------------------------- /vocab/en-us/ListItemsKeyword.voc: -------------------------------------------------------------------------------- 1 | list open hab items 2 | list openhab items 3 | -------------------------------------------------------------------------------- /vocab/en-us/ThermostatStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | regulate|adjust|tune 2 | increase|decrease -------------------------------------------------------------------------------- /vocab/es-es/requesttype.entity: -------------------------------------------------------------------------------- 1 | estado 2 | temperatura 3 | humedad 4 | ajustes 5 | -------------------------------------------------------------------------------- /dialog/de-de/RefreshTaggedItems.dialog: -------------------------------------------------------------------------------- 1 | In Ordnung. Ich fand {{number_item}} Items. 2 | -------------------------------------------------------------------------------- /dialog/es-es/ErrorDialog.dialog: -------------------------------------------------------------------------------- 1 | No sé qué hacer 2 | No entiendo 3 | Estoy perdido 4 | -------------------------------------------------------------------------------- /dialog/es-es/ItemNotFoundError.dialog: -------------------------------------------------------------------------------- 1 | Lo siento. Ítem no encontrado en open hab. 2 | -------------------------------------------------------------------------------- /dialog/it-it/ErrorDialog.dialog: -------------------------------------------------------------------------------- 1 | Non so cosa fare 2 | Non capisco 3 | Mi sono perso 4 | -------------------------------------------------------------------------------- /regex/de-de/onoff_command.rx: -------------------------------------------------------------------------------- 1 | (schalte|mache|tue) (?Pon|off) (?P.*) 2 | -------------------------------------------------------------------------------- /vocab/es-es/ThermostatStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | regula|ajusta|afina 2 | aumenta|disminuye 3 | -------------------------------------------------------------------------------- /vocab/it-it/ListItemsKeyword.voc: -------------------------------------------------------------------------------- 1 | elenca elementi openhab 2 | elenca elementi open hab -------------------------------------------------------------------------------- /vocab/it-it/ThermostatStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | regola|aggiusta|metti 2 | incrementa|decrementa -------------------------------------------------------------------------------- /dialog/de-de/CommunicationError.dialog: -------------------------------------------------------------------------------- 1 | Entschuldigung. Es gibt Probleme mit dem Befehl. 2 | -------------------------------------------------------------------------------- /dialog/de-de/ItemNotFoundError.dialog: -------------------------------------------------------------------------------- 1 | Entschuldigung. Element in Openhab nicht gefunden. 2 | -------------------------------------------------------------------------------- /dialog/en-us/ErrorDialog.dialog: -------------------------------------------------------------------------------- 1 | I don't know what to do 2 | I don't understand 3 | I'm lost -------------------------------------------------------------------------------- /dialog/es-es/CommunicationError.dialog: -------------------------------------------------------------------------------- 1 | Lo siento. Hay algunos problemas con el comando. 2 | -------------------------------------------------------------------------------- /dialog/es-es/GetItemsListError.dialog: -------------------------------------------------------------------------------- 1 | Lo sientos, no puedo obtener la lista de artículos. 2 | -------------------------------------------------------------------------------- /dialog/it-it/CommunicationError.dialog: -------------------------------------------------------------------------------- 1 | Mi spiace, ho qualche problema con il comando. 2 | -------------------------------------------------------------------------------- /dialog/it-it/ItemNotFoundError.dialog: -------------------------------------------------------------------------------- 1 | Mi spiace, non ho trovato l'oggetto in open hab. 2 | -------------------------------------------------------------------------------- /regex/it-it/onoff_command.rx: -------------------------------------------------------------------------------- 1 | (imposta|accendi|metti) (?P su on|off) (?P.*) 2 | -------------------------------------------------------------------------------- /dialog/es-es/RefreshTaggedItems.dialog: -------------------------------------------------------------------------------- 1 | De acuerdo. He encontrado {{number_item}} elementos. 2 | -------------------------------------------------------------------------------- /vocab/de-de/ListItemsKeyword.voc: -------------------------------------------------------------------------------- 1 | liste Openhab Elemente auf 2 | liste Openhab Elemente auf 3 | -------------------------------------------------------------------------------- /vocab/de-de/ThermostatStatusKeyword.voc: -------------------------------------------------------------------------------- 1 | (reguliere|stell|passe) (|ein|an) 2 | erhöhe|reduziere 3 | -------------------------------------------------------------------------------- /vocab/en-us/RefreshTaggedItemsKeyword.voc: -------------------------------------------------------------------------------- 1 | refresh open hab items 2 | refresh openhab items 3 | -------------------------------------------------------------------------------- /dialog/de-de/GetItemsListError.dialog: -------------------------------------------------------------------------------- 1 | Entschuldigung, ich kann die Element-Liste nicht bekommen. 2 | -------------------------------------------------------------------------------- /dialog/en-us/TempHumStatus.dialog: -------------------------------------------------------------------------------- 1 | the {{item}} {{temp_hum}} is {{temp_hum_val}} {{units_of_measurement}} -------------------------------------------------------------------------------- /dialog/it-it/GetItemsListError.dialog: -------------------------------------------------------------------------------- 1 | Mi spiace, non posso ottenere la lista delle cose open hab. 2 | -------------------------------------------------------------------------------- /vocab/es-es/ListItemsKeyword.voc: -------------------------------------------------------------------------------- 1 | lista de elementos de open hab 2 | lista elementos de openhab 3 | -------------------------------------------------------------------------------- /dialog/it-it/StatusOnOff.dialog: -------------------------------------------------------------------------------- 1 | messo {{command}} per {{item}} 2 | impostato {{command}} per {{item}} 3 | -------------------------------------------------------------------------------- /vocab/it-it/requesttype.entity: -------------------------------------------------------------------------------- 1 | lo stato 2 | la temperatura 3 | l'umidità 4 | messo 5 | regolato 6 | impostato -------------------------------------------------------------------------------- /dialog/es-es/TempHumStatus.dialog: -------------------------------------------------------------------------------- 1 | la {{temp_hum}} de {{item}} es {{temp_hum_val}} {{units_of_measurement}} 2 | -------------------------------------------------------------------------------- /dialog/it-it/TempHumStatus.dialog: -------------------------------------------------------------------------------- 1 | la {{temp_hum}} di {{item}} è {{temp_hum_val}} {{units_of_measurement}} 2 | -------------------------------------------------------------------------------- /vocab/de-de/RefreshTaggedItemsKeyword.voc: -------------------------------------------------------------------------------- 1 | Aktualisiere Openhab Elemente 2 | Aktualisiere Openhab Elemente 3 | -------------------------------------------------------------------------------- /vocab/en-us/requesttype.entity: -------------------------------------------------------------------------------- 1 | status 2 | temperature 3 | humidity 4 | adjusted to 5 | regulated to 6 | tuned to -------------------------------------------------------------------------------- /vocab/es-es/RefreshTaggedItemsKeyword.voc: -------------------------------------------------------------------------------- 1 | refresca elementos de open hab 2 | refresca elementos de openhab 3 | -------------------------------------------------------------------------------- /dialog/es-es/StatusOnOff.dialog: -------------------------------------------------------------------------------- 1 | pon {{command}} {{item}} 2 | conmuta {{command}} {{item}} 3 | {{command}} {{item}} 4 | -------------------------------------------------------------------------------- /vocab/de-de/requesttype.entity: -------------------------------------------------------------------------------- 1 | Status 2 | Temperatur 3 | Feuchtigkeit 4 | eingestellt 5 | reguliert 6 | angepasst 7 | -------------------------------------------------------------------------------- /dialog/de-de/ErrorDialog.dialog: -------------------------------------------------------------------------------- 1 | Ich weiß nicht, was ich tun soll 2 | Ich verstehe nicht 3 | Ich weiß nicht mehr weiter 4 | -------------------------------------------------------------------------------- /dialog/de-de/TempHumStatus.dialog: -------------------------------------------------------------------------------- 1 | (der|die|das) {{item}} {{temp_hum}} ist {{temp_hum_val}} {{units_of_measurement}} 2 | -------------------------------------------------------------------------------- /dialog/en-us/StatusOnOff.dialog: -------------------------------------------------------------------------------- 1 | put {{command}} {{item}} 2 | switch {{command}} {{item}} 3 | turn {{command}} {{item}} -------------------------------------------------------------------------------- /regex/es-es/what_status.rx: -------------------------------------------------------------------------------- 1 | el elemento (?P.*) (qué|cuál) (?Pestado|temperatura|humedad|ajustes) tiene 2 | -------------------------------------------------------------------------------- /dialog/de-de/StatusOnOff.dialog: -------------------------------------------------------------------------------- 1 | schalte {{item}} {{command}} 2 | schalte {{item}} {{command}} 3 | schalte {{item}} {{command}} 4 | -------------------------------------------------------------------------------- /dialog/en-us/ConfigurationNeeded.dialog: -------------------------------------------------------------------------------- 1 | Please add your open hab server details in the Skill settings at home dot mycroft dot AI 2 | -------------------------------------------------------------------------------- /regex/en-us/onoff_command.rx: -------------------------------------------------------------------------------- 1 | (turn|switch|put) (?Pon|off) (?P.*) 2 | (turn|switch|put) (?P.*) (?Pon|off) 3 | -------------------------------------------------------------------------------- /regex/en-us/what_status.rx: -------------------------------------------------------------------------------- 1 | (what is|what's) (?P.*) (?Pstatus|temperature|humidity|adjusted to|regulated to|tuned to) -------------------------------------------------------------------------------- /dialog/de-de/ConfigurationNeeded.dialog: -------------------------------------------------------------------------------- 1 | Fügen Sie Ihre Open Hab Systemkonfiguration auf der Konfigurationsseite hinzu home Punkt mycroft Punkt AI -------------------------------------------------------------------------------- /dialog/es-es/ConfigurationNeeded.dialog: -------------------------------------------------------------------------------- 1 | agregue la configuración de su sistema open hab en la página de configuración a home punto mycroft punto AI -------------------------------------------------------------------------------- /dialog/it-it/ConfigurationNeeded.dialog: -------------------------------------------------------------------------------- 1 | aggiungi la configurazione del tuo server open hab nella pagina impostazioni su home punto mycroft punto AI -------------------------------------------------------------------------------- /regex/it-it/what_status.rx: -------------------------------------------------------------------------------- 1 | (quale è|qual'è|com'è|come è) (?P lo stato|la temperatura|l'umidità|messo|regolato|affinato) (?P.*) 2 | -------------------------------------------------------------------------------- /regex/de-de/what_status.rx: -------------------------------------------------------------------------------- 1 | (was ist|wie ist|worauf ist) (der|die|) (?P.*) (?PStatus|Temperatur|Feuchtigkeit|eingestellt|reguliert|angepasst) 2 | -------------------------------------------------------------------------------- /dialog/es-es/ThermostatStatus.dialog: -------------------------------------------------------------------------------- 1 | {{item}} regulado a {{temp_val}} grados 2 | {{item}} ajustado a {{temp_val}} grados 3 | {{item}} afinado a {{temp_val}} gradps 4 | -------------------------------------------------------------------------------- /dialog/de-de/ThermostatStatus.dialog: -------------------------------------------------------------------------------- 1 | {{item}} auf {{temp_val}} Grad reguliert 2 | {{item}} auf {{temp_val}} Grad eingestellt 3 | {{item}} auf {{temp_val}} Grad angepasst 4 | -------------------------------------------------------------------------------- /dialog/en-us/ThermostatStatus.dialog: -------------------------------------------------------------------------------- 1 | regulated {{item}} to {{temp_val}} degrees 2 | adjusted {{item}} to {{temp_val}} degrees 3 | tuned {{item}} to {{temp_val}} degrees -------------------------------------------------------------------------------- /dialog/it-it/ThermostatStatus.dialog: -------------------------------------------------------------------------------- 1 | regolato {{item}} su {{temp_val}} gradi 2 | aggiustato {{item}} su {{temp_val}} gradi 3 | impostato {{item}} su {{temp_val}} gradi 4 | -------------------------------------------------------------------------------- /regex/en-us/set_temp_status.rx: -------------------------------------------------------------------------------- 1 | (regulate|adjust|tune) (?P.*) (to) (?P\d*) (degrees) 2 | (increase|decrease) (?P.*) (by) (?P\d*) (degrees) -------------------------------------------------------------------------------- /regex/es-es/set_temp_status.rx: -------------------------------------------------------------------------------- 1 | (regula|ajusta|afina) (?P.*) (a) (?P\d*) (grados) 2 | (aumenta|disminuye) (?P.*) (en) (?P\d*) (grados) 3 | -------------------------------------------------------------------------------- /vocab/it-it/RefreshTaggedItemsKeyword.voc: -------------------------------------------------------------------------------- 1 | aggiorna elementi openhab 2 | aggiorna elementi open hab 3 | aggiorna gli elementi di openhab 4 | aggiorna gli elementi di open hab -------------------------------------------------------------------------------- /regex/de-de/set_temp_status.rx: -------------------------------------------------------------------------------- 1 | (reguliere|stell|pass) (?P.*) (auf) (?P\d*) (Grad) (an|) 2 | (erhöhe|reduziere) (?P.*) (um) (?P\d*) (Grad) 3 | -------------------------------------------------------------------------------- /regex/it-it/set_temp_status.rx: -------------------------------------------------------------------------------- 1 | (regola|aggiusta|metti) (?P.*) (a) (?P\d*) (gradi) 2 | (incrementa|decrementa) (?P.*) (di) (?P\d*) (gradi) 3 | -------------------------------------------------------------------------------- /regex/en-us/dimmer_command.rx: -------------------------------------------------------------------------------- 1 | (set) (?P.*)(?: to )?(?P\d+)(?: percent)? 2 | (dim|bright) (?P.*?)(?: by )?(?P\d*)?(?: percent)?$ 3 | -------------------------------------------------------------------------------- /regex/de-de/dimmer_command.rx: -------------------------------------------------------------------------------- 1 | (setz) (?P.*)(?: auf )?(?P\d+)(?: Prozent)? 2 | (dimme|erhelle) (?P.*?)\s*(?: um )?(?P\d*)?(?: Prozent)?$ 3 | -------------------------------------------------------------------------------- /test/intent/RefreshItems.intent.json: -------------------------------------------------------------------------------- 1 | { 2 | "utterance": "refresh openhab items", 3 | "intent_type": "RefreshTaggedItemsIntent", 4 | "expected_dialog": "ConfigurationNeeded" 5 | } 6 | -------------------------------------------------------------------------------- /regex/es-es/dimmer_command.rx: -------------------------------------------------------------------------------- 1 | (pone) (?P.*)(?: al )?(?P\d+)(?: porciento)? 2 | (oscurece|ilumina) (?P.*?)\s*(?: al )?(?P\d*)?(?: porciento)?$ 3 | -------------------------------------------------------------------------------- /regex/it-it/dimmer_command.rx: -------------------------------------------------------------------------------- 1 | (imposta) (?P.*)(?: al )?(?P\d+)(?: percento)? 2 | (abbassa|alza) (?P.*?)\s*(?: del )?(?P\d*)?(?: percento)?$ 3 | -------------------------------------------------------------------------------- /crowdin.yml: -------------------------------------------------------------------------------- 1 | files: 2 | - source: /dialog/en-us/*.* 3 | translation: /dialog/%locale% 4 | - source: /regex/en-us/*.* 5 | translation: /regex/%locale% 6 | - source: /vocab/en-us 7 | translation: /vocab/%locale% 8 | -------------------------------------------------------------------------------- /vocab/es-es/what.status.intent: -------------------------------------------------------------------------------- 1 | (el elemento|) {item} (qué|cuál) {requesttype} tiene 2 | Quiero saber (qué|cuál|cómo|) (el elemento|) {item} {requesttype} tiene 3 | dime (qué|cuál|cómo|) (el elemento|) {item} {requesttype} (tiene|) -------------------------------------------------------------------------------- /vocab/it-it/what.status.intent: -------------------------------------------------------------------------------- 1 | (quale è|qual'è|com'è|come è) (la|lo|l'|) {requesttype} {item} 2 | vorrei sapere (quale è|qual'è|com'è|come è|) (la|lo|l'|) {requesttype} {item} 3 | dimmmi (quale è|qual'è|com'è|come è|) (la|lo|l'|) {requesttype} {item} -------------------------------------------------------------------------------- /settingsmeta.yaml: -------------------------------------------------------------------------------- 1 | skillMetadata: 2 | sections: 3 | - name: Connection 4 | fields: 5 | - name: host 6 | label: openHAB server IP 7 | type: text 8 | value: 127.0.0.1 9 | - name: port 10 | label: openHAB server port 11 | type: number 12 | value: 8080 13 | -------------------------------------------------------------------------------- /vocab/en-us/what.status.intent: -------------------------------------------------------------------------------- 1 | (what's|what is) the {item} {requesttype} 2 | (what's|what is) the {requesttype} of {item} 3 | how the {item} is {requesttype} 4 | tell me the {item} {requesttype} 5 | tell me the {requesttype} of {item} 6 | tell me how the {item} is {requesttype} 7 | I'd like to know the {item} {requesttype} 8 | I'd like to know the {requesttype} of {item} 9 | I'd like to know how the {item} is {requesttype} -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | This content is produced and maintained by the openHAB project. 2 | 3 | * Project home: https://www.openhab.org 4 | 5 | == Declared Project Licenses 6 | 7 | This program and the accompanying materials are made available under the terms 8 | of the Eclipse Public License 2.0 which is available at 9 | https://www.eclipse.org/legal/epl-2.0/. 10 | 11 | == Source Code 12 | 13 | https://github.com/openhab/openhab-mycroft 14 | 15 | -------------------------------------------------------------------------------- /vocab/de-de/what.status.intent: -------------------------------------------------------------------------------- 1 | (was ist|wie ist|worauf ist) (der|die) {item} {requesttype} 2 | (was ist|wie ist|worauf ist) (der|die) {requesttype} des {item} 3 | Sag mir (der|die) {item} {requesttype} 4 | Sag mir (der|die) {requesttype} des {item} 5 | Sag mir wie ist (der|die) {item} {requesttype} 6 | Ich möchte wissen (der|die) {item} {requesttype} 7 | Ich möchte wissen (der|die) {requesttype} des {item} 8 | Ich möchte wissen wie ist (der|die) {item} {requesttype} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # openHAB 2 | This skill adds openHAB support to Mycroft. 3 | 4 | ## About 5 | This skill adds [openHAB](http://www.openhab.org/) support to [Mycroft](https://mycroft.ai). 6 | The skill takes advantage of the openHAB REST API, so it works both with the v1.x and v2.x of openHAB. 7 | 8 | In order to make openHAB Items accessible to Mycroft, they need to be [tagged](https://www.openhab.org/addons/integrations/homekit/). 9 | Device names recognized by Mycroft are matched against openHAB Item Labels. 10 | 11 | The above examples would all work with the following set of openHAB Item definitons: 12 | 13 | ```java 14 | Color DiningroomLight "Diningroom Light" (gKitchen) [ "Lighting" ] {channel="hue:0200:1:bloom1:color"} 15 | Color KitchenLight "Kitchen Light" (gKitchen) [ "Lighting" ] {channel="hue:0200:1:bloom1:color"} 16 | Switch GoodNight "Good Night" [ "Switchable" ] 17 | 18 | Number MqttID1Temperature "Bedroom Temperature" [ "CurrentTemperature" ] {mqtt="<[mosquitto:mysensors/SI/1/1/1/0/0:state:default]"} 19 | Number MqttID1Humidity "Bedroom Humidity" [ "CurrentHumidity" ] {mqtt="<[mosquitto:mysensors/SI/1/0/1/0/1:state:default]"} 20 | 21 | Group gThermostat "Main Thermostat" [ "gMainThermostat" ] 22 | Number MainThermostatCurrentTemp "Main Thermostat Current Temperature" (gMainThermostat) [ "CurrentTemperature" ] 23 | Number MainThermostatTargetTemperature "Main Thermostat Target Temperature" (gMainThermostat) [ "TargetTemperature" ] 24 | String MainThermostatHeatingCoolingMode "Main Thermostat Heating/Cooling Mode" (gMainThermostat) [ "homekit:HeatingCoolingMode" ] 25 | ``` 26 | 27 | If items are modified in openHAB, a refresh in Mycroft is needed by the command: 28 | 29 | - *"Hey Mycroft, refresh openhab items"* 30 | 31 | If you've forgotten what items have been identified, you can ask Mycroft: 32 | - *"Hey Mycroft, list openhab items"* 33 | 34 | ## Versions Change Log 35 | * 1.5 addedd support to core v19 36 | * 1.4 added spanish translation 37 | * 1.3 added german translation 38 | * 1.2 addedd python 3 support 39 | * 1.1 added status request to Switchable items 40 | * 1.0 added support to item tagged as Thermostat, CurrentTemperature, CurrentHumidity 41 | * 0.9 added dimming command to item tagged as Lighting 42 | * 0.8 supports only Lighting and Switchable tags, commands ON and OFF 43 | 44 | ## Installation 45 | 46 | From 18.2.5b mycroft-core release it is possible to install the skill using the voice command: 47 | - *"Hey Mycroft, install openhab"* 48 | 49 | or via the [msm](https://mycroft.ai/documentation/msm/) command: 50 | ```shell 51 | msm install openhab 52 | ``` 53 | 54 | To manually install the skill: 55 | Clone this repository into your `~/.mycroft/skills` directory. 56 | Then install the dependencies inside your mycroft virtual environment: 57 | 58 | If on picroft just skip the workon part and the directory will be `/opt/mycroft/skills` 59 | 60 | ```shell 61 | cd ~/.mycroft/skills 62 | git clone https://github.com/openhab/openhab-mycroft.git skill-openhab 63 | workon mycroft 64 | cd skill-openhab 65 | pip install -r requirements.txt 66 | ``` 67 | 68 | ## Examples 69 | * "Hey Mycroft, turn on Diningroom Light" 70 | * "Hey Mycroft, switch off Kitchen Light" 71 | * "Hey Mycroft, put on Good Night" 72 | * "Hey Mycroft, what is Good Night status?" 73 | * "Hey Mycroft, what is the status of Good Night?" 74 | * "Hey Mycroft, set Diningroom to 50 percent" 75 | * "Hey Mycroft, dim Kitchen" 76 | * "Hey Mycroft, bright Kitchen" 77 | * "Hey Mycroft, dim Kitchen by 20 percent" 78 | * "Hey Mycroft, what's Bedroom temperature?" 79 | * "Hey Mycroft, tell me the temperature of Bedroom" 80 | * "Hey Mycroft, what's the Bedroom humidity?" 81 | * "Hey Mycroft, I'd like to know the humidity of Bedroom" 82 | * "Hey Mycroft, adjust Main Thermostat to 21 degrees" 83 | * "Hey Mycroft, regulate Main Thermostat to 20 degrees" 84 | * "Hey Mycroft, decrease Main Thermostat by 2 degrees" 85 | * "Hey Mycroft, increase Main Thermostat by 1 degrees" 86 | * "Hey Mycroft, what is Main Thermostat is regulated to?" 87 | * "Hey Mycroft, how the Main Thermostat tuned to?" 88 | 89 | ## Credits 90 | @mortommy 91 | 92 | ## Category 93 | **IoT** 94 | 95 | ## Tags 96 | #openHAB 97 | #smarthome 98 | #IoT 99 | #Automation 100 | #opensource 101 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contribution guidelines 2 | 3 | ### Pull requests are always welcome 4 | 5 | We are always thrilled to receive pull requests, and do our best to 6 | process them as fast as possible. Not sure if that typo is worth a pull 7 | request? Do it! We will appreciate it. 8 | 9 | If your pull request is not accepted on the first try, don't be 10 | discouraged! If there's a problem with the implementation, hopefully you 11 | received feedback on what to improve. 12 | 13 | ### Discuss your design on the mailing list 14 | 15 | We recommend discussing your plans [in the discussion forum](https://community.openhab.org/) 16 | before starting to code - especially for more ambitious contributions. 17 | This gives other contributors a chance to point you in the right 18 | direction, give feedback on your design, and maybe point out if someone 19 | else is working on the same thing. 20 | 21 | ### Create issues... 22 | 23 | Any significant improvement should be documented as [a GitHub 24 | issue](https://github.com/openhab/openhab-mycroft/issues?labels=enhancement&page=1&state=open) before anybody 25 | starts working on it. 26 | 27 | ### ...but check for existing issues first! 28 | 29 | Please take a moment to check that an issue doesn't already exist 30 | documenting your bug report or improvement proposal. If it does, it 31 | never hurts to add a quick "+1" or "I have this problem too". This will 32 | help prioritize the most common problems and requests. 33 | 34 | ### Conventions 35 | 36 | Fork the repo and make changes on your fork in a feature branch. 37 | 38 | Update the documentation when creating or modifying features. Test 39 | your documentation changes for clarity, concision, and correctness, as 40 | well as a clean documentation build. 41 | 42 | Write clean code. Universally formatted code promotes ease of writing, reading, 43 | and maintenance. 44 | 45 | Pull requests descriptions should be as clear as possible and include a 46 | reference to all the issues that they address. 47 | 48 | Pull requests must not contain commits from other users or branches. 49 | 50 | Commit messages must start with a capitalized and short summary (max. 50 51 | chars) written in the imperative, followed by an optional, more detailed 52 | explanatory text which is separated from the summary by an empty line. 53 | 54 | Code review comments may be added to your pull request. Discuss, then make the 55 | suggested modifications and push additional commits to your feature branch. Be 56 | sure to post a comment after pushing. The new commits will show up in the pull 57 | request automatically, but the reviewers will not be notified unless you 58 | comment. 59 | 60 | Before the pull request is merged, make sure that you squash your commits into 61 | logical units of work using `git rebase -i` and `git push -f`. After every 62 | commit the test suite should be passing. Include documentation changes in the 63 | same commit so that a revert would remove all traces of the feature or fix. 64 | 65 | Commits that fix or close an issue should include a reference like `Closes #XXX` 66 | or `Fixes #XXX`, which will automatically close the issue when merged. 67 | 68 | ### Merge approval 69 | 70 | openHAB-Mycroft maintainers use LGTM (Looks Good To Me) in comments on the code review 71 | to indicate acceptance. 72 | 73 | ### Sign your work 74 | 75 | The sign-off is a simple line at the end of the explanation for the 76 | patch, which certifies that you wrote it or otherwise have the right to 77 | pass it on as an open-source patch. The rules are pretty simple: if you 78 | can certify the below (from 79 | [developercertificate.org](http://developercertificate.org/)): 80 | 81 | ``` 82 | Developer Certificate of Origin 83 | Version 1.1 84 | 85 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 86 | 660 York Street, Suite 102, 87 | San Francisco, CA 94110 USA 88 | 89 | Everyone is permitted to copy and distribute verbatim copies of this 90 | license document, but changing it is not allowed. 91 | 92 | 93 | Developer's Certificate of Origin 1.1 94 | 95 | By making a contribution to this project, I certify that: 96 | 97 | (a) The contribution was created in whole or in part by me and I 98 | have the right to submit it under the open source license 99 | indicated in the file; or 100 | 101 | (b) The contribution is based upon previous work that, to the best 102 | of my knowledge, is covered under an appropriate open source 103 | license and I have the right under that license to submit that 104 | work with modifications, whether created in whole or in part 105 | by me, under the same open source license (unless I am 106 | permitted to submit under a different license), as indicated 107 | in the file; or 108 | 109 | (c) The contribution was provided directly to me by some other 110 | person who certified (a), (b) or (c) and I have not modified 111 | it. 112 | 113 | (d) I understand and agree that this project and the contribution 114 | are public and that a record of the contribution (including all 115 | personal information I submit with it, including my sign-off) is 116 | maintained indefinitely and may be redistributed consistent with 117 | this project or the open source license(s) involved. 118 | ``` 119 | 120 | then you just add a line to every git commit message: 121 | 122 | Signed-off-by: Joe Smith (github: github_handle) 123 | 124 | using your real name (sorry, no pseudonyms or anonymous contributions.) 125 | 126 | #### Small patch exception 127 | 128 | There are several exceptions to the signing requirement. Currently these are: 129 | 130 | * Your patch fixes spelling or grammar errors. 131 | * Your patch is a single line change to documentation. 132 | 133 | ## Community Guidelines 134 | 135 | We want to keep the openHAB-Mycroft community awesome, growing and collaborative. We 136 | need your help to keep it that way. To help with this we've come up with some 137 | general guidelines for the community as a whole: 138 | 139 | * Be nice: Be courteous, respectful and polite to fellow community members: no 140 | regional, racial, gender, or other abuse will be tolerated. We like nice people 141 | way better than mean ones! 142 | 143 | * Encourage diversity and participation: Make everyone in our community 144 | feel welcome, regardless of their background and the extent of their 145 | contributions, and do everything possible to encourage participation in 146 | our community. 147 | 148 | * Keep it legal: Basically, don't get us in trouble. Share only content that 149 | you own, do not share private or sensitive information, and don't break the 150 | law. 151 | 152 | * Stay on topic: Make sure that you are posting to the correct channel 153 | and avoid off-topic discussions. Remember when you update an issue or 154 | respond to an email you are potentially sending to a large number of 155 | people. Please consider this before you update. Also remember that 156 | nobody likes spam. 157 | -------------------------------------------------------------------------------- /USAGE.md: -------------------------------------------------------------------------------- 1 | # Mycroft AI Skill 2 | 3 | [Mycroft AI](https://mycroft.ai/) is the world’s first open source voice enabled assistant. 4 | The skill allows you to connect a running Mycroft instance to your openHAB system. 5 | Supported natural voice commands and responses can freely be modified and extended. 6 | 7 | The skill currently supportes the English (U.S.) and English (U.K.) languages but new languages are easily added via configuration files. 8 | 9 | ## General Configuration Instructions 10 | 11 | ### Requirements 12 | 13 | - A running [instance of Mycroft](https://mycroft.ai/get-mycroft/) (Mark 1, picroft, ...) 14 | - A running instance of openHAB 15 | - openHAB must be reacheable from the Mycroft instance 16 | 17 | ### Skill Installation 18 | 19 | The openHAB skill has to be installed on your Mycroft instance, please refer to the [official documentation](https://mycroft.ai/documentation/msm/) to learn how to install a skill. 20 | 21 | From 18.2.5b mycroft-core release it is possible to install the skill using the voice command: 22 | - *"Hey Mycroft, install openhab"* 23 | 24 | or via the [msm](https://mycroft.ai/documentation/msm/) command: 25 | ```shell 26 | msm install openhab 27 | ``` 28 | 29 | To manually install the skill: 30 | 31 | Clone the [skill repository](https://github.com/openhab/openhab-mycroft.git) into the Mycroft skills directory, 32 | then trigger installation of needed dependencies: 33 | 34 | ```shell 35 | cd ~/.mycroft/skills 36 | git clone https://github.com/openhab/openhab-mycroft.git skill-openhab 37 | workon mycroft 38 | cd skill-openhab 39 | pip install -r requirements.txt 40 | ``` 41 | 42 | If on [picroft](https://mycroft.ai/documentation/picroft/), use the skills directory `/opt/mycroft/skills` and skip the `workon mycroft` command. 43 | 44 | ### Skill Configuration 45 | 46 | The skill is configured using the mycroft skill settings. After the skill installation, configuration will be available at https://home.mycroft.ai/skills. After it is updated there, reload configuration is needed by saying: 47 | 48 | - *"Hey Mycroft, reload configuration"* 49 | 50 | The new settings will downloaded to settings.json in the skill folder. 51 | 52 | ### openHAB Item Configuration 53 | 54 | Items are exposed to openHAB skill for Mycroft through the use of tags. 55 | See the [Hue Emulation](https://www.openhab.org/addons/integrations/hueemulation/) and [HomeKit Add-on](https://www.openhab.org/addons/integrations/homekit/) documentation for details about tagging and available tags. 56 | 57 | * **Items via .items - File** 58 | 59 | See [Item Definition and Syntax](https://www.openhab.org/docs/configuration/items.html#item-definition-and-syntax) 60 | 61 | Some examples of tagged items are: 62 | 63 | ```java 64 | Color KitchenLight "Kitchen Light" (gKitchen) ["Lighting"] {channel="hue:0200:1:bloom1:color"} 65 | Color DiningroomLight "Diningroom Light" (gKitchen) ["Lighting"] {channel="hue:0200:1:bloom1:color"} 66 | Switch GoodNight "Good Night" ["Switchable"] 67 | 68 | Number MqttID1Temperature "Bedroom Temperature" ["CurrentTemperature"] {mqtt="<[mosquitto:mysensors/SI/1/1/1/0/0:state:default]"} 69 | Number MqttID1Humidity "Bedroom Humidity" ["CurrentHumidity"] {mqtt="<[mosquitto:mysensors/SI/1/0/1/0/1:state:default]"} 70 | 71 | Group gThermostat "Main Thermostat" ["gMainThermostat"] 72 | Number MainThermostatCurrentTemp "Main Thermostat Current Temperature" (gMainThermostat) ["CurrentTemperature"] 73 | Number MainThermostatTargetTemperature "Main Thermostat Target Temperature" (gMainThermostat) ["TargetTemperature"] 74 | String MainThermostatHeatingCoolingMode "Main Thermostat Heating/Cooling Mode" (gMainThermostat) ["homekit:HeatingCoolingMode"] 75 | ``` 76 | 77 | If items are modified in openHAB, a refresh in Mycroft is needed by the voice command: 78 | 79 | - *"Hey Mycroft, refresh openHAB Items"* 80 | 81 | #### Item Label Recommendation 82 | 83 | Matching of voice commands to Items happens based on the Item label (e.g. "Kitchen Light"). 84 | It is therefore advisable, to choose labels that can be used to form natural commands. 85 | As an example, compare "Hey Mycroft, turn on the *Kitchen Light*" vs. "Hey Mycroft, turn on the *Ground Floor LEDs Kitchen*". 86 | 87 | In combination with the Mycroft skill (and other similar services) you are thereby tempted to break with your naming scheme and introduce confusion into your setup. 88 | openHAB Tip: You may define multiple Items bound to one channel. 89 | Instead of manipulating the label of one single Item, you can define multiple Items specifically for voice commands. 90 | See the following example: 91 | 92 | ```java 93 | // Common/main Item bound to a binding channel 94 | Switch Kitchen_Light "Ground Floor LEDs Kitchen" (gKitchen) {channel="..."} 95 | // Two Items with labels fitting for voice commands, bound to the same binding channel 96 | Switch Kitchen_Light_A "Kitchen Light" ["Lighting"] {channel="..."} 97 | Switch Kitchen_Light_A2 "Kitchen LEDs" ["Lighting"] {channel="..."} 98 | ``` 99 | 100 | ### Example Voice Commands 101 | 102 | Each item tag supports different command, here is the summary: 103 | 104 | | Tag | Key word | Commands | 105 | |------------------------|-------------|---------------------| 106 | | `Switchable` | turn | on, off | 107 | | | switch | on, off | 108 | | | put | on, off | 109 | | | what's | status | 110 | | | | | 111 | | `Lighting` | turn | on, off | 112 | | | switch | on, off | 113 | | | put | on, off | 114 | | | dim | | 115 | | | dim by | value in percentage | 116 | | | bright | | 117 | | | bright by | value in percentage | 118 | | | | | 119 | | `Thermostat` | adjust to | values in degrees | 120 | | | regulate to | values in degrees | 121 | | | tune to | values in degrees | 122 | | | decrease by | values in degrees | 123 | | | increase by | values in degrees | 124 | | | what's | adjusted to | 125 | | | what's | regulated to | 126 | | | what's | tuned to | 127 | | | | | 128 | | `CurrentHumidity` | what's | humidity | 129 | | | | | 130 | | `CurrentTemperature` | what's | temperature | 131 | 132 | With references to the above item definitions, here are an examples of working commands: 133 | 134 | - * "Hey Mycroft, turn on Diningroom Light" 135 | - * "Hey Mycroft, switch off Kitchen Light" 136 | - * "Hey Mycroft, put on Good Night" 137 | - * "Hey Mycroft, what is Good Night status?" 138 | - * "Hey Mycroft, what is the status of Good Night?" 139 | - * "Hey Mycroft, set Diningroom to 50 percent" 140 | - * "Hey Mycroft, dim Kitchen" 141 | - * "Hey Mycroft, bright Kitchen" 142 | - * "Hey Mycroft, dim Kitchen by 20 percent" 143 | - * "Hey Mycroft, what's Bedroom temperature?" 144 | - * "Hey Mycroft, tell me the temperature of Bedroom" 145 | - * "Hey Mycroft, what's the Bedroom humidity?" 146 | - * "Hey Mycroft, I'd like to know the humidity of Bedroom" 147 | - * "Hey Mycroft, adjust Main Thermostat to 21 degrees" 148 | - * "Hey Mycroft, regulate Main Thermostat to 20 degrees" 149 | - * "Hey Mycroft, decrease Main Thermostat by 2 degrees" 150 | - * "Hey Mycroft, increase Main Thermostat by 1 degrees" 151 | - * "Hey Mycroft, what is Main Thermostat is regulated to?" 152 | - * "Hey Mycroft, how the Main Thermostat tuned to?" 153 | 154 | ### Additional Comments 155 | 156 | * By default all temperatures are in Celsius, no test so far about the tag Fahrenheit to the thermostat group item (which should also be tagged with `Thermostat`). 157 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Eclipse Public License - v 2.0 2 | 3 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE 4 | PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION 5 | OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 6 | 7 | 1. DEFINITIONS 8 | 9 | "Contribution" means: 10 | 11 | a) in the case of the initial Contributor, the initial content 12 | Distributed under this Agreement, and 13 | 14 | b) in the case of each subsequent Contributor: 15 | i) changes to the Program, and 16 | ii) additions to the Program; 17 | where such changes and/or additions to the Program originate from 18 | and are Distributed by that particular Contributor. A Contribution 19 | "originates" from a Contributor if it was added to the Program by 20 | such Contributor itself or anyone acting on such Contributor's behalf. 21 | Contributions do not include changes or additions to the Program that 22 | are not Modified Works. 23 | 24 | "Contributor" means any person or entity that Distributes the Program. 25 | 26 | "Licensed Patents" mean patent claims licensable by a Contributor which 27 | are necessarily infringed by the use or sale of its Contribution alone 28 | or when combined with the Program. 29 | 30 | "Program" means the Contributions Distributed in accordance with this 31 | Agreement. 32 | 33 | "Recipient" means anyone who receives the Program under this Agreement 34 | or any Secondary License (as applicable), including Contributors. 35 | 36 | "Derivative Works" shall mean any work, whether in Source Code or other 37 | form, that is based on (or derived from) the Program and for which the 38 | editorial revisions, annotations, elaborations, or other modifications 39 | represent, as a whole, an original work of authorship. 40 | 41 | "Modified Works" shall mean any work in Source Code or other form that 42 | results from an addition to, deletion from, or modification of the 43 | contents of the Program, including, for purposes of clarity any new file 44 | in Source Code form that contains any contents of the Program. Modified 45 | Works shall not include works that contain only declarations, 46 | interfaces, types, classes, structures, or files of the Program solely 47 | in each case in order to link to, bind by name, or subclass the Program 48 | or Modified Works thereof. 49 | 50 | "Distribute" means the acts of a) distributing or b) making available 51 | in any manner that enables the transfer of a copy. 52 | 53 | "Source Code" means the form of a Program preferred for making 54 | modifications, including but not limited to software source code, 55 | documentation source, and configuration files. 56 | 57 | "Secondary License" means either the GNU General Public License, 58 | Version 2.0, or any later versions of that license, including any 59 | exceptions or additional permissions as identified by the initial 60 | Contributor. 61 | 62 | 2. GRANT OF RIGHTS 63 | 64 | a) Subject to the terms of this Agreement, each Contributor hereby 65 | grants Recipient a non-exclusive, worldwide, royalty-free copyright 66 | license to reproduce, prepare Derivative Works of, publicly display, 67 | publicly perform, Distribute and sublicense the Contribution of such 68 | Contributor, if any, and such Derivative Works. 69 | 70 | b) Subject to the terms of this Agreement, each Contributor hereby 71 | grants Recipient a non-exclusive, worldwide, royalty-free patent 72 | license under Licensed Patents to make, use, sell, offer to sell, 73 | import and otherwise transfer the Contribution of such Contributor, 74 | if any, in Source Code or other form. This patent license shall 75 | apply to the combination of the Contribution and the Program if, at 76 | the time the Contribution is added by the Contributor, such addition 77 | of the Contribution causes such combination to be covered by the 78 | Licensed Patents. The patent license shall not apply to any other 79 | combinations which include the Contribution. No hardware per se is 80 | licensed hereunder. 81 | 82 | c) Recipient understands that although each Contributor grants the 83 | licenses to its Contributions set forth herein, no assurances are 84 | provided by any Contributor that the Program does not infringe the 85 | patent or other intellectual property rights of any other entity. 86 | Each Contributor disclaims any liability to Recipient for claims 87 | brought by any other entity based on infringement of intellectual 88 | property rights or otherwise. As a condition to exercising the 89 | rights and licenses granted hereunder, each Recipient hereby 90 | assumes sole responsibility to secure any other intellectual 91 | property rights needed, if any. For example, if a third party 92 | patent license is required to allow Recipient to Distribute the 93 | Program, it is Recipient's responsibility to acquire that license 94 | before distributing the Program. 95 | 96 | d) Each Contributor represents that to its knowledge it has 97 | sufficient copyright rights in its Contribution, if any, to grant 98 | the copyright license set forth in this Agreement. 99 | 100 | e) Notwithstanding the terms of any Secondary License, no 101 | Contributor makes additional grants to any Recipient (other than 102 | those set forth in this Agreement) as a result of such Recipient's 103 | receipt of the Program under the terms of a Secondary License 104 | (if permitted under the terms of Section 3). 105 | 106 | 3. REQUIREMENTS 107 | 108 | 3.1 If a Contributor Distributes the Program in any form, then: 109 | 110 | a) the Program must also be made available as Source Code, in 111 | accordance with section 3.2, and the Contributor must accompany 112 | the Program with a statement that the Source Code for the Program 113 | is available under this Agreement, and informs Recipients how to 114 | obtain it in a reasonable manner on or through a medium customarily 115 | used for software exchange; and 116 | 117 | b) the Contributor may Distribute the Program under a license 118 | different than this Agreement, provided that such license: 119 | i) effectively disclaims on behalf of all other Contributors all 120 | warranties and conditions, express and implied, including 121 | warranties or conditions of title and non-infringement, and 122 | implied warranties or conditions of merchantability and fitness 123 | for a particular purpose; 124 | 125 | ii) effectively excludes on behalf of all other Contributors all 126 | liability for damages, including direct, indirect, special, 127 | incidental and consequential damages, such as lost profits; 128 | 129 | iii) does not attempt to limit or alter the recipients' rights 130 | in the Source Code under section 3.2; and 131 | 132 | iv) requires any subsequent distribution of the Program by any 133 | party to be under a license that satisfies the requirements 134 | of this section 3. 135 | 136 | 3.2 When the Program is Distributed as Source Code: 137 | 138 | a) it must be made available under this Agreement, or if the 139 | Program (i) is combined with other material in a separate file or 140 | files made available under a Secondary License, and (ii) the initial 141 | Contributor attached to the Source Code the notice described in 142 | Exhibit A of this Agreement, then the Program may be made available 143 | under the terms of such Secondary Licenses, and 144 | 145 | b) a copy of this Agreement must be included with each copy of 146 | the Program. 147 | 148 | 3.3 Contributors may not remove or alter any copyright, patent, 149 | trademark, attribution notices, disclaimers of warranty, or limitations 150 | of liability ("notices") contained within the Program from any copy of 151 | the Program which they Distribute, provided that Contributors may add 152 | their own appropriate notices. 153 | 154 | 4. COMMERCIAL DISTRIBUTION 155 | 156 | Commercial distributors of software may accept certain responsibilities 157 | with respect to end users, business partners and the like. While this 158 | license is intended to facilitate the commercial use of the Program, 159 | the Contributor who includes the Program in a commercial product 160 | offering should do so in a manner which does not create potential 161 | liability for other Contributors. Therefore, if a Contributor includes 162 | the Program in a commercial product offering, such Contributor 163 | ("Commercial Contributor") hereby agrees to defend and indemnify every 164 | other Contributor ("Indemnified Contributor") against any losses, 165 | damages and costs (collectively "Losses") arising from claims, lawsuits 166 | and other legal actions brought by a third party against the Indemnified 167 | Contributor to the extent caused by the acts or omissions of such 168 | Commercial Contributor in connection with its distribution of the Program 169 | in a commercial product offering. The obligations in this section do not 170 | apply to any claims or Losses relating to any actual or alleged 171 | intellectual property infringement. In order to qualify, an Indemnified 172 | Contributor must: a) promptly notify the Commercial Contributor in 173 | writing of such claim, and b) allow the Commercial Contributor to control, 174 | and cooperate with the Commercial Contributor in, the defense and any 175 | related settlement negotiations. The Indemnified Contributor may 176 | participate in any such claim at its own expense. 177 | 178 | For example, a Contributor might include the Program in a commercial 179 | product offering, Product X. That Contributor is then a Commercial 180 | Contributor. If that Commercial Contributor then makes performance 181 | claims, or offers warranties related to Product X, those performance 182 | claims and warranties are such Commercial Contributor's responsibility 183 | alone. Under this section, the Commercial Contributor would have to 184 | defend claims against the other Contributors related to those performance 185 | claims and warranties, and if a court requires any other Contributor to 186 | pay any damages as a result, the Commercial Contributor must pay 187 | those damages. 188 | 189 | 5. NO WARRANTY 190 | 191 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT 192 | PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" 193 | BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR 194 | IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF 195 | TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR 196 | PURPOSE. Each Recipient is solely responsible for determining the 197 | appropriateness of using and distributing the Program and assumes all 198 | risks associated with its exercise of rights under this Agreement, 199 | including but not limited to the risks and costs of program errors, 200 | compliance with applicable laws, damage to or loss of data, programs 201 | or equipment, and unavailability or interruption of operations. 202 | 203 | 6. DISCLAIMER OF LIABILITY 204 | 205 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT 206 | PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS 207 | SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 208 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST 209 | PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 210 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 211 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 212 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE 213 | POSSIBILITY OF SUCH DAMAGES. 214 | 215 | 7. GENERAL 216 | 217 | If any provision of this Agreement is invalid or unenforceable under 218 | applicable law, it shall not affect the validity or enforceability of 219 | the remainder of the terms of this Agreement, and without further 220 | action by the parties hereto, such provision shall be reformed to the 221 | minimum extent necessary to make such provision valid and enforceable. 222 | 223 | If Recipient institutes patent litigation against any entity 224 | (including a cross-claim or counterclaim in a lawsuit) alleging that the 225 | Program itself (excluding combinations of the Program with other software 226 | or hardware) infringes such Recipient's patent(s), then such Recipient's 227 | rights granted under Section 2(b) shall terminate as of the date such 228 | litigation is filed. 229 | 230 | All Recipient's rights under this Agreement shall terminate if it 231 | fails to comply with any of the material terms or conditions of this 232 | Agreement and does not cure such failure in a reasonable period of 233 | time after becoming aware of such noncompliance. If all Recipient's 234 | rights under this Agreement terminate, Recipient agrees to cease use 235 | and distribution of the Program as soon as reasonably practicable. 236 | However, Recipient's obligations under this Agreement and any licenses 237 | granted by Recipient relating to the Program shall continue and survive. 238 | 239 | Everyone is permitted to copy and distribute copies of this Agreement, 240 | but in order to avoid inconsistency the Agreement is copyrighted and 241 | may only be modified in the following manner. The Agreement Steward 242 | reserves the right to publish new versions (including revisions) of 243 | this Agreement from time to time. No one other than the Agreement 244 | Steward has the right to modify this Agreement. The Eclipse Foundation 245 | is the initial Agreement Steward. The Eclipse Foundation may assign the 246 | responsibility to serve as the Agreement Steward to a suitable separate 247 | entity. Each new version of the Agreement will be given a distinguishing 248 | version number. The Program (including Contributions) may always be 249 | Distributed subject to the version of the Agreement under which it was 250 | received. In addition, after a new version of the Agreement is published, 251 | Contributor may elect to Distribute the Program (including its 252 | Contributions) under the new version. 253 | 254 | Except as expressly stated in Sections 2(a) and 2(b) above, Recipient 255 | receives no rights or licenses to the intellectual property of any 256 | Contributor under this Agreement, whether expressly, by implication, 257 | estoppel or otherwise. All rights in the Program not expressly granted 258 | under this Agreement are reserved. Nothing in this Agreement is intended 259 | to be enforceable by any entity that is not a Contributor or Recipient. 260 | No third-party beneficiary rights are created under this Agreement. 261 | 262 | Exhibit A - Form of Secondary Licenses Notice 263 | 264 | "This Source Code may also be made available under the following 265 | Secondary Licenses when the conditions for such availability set forth 266 | in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), 267 | version(s), and exceptions or additional permissions here}." 268 | 269 | Simply including a copy of this Agreement, including this Exhibit A 270 | is not sufficient to license the Source Code under Secondary Licenses. 271 | 272 | If it is not possible or desirable to put the notice in a particular 273 | file, then You may include the notice in a location (such as a LICENSE 274 | file in a relevant directory) where a recipient would be likely to 275 | look for such a notice. 276 | 277 | You may add additional accurate notices of copyright ownership. 278 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: iso-8859-15 -*- 2 | 3 | # 4 | # Copyright (c) 2010-2019 Contributors to the openHAB project 5 | # 6 | # See the NOTICE file(s) distributed with this work for additional 7 | # information. 8 | # 9 | # This program and the accompanying materials are made available under the 10 | # terms of the Eclipse Public License 2.0 which is available at 11 | # http://www.eclipse.org/legal/epl-2.0 12 | # 13 | # SPDX-License-Identifier: EPL-2.0 14 | # 15 | 16 | from os.path import dirname 17 | 18 | from adapt.intent import IntentBuilder 19 | from mycroft.skills.core import MycroftSkill, intent_handler 20 | from mycroft.util.log import getLogger 21 | from rapidfuzz import fuzz 22 | 23 | import requests 24 | import json 25 | 26 | # v 0.1 - just switch on and switch off a fix light 27 | # v 0.2 - code review 28 | # v 0.3 - first working version on fixed light item 29 | # v 0.4 - getTaggedItems method in order to get all the tagged items from openHAB 30 | # v 0.5 - refresh tagged item intent 31 | # v 0.6 - add findItemName method and import fuzzywuzzy 32 | # v 0.7 - add intent for switchable items 33 | # v 0.8 - merged lighting and switchable intent in onoff intent 34 | # v 0.9 - added support to dimmable items 35 | # v 1.0 - added Thermostat tag support 36 | # v 1.1 - added what status Switchable tag 37 | # v 1.2 - support to python 3.0 38 | # v 1.3 - support german 39 | # v 1.4 - support spanish 40 | # v 1.5 - support to 19 41 | 42 | 43 | __author__ = 'mortommy' 44 | 45 | LOGGER = getLogger(__name__) 46 | 47 | class openHABSkill(MycroftSkill): 48 | 49 | def __init__(self): 50 | super(openHABSkill, self).__init__(name="openHABSkill") 51 | 52 | self.command_headers = {"Content-type": "text/plain"} 53 | 54 | self.polling_headers = {"Accept": "application/json"} 55 | 56 | self.url = None 57 | self.lightingItemsDic = dict() 58 | self.switchableItemsDic = dict() 59 | self.currentTempItemsDic = dict() 60 | self.currentHumItemsDic = dict() 61 | #self.currentThermostatItemsDic = dict() 62 | self.targetTemperatureItemsDic = dict() 63 | #self.homekitHeatingCoolingModeDic = dict() 64 | 65 | def initialize(self): 66 | 67 | supported_languages = ["en-us", "it-it", "de-de", "es-es"] 68 | 69 | if self.lang not in supported_languages: 70 | self.log.warning("Unsupported language for " + self.name + ", shutting down skill.") 71 | self.shutdown() 72 | 73 | self.handle_websettings_update() 74 | 75 | if self.url is not None: 76 | self.getTaggedItems() 77 | else: 78 | self.speak_dialog('ConfigurationNeeded') 79 | 80 | refresh_tagged_items_intent = IntentBuilder("RefreshTaggedItemsIntent").require("RefreshTaggedItemsKeyword").build() 81 | self.register_intent(refresh_tagged_items_intent, self.handle_refresh_tagged_items_intent) 82 | 83 | onoff_status_intent = IntentBuilder("OnOff_StatusIntent").require("OnOffStatusKeyword").require("Command").require("Item").build() 84 | self.register_intent(onoff_status_intent, self.handle_onoff_status_intent) 85 | 86 | dimmer_status_intent = IntentBuilder("Dimmer_StatusIntent").require("DimmerStatusKeyword").require("Item").optionally("BrightPercentage").build() 87 | self.register_intent(dimmer_status_intent, self.handle_dimmer_status_intent) 88 | 89 | #what_status_intent = IntentBuilder("What_StatusIntent").require("WhatStatusKeyword").require("Item").require("RequestType").build() 90 | #self.register_intent(what_status_intent, self.handle_what_status_intent) 91 | self.register_entity_file('item.entity') 92 | self.register_entity_file('requesttype.entity') 93 | self.register_intent_file('what.status.intent',self.handle_what_status_intent) 94 | 95 | setTemp_status_intent = IntentBuilder("SetTemp_StatusIntent").require("ThermostatStatusKeyword").require("Item").require("TempValue").build() 96 | self.register_intent(setTemp_status_intent, self.handle_setTemp_status_intent) 97 | 98 | list_items_intent = IntentBuilder("ListItemsIntent").require("ListItemsKeyword").build() 99 | self.register_intent(list_items_intent, self.handle_list_items_intent) 100 | 101 | self.settings_change_callback = self.handle_websettings_update 102 | 103 | def get_config(self, key): 104 | return (self.settings.get(key) or self.config_core.get('openHABSkill', {}).get(key)) 105 | 106 | def handle_websettings_update(self): 107 | if self.get_config('host') is not None and self.get_config('port') is not None: 108 | self.url = "http://%s:%s/rest" % (self.get_config('host'), self.get_config('port')) 109 | self.getTaggedItems() 110 | else: 111 | self.url = None 112 | 113 | def getTaggedItems(self): 114 | #find all the items tagged Lighting and Switchable from openHAB 115 | #the labeled items are stored in dictionaries 116 | 117 | self.lightingItemsDic = {} 118 | self.switchableItemsDic = {} 119 | self.currentTempItemsDic = {} 120 | self.currentHumItemsDic = {} 121 | self.currentThermostatItemsDic = {} 122 | self.targetTemperatureItemsDic = {} 123 | self.homekitHeatingCoolingModeDic = {} 124 | 125 | if self.url == None: 126 | LOGGER.error("Configuration needed!") 127 | self.speak_dialog('ConfigurationNeeded') 128 | else: 129 | requestUrl = self.url+"/items?recursive=false" 130 | 131 | try: 132 | req = requests.get(requestUrl, headers=self.polling_headers) 133 | if req.status_code == 200: 134 | json_response = req.json() 135 | for x in range(0,len(json_response)): 136 | if ("Lighting" in json_response[x]['tags']): 137 | self.lightingItemsDic.update({json_response[x]['name']: json_response[x]['label']}) 138 | elif ("Switchable" in json_response[x]['tags']): 139 | self.switchableItemsDic.update({json_response[x]['name']: json_response[x]['label']}) 140 | elif ("CurrentTemperature" in json_response[x]['tags']): 141 | self.currentTempItemsDic.update({json_response[x]['name']: json_response[x]['label']}) 142 | elif ("CurrentHumidity" in json_response[x]['tags']): 143 | self.currentHumItemsDic.update({json_response[x]['name']: json_response[x]['label']}) 144 | elif ("Thermostat" in json_response[x]['tags']): 145 | self.currentThermostatItemsDic.update({json_response[x]['name']: json_response[x]['label']}) 146 | elif ("TargetTemperature" in json_response[x]['tags']): 147 | self.targetTemperatureItemsDic.update({json_response[x]['name']: json_response[x]['label']}) 148 | elif ("homekit:HeatingCoolingMode" in json_response[x]['tags']): 149 | self.homekitHeatingCoolingModeDic.update({json_response[x]['name']: json_response[x]['label']}) 150 | else: 151 | pass 152 | else: 153 | LOGGER.error("Some issues with the command execution!") 154 | self.speak_dialog('GetItemsListError') 155 | 156 | except KeyError: 157 | pass 158 | except Exception: 159 | LOGGER.error("Some issues with the command execution!") 160 | self.speak_dialog('GetItemsListError') 161 | 162 | def findItemName(self, itemDictionary, messageItem): 163 | 164 | bestScore = 0 165 | score = 0 166 | bestItem = None 167 | 168 | try: 169 | for itemName, itemLabel in list(itemDictionary.items()): 170 | score = fuzz.ratio(messageItem, itemLabel, score_cutoff=bestScore) 171 | if score > bestScore: 172 | bestScore = score 173 | bestItem = itemName 174 | except KeyError: 175 | pass 176 | 177 | return bestItem 178 | 179 | 180 | def getItemsFromDict(self, typeStr, itemsDict): 181 | if len(itemsDict) == 0: 182 | return "" 183 | else: 184 | return "%s: %s" % (typeStr, ', '.join(list(itemsDict.values()))) 185 | 186 | def handle_list_items_intent(self, message): 187 | msg = self.getItemsFromDict("Lights", self.lightingItemsDic) + "\n" 188 | msg = msg.strip() + ' ' + self.getItemsFromDict("Switches", self.switchableItemsDic) + "\n" 189 | msg = msg.strip() + ' ' + self.getItemsFromDict("Current Temperature", self.currentTempItemsDic) + "\n" 190 | msg = msg.strip() + ' ' + self.getItemsFromDict("Current Humidity", self.currentHumItemsDic) + "\n" 191 | msg = msg.strip() + ' ' + self.getItemsFromDict("Thermostat", self.currentThermostatItemsDic) + "\n" 192 | msg = msg.strip() + ' ' + self.getItemsFromDict("Target Temperature", self.targetTemperatureItemsDic) + "\n" 193 | msg = msg.strip() + ' ' + self.getItemsFromDict("Homekit Heating and Cooling", self.homekitHeatingCoolingModeDic) 194 | self.speak_dialog('FoundItems', {'items': msg.strip()}) 195 | 196 | def handle_refresh_tagged_items_intent(self, message): 197 | #to refresh the openHAB items labeled list we use an intent, we can ask Mycroft to make the refresh 198 | 199 | self.getTaggedItems() 200 | dictLenght = str(len(self.lightingItemsDic) + len(self.switchableItemsDic) + len(self.currentTempItemsDic) + len(self.currentHumItemsDic) + len(self.currentThermostatItemsDic) + len(self.targetTemperatureItemsDic) + len(self.homekitHeatingCoolingModeDic)) 201 | self.speak_dialog('RefreshTaggedItems', {'number_item': dictLenght}) 202 | 203 | def handle_onoff_status_intent(self, message): 204 | command = message.data.get('Command') 205 | messageItem = message.data.get('Item') 206 | 207 | #We have to find the item to update from our dictionaries 208 | self.lightingSwitchableItemsDic = dict() 209 | self.lightingSwitchableItemsDic.update(self.lightingItemsDic) 210 | self.lightingSwitchableItemsDic.update(self.switchableItemsDic) 211 | 212 | ohItem = self.findItemName(self.lightingSwitchableItemsDic, messageItem) 213 | 214 | if ohItem != None: 215 | if (command != "on") and (command != "off"): 216 | self.speak_dialog('ErrorDialog') 217 | else: 218 | statusCode = self.sendCommandToItem(ohItem, command.upper()) 219 | if statusCode == 200: 220 | self.speak_dialog('StatusOnOff', {'command': command, 'item': messageItem}) 221 | elif statusCode == 404: 222 | LOGGER.error("Some issues with the command execution!. Item not found") 223 | self.speak_dialog('ItemNotFoundError') 224 | else: 225 | LOGGER.error("Some issues with the command execution!") 226 | self.speak_dialog('CommunicationError') 227 | else: 228 | LOGGER.error("Item not found!") 229 | self.speak_dialog('ItemNotFoundError') 230 | 231 | def handle_dimmer_status_intent(self, message): 232 | command = message.data.get('DimmerStatusKeyword') 233 | messageItem = message.data.get('Item') 234 | brightValue = message.data.get('BrightPercentage', None) 235 | 236 | statusCode = 0 237 | newBrightValue = 0 238 | 239 | ohItem = self.findItemName(self.lightingItemsDic, messageItem) 240 | 241 | if ohItem != None: 242 | #if ((command == "set") or (command == "imposta") or (command == "setze") or (command == "pone")): 243 | if self.voc_match(command, 'Set'): 244 | if ((brightValue == None) or (int(brightValue) < 0) or (int(brightValue) > 100)): 245 | self.speak_dialog('ErrorDialog') 246 | else: 247 | statusCode = self.sendCommandToItem(ohItem, brightValue) 248 | else: 249 | #find current item statusCode 250 | state = self.getCurrentItemStatus(ohItem) 251 | if (state != None): 252 | #dim or brighten the value 253 | curBrightList = state.split(',') 254 | curBright = int(curBrightList[len(curBrightList)-1]) 255 | 256 | if(brightValue == None): 257 | brightValue = "10" 258 | 259 | #if ((command == "dim") or (command == "abbassa") or (command == "dimme") or (command == "oscurece")): 260 | if self.voc_match(command, 'Dim'): 261 | newBrightValue = curBright-(int(brightValue)) 262 | else: 263 | newBrightValue = curBright+(int(brightValue)) 264 | 265 | if (newBrightValue < 0): 266 | newBrightValue = 0 267 | elif (newBrightValue > 100): 268 | newBrightValue = 100 269 | else: 270 | pass 271 | 272 | #send command to item 273 | statusCode = self.sendCommandToItem(ohItem, str(newBrightValue)) 274 | else: 275 | pass 276 | 277 | if statusCode == 200: 278 | self.speak_dialog('StatusDimmer', {'item': messageItem}) 279 | elif statusCode == 404: 280 | LOGGER.error("Some issues with the command execution!. Item not found") 281 | self.speak_dialog('ItemNotFoundError') 282 | else: 283 | LOGGER.error("Some issues with the command execution!") 284 | self.speak_dialog('CommunicationError') 285 | 286 | else: 287 | LOGGER.error("Item not found!") 288 | self.speak_dialog('ItemNotFoundError') 289 | 290 | def handle_what_status_intent(self, message): 291 | 292 | messageItem = message.data.get('item') 293 | LOGGER.debug("Item: %s" % (messageItem)) 294 | requestType = message.data.get('requesttype') 295 | LOGGER.debug("Request Type: %s" % (requestType)) 296 | 297 | unitOfMeasure = self.translate('Degree') 298 | infoType = self.translate('Temperature') 299 | 300 | self.currStatusItemsDic = dict() 301 | 302 | if self.voc_match(requestType, 'Temperature'): 303 | self.currStatusItemsDic.update(self.currentTempItemsDic) 304 | elif self.voc_match(requestType, 'Humidity'): 305 | unitOfMeasure = self.translate('Percentage') 306 | infoType = self.translate('Humidity') 307 | self.currStatusItemsDic.update(self.currentHumItemsDic) 308 | elif self.voc_match(requestType, 'Status'): 309 | infoType = self.translate('Status') 310 | unitOfMeasure = "" 311 | self.currStatusItemsDic.update(self.switchableItemsDic) 312 | else: 313 | self.currStatusItemsDic.update(self.targetTemperatureItemsDic) 314 | 315 | ohItem = self.findItemName(self.currStatusItemsDic, messageItem) 316 | 317 | if ohItem != None: 318 | state = self.getCurrentItemStatus(ohItem) 319 | self.speak_dialog('TempHumStatus', {'item': messageItem, 'temp_hum': infoType, 'temp_hum_val': state, 'units_of_measurement': unitOfMeasure}) 320 | else: 321 | LOGGER.error("Item not found!") 322 | self.speak_dialog('ItemNotFoundError') 323 | 324 | def handle_setTemp_status_intent(self, message): 325 | command = message.data.get('ThermostatStatusKeyword') 326 | messageItem = message.data.get('Item') 327 | tempVal = message.data.get('TempValue') 328 | 329 | statusCode = 0 330 | newTempValue = 0 331 | 332 | ohItem = self.findItemName(self.targetTemperatureItemsDic, messageItem) 333 | 334 | if ohItem != None: 335 | if self.voc_match(command, 'Regulate'): 336 | statusCode = self.sendCommandToItem(ohItem, tempVal) 337 | newTempValue = tempVal 338 | else: 339 | state = self.getCurrentItemStatus(ohItem) 340 | if ((state != None) and (state.isdigit())): 341 | if self.voc_match(command, 'Increase'): 342 | newTempValue = int(state)+(int(tempVal)) 343 | else: 344 | newTempValue = int(state)-(int(tempVal)) 345 | 346 | statusCode = self.sendCommandToItem(ohItem, str(newTempValue)) 347 | else: 348 | pass 349 | 350 | if statusCode == 200: 351 | self.speak_dialog('ThermostatStatus', {'item': messageItem, 'temp_val': str(newTempValue)}) 352 | elif statusCode == 404: 353 | LOGGER.error("Some issues with the command execution! Item not found") 354 | self.speak_dialog('ItemNotFoundError') 355 | else: 356 | LOGGER.error("Some issues with the command execution!") 357 | self.speak_dialog('CommunicationError') 358 | 359 | else: 360 | LOGGER.error("Item not found!") 361 | self.speak_dialog('ItemNotFoundError') 362 | 363 | def sendStatusToItem(self, ohItem, command): 364 | requestUrl = self.url+"/items/%s/state" % (ohItem) 365 | req = requests.put(requestUrl, data=command, headers=self.command_headers) 366 | 367 | return req.status_code 368 | 369 | def sendCommandToItem(self, ohItem, command): 370 | requestUrl = self.url+"/items/%s" % (ohItem) 371 | req = requests.post(requestUrl, data=command, headers=self.command_headers) 372 | 373 | return req.status_code 374 | 375 | def getCurrentItemStatus(self, ohItem): 376 | requestUrl = self.url+"/items/%s/state" % (ohItem) 377 | state = None 378 | 379 | try: 380 | req = requests.get(requestUrl, headers=self.command_headers) 381 | 382 | if req.status_code == 200: 383 | state = req.text 384 | else: 385 | LOGGER.error("Some issues with the command execution!") 386 | self.speak_dialog('CommunicationError') 387 | 388 | except KeyError: 389 | pass 390 | 391 | return state 392 | 393 | def stop(self): 394 | pass 395 | 396 | def create_skill(): 397 | return openHABSkill() 398 | --------------------------------------------------------------------------------