Piloter sa box Domoticz avec Google Assistant


Dans un premier temps, assurez vous d’avoir sécurisé l’accès à votre box domotique Domoticz et de l’avoir rendu accessible depuis internet. Vous devez configurer votre routeur WAN afin de rediriger le port HTTP vers l’adresse IP de votre box domotique en ajoutant une nouvelle règle NAT (référez vous à la documentation de votre FAI). Dans le cas où vous ne disposez pas d’une adresse IP fixe, je vous conseille d’utiliser l’application ngrok qui est payante mais à des tarifs très abordables pour ce cas d’usage.

L’aquisition et l’installation d’un haut-parleur intelligent Google Home ou Google Home Mini vous permettra de piloter votre domotique même si vos téléphones et tablettes sont inactifs.

Création du capteur virtuel sous Domoticz

Nous allons avoir besoin d’ajouter un capteur virtuel afin de traiter les ordres vocaux émis par IFTTT.

Depuis le menu Réglages > Matériel, ajoutez un matériel de type Dummy, vous pouvez le nommer comme vous le souhaitez.

En validant il apparait dans la liste, cliquez alors sur le bouton Créer un capteur virtuel, nommez le IFTTT et sélectionnez le type Texte puis validez.

Assurez vous que la donnée du dispositif affiche bien Test lorsque vous saisissez l’url complétée ci-dessous dans votre navigateur web :

[scheme]://[username:password@][host][:port]/json.htm?type=command&param=udevice&idx=[idx]&svalue=Test

Notez bien précisement cette URL, vous en aurez besoin pour réaliser la suite du tutoriel.

Configuration de IFTTT

Nous allons utiliser l’application IFTTT qui fera office de passerelle assurant la transmission de certains ordres vocaux à l'API de Domoticz.

Création du compte IFTTT

Pour utiliser IFTTT vous allez avoir besoin de vous inscrire sur l'application web, à noter qu’une application native est disponible sur les systèmes Android et iOS.

Création des applets IFTTT

Une applet IFTTT se décompose en deux parties, le déclencheur this qui écoute les ordres vocaux et exécute l’action then en cas de correspondance. Comme vous pouvez vous en douter, pour chaque applet notre déclencheur sera donc Google Assistant et notre action sera un simple Webhooks qui fera une simple requête HTTP GET.

Voici la liste des applets que j’utilise au sein de ma domotique (le paramètre domoticz_baseurl est à remplacer selon l’url que vous aurez mis de côté) :

"Say a phrase with a text ingredient" > "allume $" > "D'accord" > "[domoticz_baseurl]&svalue=switch:On:<<<{{TextField}}>>>"

"Say a phrase with a text ingredient" > "éteins $" ou "coupe $" > "D'accord" > "[domoticz_baseurl]&svalue=switch:Off:<<<{{TextField}}>>>"

"Say a phrase with a text ingredient" > "ouvre $" ou "monte $" > "D'accord" > "[domoticz_baseurl]&svalue=blind:On:<<<{{TextField}}>>>"

"Say a phrase with a text ingredient" > "ferme $" ou "descend $" > "D'accord" > "[domoticz_baseurl]&svalue=blind:Off:<<<{{TextField}}>>>"

"Say a phrase with both a number and a text ingredient" > "règle $ #" ou "régler $ #" > "D'accord" > "[domoticz_baseurl]&svalue=set:<<<{{TextField}}>>>:{{NumberField}}"

"Say a phrase with a text ingredient" > "exécute le scénario $" ou "joue la scène $" > "D'accord" > "[domoticz_baseurl]&svalue=scene:<<<{{TextField}}>>>"

Implémentation du script pour Domoticz

Le script LUA ci-dessous permet de faire la correspondance entre la donnée du dispositif IFTTT et les divers dispositifs à domotiser par la voix. Adaptez le selon vos besoins et placez le dans le dossier de Domoticz prévu à cet effet.

scripts/lua/script_device_ifttt.lua

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
commandArray = {}

local blinds = {
	["Chambre 1 - Volet"]="celuidelachambredelapetite lachambredelapetite levoletdelachambredelapetite levoletroulantdelachambredelapetite lesvoletsdeschambres touslesvolets touslesvoletsroulants",
	["Chambre 2 - Volet"]="celuidelachambre lachambre levoletdelachambre levoletroulantdelachambre lesvoletsdeschambres touslesvolets touslesvoletsroulants",
	["Cuisine - Volet"]="celuidelacuisine lacuisine levoletdelacuisine levoletroulantdelacuisine touslesvolets touslesvoletsroulants",
	["Salon - Volet 1"]="celuidedroite levoletdedroite levoletroulantdedroite levoletdedroitedusalon levoletroulantdedroitedusalon lesalon lesvoletsdusalon lesvoletsroulantsdusalon touslesvolets touslesvoletsroulants",
	["Salon - Volet 2"]="celuidumilieu levoletdumilieu levoletroulantdumilieu levoletdumilieudusalon levoletroulantdumilieudusalon lesalon lesvoletsdusalon lesvoletsroulantsdusalon touslesvolets touslesvoletsroulants",
	["Salon - Volet 3"]="celuidegauche levoletdegauche levoletroulantdegauche levoletdegauchedusalon levoletroulantdegauchedusalon lesalon lesvoletsdusalon lesvoletsroulantsdusalon touslesvolets touslesvoletsroulants",
}

local captors = {
	["Chambre 1"]="delachambredelapetite danslachambredelapetite deschambres detouteslespices delamaison",
	["Chambre 2"]="delachambre danslachambre deschambres detouteslespices delamaison",
	["Cuisine"]="delacuisine danslacuisine detouteslespices delamaison",
	["Salle de bain"]="delasalledebain danslasalledebain detouteslespices delamaison",
	["Salon"]="dusalon danslesalon dusjour danslesjour detouteslespices delamaison"
}

local sensors = {
	["Aspirateur"]="laspirateur laspirateursur lapuissancedelaspirateur lapuissancedelaspirateursur touslesdispositifs",
	["Hygrostat"]="lavmc lavmcsur lhygrostat lhygrostatsur lhumidit lhumiditsur lhumiditdelair lhumiditdelairsur lhumiditdanslair lhumiditdanslairsur letauxdhumidit letauxdhumiditsur letauxdhumiditdelair letauxdhumiditdelairsur letauxdhumiditdanslair letauxdhumiditdanslairsur",
	["Thermostat"]="lechauffage lechauffagesur lethermostat lethermostatsur latemprature latempraturesur latempraturedelair latempraturedelairsur latempraturedanslair latempraturedanslairsur"
}

local scenes = {
	["Soir"]="soir dusoir"
}

local switchs = {
	["Balcon - Lumière 1"]="celledubalcon lebalcon lalumiredubalcon lespotdubalcon lejardin lalumiredujardin leslumiresdujardin lesspotsdubalcon lesspotsdujardin toutesleslumires touslesdispositifs",
	["Balcon - Lumière 2"]="celledelaterrasse laterrasse lalumiredelaterrasse lespotdelaterrasse lejardin lalumiredujardin leslumiresdujardin lesspotsdubalcon lesspotsdujardin toutesleslumires touslesdispositifs",
	["Chambre 1 - Lumière 1"]="celledelapetite lapetite lachambredelapetite lalumiredelachambredelapetite leslumiresdelachambredelapetite leschambres leslumiresdeschambres toutesleslumires touslesdispositifs",
	["Chambre 1 - Lumière 2"]="laguirlande laguirlandedelapetite laguirlandedelachambredelapetite leslumiresdelachambredelapetite toutesleslumires touslesdispositifs",
	["Chambre 2 - Lumière"]="celledelachambre lachambre lalumiredelachambre leslumiresdelachambre leschambres leslumiresdeschambres toutesleslumires touslesdispositifs",
	["Cuisine - Lumière 1"]="lesspots lesspotsdelacuisine lacuisine leslumiresdelacuisine toutesleslumires touslesdispositifs",
	["Cuisine - Lumière 2"]="celledelacuisine lalumiredelacuisine lacuisine leslumiresdelacuisine toutesleslumires touslesdispositifs",
	["Cuisine - Lumière 3"]="lesspots lesspotsdelacuisine lacuisine leslumiresdelacuisine toutesleslumires touslesdispositifs",
	["Entrée - Lumière"]="celledelentree lentree lalumiredelentree lepalier lalumiredupalier toutesleslumires touslesdispositifs",
	["Entrée - Placard"]="leplacard la lumireduplacard toutesleslumires touslesdispositifs",
	["Escalier - Lumière"]="celledelescalier lescalier lalumiredelescalier lescalierdusoussol ladescentedusoussol toutesleslumires touslesdispositifs",
	["Salon - Lumière 1"]="celledelatable latable lalumiredelatable lalumiredelatabledusalon lesalon lalumiredusalon leslumiresdusalon toutesleslumires touslesdispositifs",
	["Salon - Lumière 2"]="celleducanap lecanap lalumireducanap lalumireducanapdusalon lesalon lalumiredusalon leslumiresdusalon toutesleslumires touslesdispositifs",
	["Salon - Lumière 3"]="celledelatl latl lalumiredelatl lalumiredelatldusalon lesalon lalumiredusalon leslumiresdusalon toutesleslumires touslesdispositifs",
	["Salle de bain - Lumière"]="celledelasalledebain lasalledebain lalumiredelasalledebain toutesleslumires touslesdispositifs",
	["WC - Lumière"]="celledeswc celledestoilettes lestoilettes leswc lalumiredestoilettes lalumiredeswc toutesleslumires touslesdispositifs"
}

local function get(deviceValue, position)
    local current = 0
	for value in string.gmatch(deviceValue, '([^:]+)') do
		current = current + 1
		if current == position then
            return value
		end
    end
    return value
end

for deviceName,deviceValue in pairs(devicechanged) do
	if deviceName == 'IFTTT' then
		local command = get(deviceValue, 1)
        if command == 'blind' then
            local value = get(deviceValue, 2)
            local text = get(deviceValue, 3):gsub("%W", ""):lower()
            for blind,words in pairs(blinds) do
                for word in words:gmatch("%w+") do
                    if text == word then
                        commandArray[blind] = value
                    end
                end
            end
		elseif command == 'set' then
            local value = get(deviceValue, 3)
            local text = get(deviceValue, 2):gsub("%W", ""):lower()
            for sensor,words in pairs(sensors) do
                for word in words:gmatch("%w+") do
                    if text == word then
                        commandArray[sensor] = 'Set Level: ' .. value
                    end
                end
            end
		elseif command == 'get' then
		    local raw = get(deviceValue, 3)
            local text = raw:gsub("%W", ""):lower()
			local sentences = {}
            for captor,words in pairs(captors) do
                for word in words:gmatch("%w+") do
                    if text == word then
						local property = get(deviceValue, 2)
						local values = {}
						local index = 0
						for value in otherdevices[captor]:gmatch("[^;]+") do
							values[index] = value
							index = index + 1
						end
						if property == 'temperature' then
							table.insert(sentences, captor..", "..tostring(values[0]).." °")
						end
						if property == 'humidity' and index > 1 then
							table.insert(sentences, captor..", "..tostring(values[1]).." %")
						end
                    end
                end
            end
            local tts = "404"
            if #sentences > 0 then
            	tts = table.concat(sentences, ".")
            end
			os.execute("gnotify "..tts)
		elseif command == 'scene' then
            local text = get(deviceValue, 2):gsub("%W", ""):lower()
            for scene,words in pairs(scenes) do
                for word in words:gmatch("%w+") do
                    if text == word then
                        commandArray['Scene:'..scene] = 'On'
                    end
                end
            end
        elseif command == 'switch' then
            local value = get(deviceValue, 2)
            local text = get(deviceValue, 3):gsub("%W", ""):lower()
            for switch,words in pairs(switchs) do
                for word in words:gmatch("%w+") do
                    if text == word then
                        commandArray[switch] = value
                    end
                end
            end
            for sensor,words in pairs(sensors) do
                for word in words:gmatch("%w+") do
                    if text == word then
                        commandArray[sensor] = value
                    end
                end
            end
        end
    end
end

return commandArray

Dites juste “Ok Google, allume toutes les lumières” pour tester.

J’espère que ce tutoriel vous aura plu, et n’hésitez pas à poster vos commentaires.