Aller au contenu
ADN182

JPI SMS/MMS Gateway

Recommended Posts

Yo, 

 

Je vous propose un petit module sans prétention, dialoguant avec JPI (voir le sujet ici Sujet JPI) permettant d'envoyer des SMS/MMS depuis la HC2. J'utilise ce module depuis pas mal de temps pour m'envoyer des SMS (d'alerte, d'information) depuis la HC2.

 

JPI a remplacé l'application "SMS Gateway" tournant également sur Android, JPI permettant de bénéficier d'autres fonctionnalités (Effectué des actions sur le HC2 à la réception de SMS...) Au passage de je remercie @dJuL pour cette excellente application et la rapidité de son support.

 

Voilà si ça peu aider certain c'est par ici : 

 

Principe :

Envoyé des SMS/MMS en modifiant une Variable Global se nommant : SMS/MMS

Le VD se charge d'envoyer le Message à JPI, si celui-ci ne répond pas, il retentera suivant les paramètres inscrit dans le VD ("retry_max", 6 tentatives par défaut pour les SMS, 3 pour les MMS) si après toutes ces tentatives il n'a pas réussi il enverra une Notification Push ainsi qu'un Email pour prévenir de l'échec.

L'idée est de recevoir toujours l'information même si votre passerelle SMS est indisponible.

Depuis les dernière version de JPI il est possible d'envoyer des MMS, le but est de pouvoir recevoir l'image d'une caméra directement pas MMS tout comme vous le faites sans doute déjà par Mail.

 

Utiliisation :

SMS :

Envoyer un SMS a tous les contacts : 

fibaro:setGlobal("SMS", "Test") -- Envoie Test à tous les contact de la variable DefaultContact paramètrer dans les bouton du VD.

Envoyer un SMS à des contacts spécifique présent dans la variable Contacts : 

fibaro:setGlobal("SMS", '"Message":"Test", "SendTo":["Georges","0606060606"]') -- Envoie Test à Georges (doit être présent dans la variable DefaultContact) et au numéro 0606060606

Envoyer un SMS à un numéro (Peut être utilisé pour des cas spécifique, temporaire, alerte les voisins...  :

fibaro:setGlobal("SMS", '"Message":"Test", "SendTo":["0606060606"]') -- Envoie Test au numéro 06060606

MMS :

Envoyer un MMS à partir d'une Caméra existante dans la HC2 : 

fibaro:setGlobal("MMS", "Cam_Salon") -- Envoie à tous les contacts un Snapshot de la caméra se nommant "Cam_Salon" attention à la casse !
fibaro:setGlobal("MMS", '"Image":"Cam_Salon", "Message":"Detection dans le salon", "SendTo":["0606060606"]') -- Envoie l'image de la camera "Cam_Salon" avec le Message Détection dans le Salon au numéro 0606060606

Envoyé un MMS à partir d'une URL : 

fibaro:setGlobal("MMS", '"Image":"http://user:pass@doorbird.mondomaine.com/bha-api/image.cgi", "Message":"Quelqu un Sonne a la porte", "SendTo":["Georges"]')

 

Installation : 

 - Importer le module Virtuel JPI_SMS_MMS_Gateway-v3.0.vfib

  • Renseigner dans le VD l'adresse IP et le Port pour contacter JPI
  • Modifier la variable Contacts dans chaque bouton (SMS/MMS), vous pouvez ajouter des contacts en respectant le schéma {"Name": "Georges","number": "0600000000"}
    • local Contacts = '{ { "Name": "ADN182", "number": "0600000000" }, {"Name": "Lazer","number": "0600000000"} }'
  • Renseigner le tableau userID et smartphoneID pour la notification en cas d'echec.
    • local userID = {       -- Email User ID if SMS not Sent
          2,
          "Lazer",
      }
      local smartphoneID = {  -- Push Smartphone ID if SMS not Sent
          600,
          "Google Pixel 2 XL",
      }
  • Intégrer les icônes (optionnel) 
  • Cliquer au moins une fois sur les bouton SMS et MMS pour la création des variables

 - Créer une nouvelle Scène JPI Gateway de type LUA 

  • Insérer le code ci-dessous, en prenant soin de modifier le numéro  avec celui de votre VD
--[[
%% properties
%% events
%% globals
SMS
MMS
--]]

local JPI_Gateway = 125;

fibaro:debug("Start Scene")

if fibaro:getGlobalValue("SMS") ~= "" then
  fibaro:debug("Envoi du SMS : "..tostring(fibaro:getGlobalValue("SMS")))
  fibaro:call(JPI_Gateway, "pressButton", "3")
end

if fibaro:getGlobalValue("MMS") ~= "" then
  fibaro:debug("Envoi du MMS : "..tostring(fibaro:getGlobalValue("MMS")))
  fibaro:call(JPI_Gateway, "pressButton", "4")
end

 

GEA (Merci @Steven et @pepite, dieu sait que j'embête ce dernier avec mes toilettes mais il me le rend bien ;) ) : 

 

  • Sois en affectant une variable Global comme ceux-ci : 
{"Global", "SMS", ' "Message":"Ouverture de la porte de garage - #date# #time#" '}
  • Ou alors si vous disposez de la V6, mettre ces informations dans le config() :  
GEA.options.sms = {name = "SMS",
    action = function(message) fibaro:setGlobal("SMS", GEA.getMessage(message)) end,
}
  GEA.options.mms = {name = "MMS",
    action = function(message) fibaro:setGlobal("MMS", GEA.getMessage(message)) end,
}
  • Ensuite pour l'envoie d'un SMS : 
GEA.add(true, 0, "",{{"SMS", '"Message":"GEA demarrer à #time# le #date#", "SendTo":["Anto"]'}})
GEA.add(true, 0, "",{{"SMS", "GEA demarrer à #time# le #date#"}})
  •  Envoie de MMS :
GEA.add(true, 0, "",{{"MMS", "Cam_Salon"}})
GEA.add(true, 0, "",{{"MMS", '"Image":"Cam_Salon", "Message":"Detection dans le salon"'}})
GEA.add(true, 0, "",{{"MMS", '"Image":"Cam_Salon", "Message":"Detection dans le salon", "SendTo":["Anto"]'}})

Icône : 

Bouton MMS : 

JPI MMS.png

Bouton SMS :

JPI SMS.png

Bouton pour la Scène :

JPI SMS-MMS.png

JPI_SMS_MMS_Gateway.vfib

Modifié par ADN182
V3.0
  • Like 6

Partager ce message


Lien à poster
Partager sur d’autres sites

Yes, merci@ADN182

Le MMS est vraiment top. Merci@Djul

Qu on rende à Cesar ce qui est à Cesar :-) GEA est à@Steven. Jene suis qu un disciple qui apprend du maitre et il m en apprend énormement.
Bon faut que dedie une tablette avec SIm ou un vieux tel pour JPI.
Tu utilises JPI en passerelle SMS ?

Envoyé de mon Nexus 5X en utilisant Tapatalk

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

merci pour cela, je vais le traduire pour ma LD

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites
Il y a 3 heures, pepite a dit :

Tu utilises JPI en passerelle SMS ?

Oui, tout comme je le faisais avec SMS Gateway, ça permet d'avoir un moyen de communication avec la domotique ne dépendant pas de la connexion Internet. Cela me permet également de redémarrer les services de la Fibaro (root) à distance par l'envoi de SMS. Cause : ça m'est déjà arrivé d'être coincé avec une erreur 503, en week-end a plusieurs KMs sans pouvoir interagir physiquement avec la box :(.

 

Content que ça puisse servir @jojo;)

 

Partager ce message


Lien à poster
Partager sur d’autres sites

Bon, faut vraiment que je me mette à JPI plus en profondeur ;-) il met aussi arriver que la box plante alors que des kms nous separe l'un de l'autre ;-)

  • Haha 1

Partager ce message


Lien à poster
Partager sur d’autres sites
Le 18/02/2018 à 13:00, ADN182 a dit :

en modifiant une Variable Global se nommant : SMS/MMS

Bonjour,

 

Je suis un débutant sur le domaine, j'ai bien suivi les étapes mais je n'ai pas compris cette partie

Partager ce message


Lien à poster
Partager sur d’autres sites

Hello @nabil,

 

Quand je dis ça :

Citation

Envoyé des SMS/MMS en modifiant une Variable Global se nommant : SMS/MMS

C'est à dire en faisant comme ci-dessous, tu retrouve les instructions dans la section "Utilisation" du tuto en première page :

Citation

fibaro:setGlobal("SMS", "Test")

Par cette action tu affecte la valeur "Test" à la variable Global "SMS" cela enverra "Test" à tous les contacts.

 

Tu as une HCL ou une HC2 ?  (Car il me semble qu'il n'y a pas de variable Global sur HCL :( ) 

Modifié par ADN182

Partager ce message


Lien à poster
Partager sur d’autres sites

oui, oui, il y a des variables globales dans les HCL, mais pas de LUA

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Bonjour

 

Merci de votre retour, J'en ai les deux. A vrai dire j'en ai 7 HC2 et une HCL et je les utilisent dans une contexte professionnelle.

Je vous donnerai plus de détail par la suite.

Je vais essayer de suivre les différents étapes comme dans le tuto et je vous tiendrai au courant.

Je suis vraiment intéressé par la fonction d’envois SMS parce que je supervise des équipement très critiques.

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites
Le 18/02/2018 à 22:00, ADN182 a dit :

Oui, tout comme je le faisais avec SMS Gateway, ça permet d'avoir un moyen de communication avec la domotique ne dépendant pas de la connexion Interne

D'ailleurs, comment as tu mis cela en place ? Il est inutile de reinventer la roue ;-)

Partager ce message


Lien à poster
Partager sur d’autres sites

Moi aussi, la partie MMS me le faut, mais pas eu le temps de tout basculer sur le smartphone dédié encore.

Partager ce message


Lien à poster
Partager sur d’autres sites

Hello,

Le 21/09/2018 à 13:54, pepite a dit :

D'ailleurs, comment as tu mis cela en place ? Il est inutile de reinventer la roue ;-)

Concernant la communication Domotique j'utilise directement JPI, dans SMS entrant je configure un mot clé

image.png.5988119e9377f9c47396958452ff9e2d.png 

 

Ensuite je crée un scénario avec le mot Cle TTS par exemple qui permet de décelnché une scène de la HC2 en lui passant des arguments 

Le but étant d'envoyé une notification TTS dans la maison par le biais d'un SMS (je sais totalement useless ;) )

Il suffit de le décliné pour ce que vous voulez.

On pourrait très bien imagine reprendre la scène de Steven pour Google Home et la transformer pour JPI. Ainsi envoyé Eteint Lumière Canapé ou Ouvre la porte de garage.

image.png.4d08ae781d689e0bdc68a4f1151085fa.png

 

Faut que je mette à jour mon code, j'ai fait une petit évolution qui permet d'appeler une fois l'API si plusieurs contact au lieu de 1 appels/contact

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Bonsoir @ADN182

 

Super Merci.Oui j'aurais pu chercher mais pourquoi réinventer ce que font les pros ? ;-) 

 

Le 26/09/2018 à 22:58, ADN182 a dit :

j'ai fait une petit évolution qui permet d'appeler une fois l'API si plusieurs contact au lieu de 1 appels/contact

:13:

Partager ce message


Lien à poster
Partager sur d’autres sites
Il y a 9 heures, Twentycents a dit :

a carte SIM

Non je ne répondrai pas ;-)

  • Like 1
  • Haha 1

Partager ce message


Lien à poster
Partager sur d’autres sites

pas cool de ne pas répondre @pepite ! il faut prendre une mèche à métaux et faire un trou à environ 5cm de la prise réseau, ça marche aussi avec une cuillère à soupe mais c'est plus long à percer :)

Ben non dans ton tel ou ta tablette ;) 

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Bah si j’ai plus de courant j’ai plus internet si j’ai plus internet j’ai pas de passerelle sms lol faites les malins les mecs lool

non mais je pensais me prendre plutôt un routeur sms en vrai genre avec une dual sim quoi ;)

Partager ce message


Lien à poster
Partager sur d’autres sites
Le 19/10/2018 à 15:06, Twentycents a dit :

j’ai plus de courant

Les onduleurs c'est magique ;-)

Partager ce message


Lien à poster
Partager sur d’autres sites

Merci pour ton VD @ADN182

 

Je me suis permis de faire une v2 du bouton d'envoi de SMS, avec la possibilité d'utiliser aux choix les noms ou les ID des users et portables pour les notifications email+push en cas d'erreur, ainsi que quelques modifications cosmétiques :

---------------------------------------------------------------------
-- Module permettant d'envoyer des SMS/MMS par l'intermédiaire de JPI
-- Nom	   : JPI Gateway
-- Author  : ADN182 / Lazer
-- Date    : 18-02-2018 / 08-12-2018
-- History : v2.0
-- Thanks  : All Members of www.domotique-fibaro.fr forum
---------------------------------------------------------------------

-- Examples :
-- Send a SMS to a specific contact Georges (must be present in Contacts) and to number 0606060606
-- fibaro:setGlobal("SMS", '{"Message":"Test", "SendTo":["0606060606", "Georges"]}')
-- fibaro:setGlobal("SMS", '"Message":"Test", "SendTo":["0606060606", "Georges"]')
-- fibaro:setGlobal("SMS", '"Message":"Test", "SendTo":["Anto"]')
-- Send a SMS to All contact present in Contacts Variable
-- fibaro:setGlobal("SMS", '{"Message":"Test"}')
-- fibaro:setGlobal("SMS", '"Message":"Test"')
-- fibaro:setGlobal("SMS", "Test")

-- User configurable variables
local Contacts = {
	{Name="Anto", number="0707070707"},
	{Name="George", number="0606060606"}
}
local userID = {       -- Email User ID if SMS not Sent
	2,
	"Lazer",
}
local smartphoneID = {  -- Push Smartphone ID if SMS not Sent
	600,
	"Google Pixel 2 XL",
}
local retry_max = 6     -- Number of Retry if SMS sent failed
local retry_sleep = 10  -- Sleep in second between each retry

-- System variables
local selfID = fibaro:getSelfId()
local ip = fibaro:get(selfID, 'IPAddress')
local port = fibaro:get(selfID, 'TCPPort')

--
-- Message() function
--
local function Message(color, text)
	if color and color ~= "" then
		fibaro:debug('<span style="color:'..color..';">'..(text or "<i>nil</i>")..'</span>')
	else
		fibaro:debug(text or "<i>nil</i>")
	end
end

--
-- updateLabel() function
--
local function updateLabel(label, value)
	if fibaro:get(selfID, "ui."..label..".value") ~= value then
		if debug then
			Message("", "Update label : ui." .. label .. ".value => " .. (value or ""))
		end
		fibaro:call(selfID, "setProperty", "ui."..label..".value", value or "")
	end
end

--
-- Notification() function
--
local function Notification(message, param)
	local message = message or "<vide>"
	Message("yellow", "Notification : "..message)
	if param then
		local notif
		for _, notif in ipairs(param) do
			if debug then
				Message("", notif)
			end
			-- Envoi Push
			if notif == "push" and type(smartphoneID) == "table" then
				local id
				for _, id in ipairs(smartphoneID) do
					if type(id) == "number" then
						if debug then
							Message("", "Send Push smartphone ID : " .. tostring(id))
						end
						fibaro:call(id, "sendPush", message)
					elseif type(id) == "string" then
						local response = api.get("/iosDevices")
						if type(response) == "table" then
							local smartphone
							for _, smartphone in ipairs(response) do
								if smartphone.id and smartphone.name and smartphone.name == id then
									if debug then
										Message("", "Send Push smartphone ID : " .. tostring(smartphone.id))
									end
									fibaro:call(smartphone.id, "sendPush", message)
								end
							end
						else
							Message("red", "Error : can't get smartphones API")
						end
					else
						Message("red", 'Error : invalid smartphoneID type "' .. type(id) .. '"')
					end
				end
			-- Envoi Email
			elseif notif == "email" and type(userID) == "table" then
				local id
				for _, id in ipairs(userID) do
					if type(id) == "number" then
						if debug then
							Message("", "Send Email user ID : " .. tostring(id))
						end
						fibaro:call(id, "sendEmail", "JPI SMS Gateway", message)
					elseif type(id) == "string" then
						local response = api.get("/users")
						if type(response) == "table" then
							local user
							for _, user in ipairs(response) do
								if user.id and user.name and user.name == id then
									if debug then
										Message("", "Send Email user ID : " .. tostring(user.id))
									end
									fibaro:call(user.id, "sendEmail", "JPI SMS Gateway", message)
								end
							end
						else
							Message("red", "Error : can't get users API")
						end
					else
						Message("red", 'Error : invalid userID type "' .. type(id) .. '"')
					end
				end
			end
		end
	else
		Message("orange", "Warning : no notification options given")
	end
end

--
-- Create Variable function
--
local function createGlobalIfNotExists(varName, defaultValue)
	if varName and fibaro:getGlobal(varName) == nil then
		Message("blue", "Création de la variable "..varName)
		newVar = {}
		newVar.name = varName
		newVar.value = defaultValue or ""
		local HC2 = Net.FHttp("127.0.0.1", 11111)
		HC2:POST("/api/globalVariables", json.encode(newVar))
		HC2 = nil
	end
end

--
-- URL Encode function
--
local function urlencode(str)
	if str then
		str = string.gsub(str, "\n", "\r\n")
		str = string.gsub(str, "([^%w %-%_%.%~])", function (c) return string.format ("%%%02X", string.byte(c)) end)
		str = string.gsub(str, " ", "+")
	end
	return str	
end

--
-- SendSMS() function
--
local function SendSMS(message, number)
	updateLabel("LabelStatus", "...")
	updateLabel("LabelMessage", message)
	updateLabel("LabelDate", os.date("%d/%m/%Y %H:%M:%S"))
	local erreur = 0
	local server = Net.FHttp(ip, tonumber(port))
	local payload = "/?action=sendSms&number="..number.."&message="..urlencode(tostring(message or "empty"))
	for i=1, retry_max do
		response, status, errorCode = server:GET(payload)
		if tonumber(errorCode) == 0 and tonumber(status) == 200 then
			if (response ~= nil) then
				if tostring(response):match("OK - ") then
					Message("green", response)
					updateLabel("LabelStatus", "OK - SMS sent")
					fibaro:log("SMS envoyé")
					erreur = 0
					break
				else
					Message("red", "Error : incorrect response")
					Message("red", "status="..status..", errorCode="..errorCode..", response="..response)
					erreur = erreur + 1
				end
			else
				Message("red", "Error : empty response")
				Message("red", "status="..status..", errorCode="..errorCode)
				erreur = erreur + 1
			end
		else
			Message("red", "Error !")
			Message("red;", "status="..status..", errorCode="..errorCode..", response="..(response or "<i>nil</i>"))
			erreur = erreur + 1
		end
		fibaro:sleep(retry_sleep*1000)
	end

	-- Error management
	if erreur > 0 then
		updateLabel("LabelStatus", "Error - SMS not sent")
		fibaro:log("Error")
		Message("red", "Unable to send the message, SMS Gateway was unavailable !")
		Notification("Erreur lors de l'envoi du SMS : "..message, {"push", "email"})
	end
end


--
-- Main 
--

Message("", os.date("%d/%m/%Y"))

-- Create Variable if not exist
createGlobalIfNotExists("SMS", "")

-- Get SMS content
local data = fibaro:getGlobalValue("SMS")

-- Reset global variable value
fibaro:setGlobal("SMS", "")

-- Prepare data
if not string.find(data, '"\s*:\s*"') then 
	data = '{"Message":"'..data..'"}'
end
if string.find(data, "{") ~= 1 then
	data = '{'..data..'}'
end
local status, data = pcall(function() return json.decode(data) end)

if data.Message ~= "" then
	if data.SendTo then
		local j
		for j = #data.SendTo, 1, -1 do
			local ContactnotFound = 1
			Message("yellow", "Try to send the message '" ..data.Message.. "' to "..data.SendTo[j])
			-- Envoi vers un numéro spécifique
			if data.SendTo[j]:match("%d%d%d%d%d%d%d%d%d%d") then
				Message("white", "Send message : "..data.Message)
				Message("white", "To number : "..data.SendTo[j])
				SendSMS(data.Message, data.SendTo[j])
				ContactnotFound = 0
			else
				-- Envoi vers un contact spécifique présent dans la variable Contacts
				local i
				for i = #Contacts, 1, -1 do
					if Contacts[i].Name == data.SendTo[j] then
						Message("white", "Send message : "..data.Message)
						Message("white", "To : "..Contacts[i].Name)
						SendSMS(data.Message, Contacts[i].number)
						ContactnotFound = 0
					end
				end
			end
			if ContactnotFound == 1 then
				Message("red", "Contact "..data.SendTo[j].." not found in Param !")
				Notification("Contact "..data.SendTo[j].." not found", {"push", "email"})
			end
		end
	else
		-- Envoi vers l'ensemble des numéros
		local i
		for i = #Contacts, 1, -1 do
			Message("yellow", "Try to send the message '" ..data.Message.. "' to "..Contacts[i].Name)
			SendSMS(data.Message, Contacts[i].number)
		end
	end
else
	Message("red", "Unable to send SMS, filed Message is empty")
	Notification("Unable to send SMS, filed Message is empty", {"push", "email"})
end

 

Je n'ai pas touché au bouton d'envoi de MMS car je n'ai pas activé la data sur ma passerelle, je préfère ne pas exploser les petits 50 Mo de mon forfait Free Mobile 0/2€.

Cependant, j'ai identifié un bug potentiel dans la détection des caméras en ligne 72 :

			if jsonTable[j].baseType == "com.fibaro.camera" then

Mes caméras Hikvision utilisent un plugin, donc le baseType peut être différent, il faudrait modifier comme suit :

			if jsonTable[j].baseType == "com.fibaro.camera" or jsonTable[j].baseType == "com.fibaro.ipCamera"  then

 

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Hello,

 

Merci @Lazer ! La fonction notif annexe j'avais pas pris le temps de l'implémenté la c'est nickel ! J'ai corrigé la partie MMS et ajouter les cosmétiques ;) 

 

J'ai pris le temps de faire un "merge" et d'intégrer aussi les modifications que j'avais faites mais pas eu le temps de partager. Il s'agit de faire un seul appel API pour le même message à plusieurs contacts. (En effet avant 1 message à 3 contacts faisait 3 appels API par contact, désormais une seul appel API est fait avec à l'intérieur les numéros des 3 contacts.)

 

Je viens de mettre à jour en v3.0 du coup.

Partager ce message


Lien à poster
Partager sur d’autres sites

Yo,

 

@ADN182 Peuxtu mettre les codes des boutons SMS et MMS en V3.0 stp, pour éviter de réimporter le vfib stp ;-)

pepite mode faineant, adepte du copier-coller lol

Partager ce message


Lien à poster
Partager sur d’autres sites

Code Bouton SMS v3 :

---------------------------------------------------------------------
-- Module permettant d'envoyer des SMS/MMS par l'intermédiaire de JPI
-- Nom	   : JPI Gateway
-- Author  : ADN182 / Lazer
-- Date    : 18-02-2018 / 10-12-2018
-- History : v3.0
-- Thanks  : All Members of www.domotique-fibaro.fr forum
---------------------------------------------------------------------

-- Examples :
-- Send a SMS to a specific contact Lazer (must be present in Contacts) and to number 0606060606
-- fibaro:setGlobal("SMS", '{"Message":"Test", "SendTo":["0606060606", "Lazer"]}')
-- fibaro:setGlobal("SMS", '"Message":"Test", "SendTo":["0606060606", "ADN182"]')
-- fibaro:setGlobal("SMS", '"Message":"Test", "SendTo":["ADN182"]')

-- Send a SMS to All contact present in Contacts Variable
-- fibaro:setGlobal("SMS", '{"Message":"Test"}')
-- fibaro:setGlobal("SMS", '"Message":"Test"')
-- fibaro:setGlobal("SMS", "Test")

-- User configurable variables
local Contacts = {
	{Name="ADN182", number="0707070707"},
	{Name="Lazer", number="0606060606"}								 
}

local userID = {       -- Email User ID if SMS not Sent
	2,
	"Lazer",
}
local smartphoneID = {  -- Push Smartphone ID if SMS not Sent
	600,
	"Google Pixel 2 XL",
}
local retry_max = 6;     -- Number of Retry if SMS sent failed
local retry_sleep = 10;  -- Sleep in second between each retry

-- System variables
local selfID = fibaro:getSelfId()
local ip = fibaro:get(selfID, 'IPAddress')
local port = fibaro:get(selfID, 'TCPPort')
				

--
-- Message() function
--
local function Message(color, text)
	if color and color ~= "" then
		fibaro:debug('<span style="color:'..color..';">'..(text or "<i>nil</i>")..'</span>')
	else
		fibaro:debug(text or "<i>nil</i>")
	end
end

--
-- updateLabel() function
--
local function updateLabel(label, value)
	if fibaro:get(selfID, "ui."..label..".value") ~= value then
		if debug then
			Message("", "Update label : ui." .. label .. ".value => " .. (value or ""))
		end
		fibaro:call(selfID, "setProperty", "ui."..label..".value", value or "")
	end
end

--
-- Notification() function
--
local function Notification(message, param)
	local message = message or "<vide>"
	Message("yellow", "Notification : "..message)
	if param then
		local notif
		for _, notif in ipairs(param) do
			if debug then
				Message("", notif)
			end
			-- Envoi Push
			if notif == "push" and type(smartphoneID) == "table" then
				local id
				for _, id in ipairs(smartphoneID) do
					if type(id) == "number" then
						if debug then
							Message("", "Send Push smartphone ID : " .. tostring(id))
						end
						fibaro:call(id, "sendPush", message)
					elseif type(id) == "string" then
						local response = api.get("/iosDevices")
						if type(response) == "table" then
							local smartphone
							for _, smartphone in ipairs(response) do
								if smartphone.id and smartphone.name and smartphone.name == id then
									if debug then
										Message("", "Send Push smartphone ID : " .. tostring(smartphone.id))
									end
									fibaro:call(smartphone.id, "sendPush", message)
								end
							end
						else
							Message("red", "Error : can't get smartphones API")
						end
					else
						Message("red", 'Error : invalid smartphoneID type "' .. type(id) .. '"')
					end
				end
			-- Envoi Email
			elseif notif == "email" and type(userID) == "table" then
				local id
				for _, id in ipairs(userID) do
					if type(id) == "number" then
						if debug then
							Message("", "Send Email user ID : " .. tostring(id))
						end
						fibaro:call(id, "sendEmail", "JPI SMS Gateway", message)
					elseif type(id) == "string" then
						local response = api.get("/users")
						if type(response) == "table" then
							local user
							for _, user in ipairs(response) do
								if user.id and user.name and user.name == id then
									if debug then
										Message("", "Send Email user ID : " .. tostring(user.id))
									end
									fibaro:call(user.id, "sendEmail", "JPI SMS Gateway", message)
								end
							end
						else
							Message("red", "Error : can't get users API")
						end
					else
						Message("red", 'Error : invalid userID type "' .. type(id) .. '"')
					end
				end
			end
		end
	else
		Message("orange", "Warning : no notification options given")
	end
end

--
-- Create Variable function
--
local function createGlobalIfNotExists(varName, defaultValue)
	if varName and fibaro:getGlobal(varName) == nil then
		Message("blue", "Création de la variable "..varName)
		newVar = {}
		newVar.name = varName
		newVar.value = defaultValue or ""
		local HC2 = Net.FHttp("127.0.0.1", 11111)
		HC2:POST("/api/globalVariables", json.encode(newVar))
		HC2 = nil
	end
end

--
-- URL Encode function
--
local function urlencode(str)
	if str then
		str = string.gsub(str, "\n", "\r\n")
		str = string.gsub(str, "([^%w %-%_%.%~])", function (c) return string.format ("%%%02X", string.byte(c)) end)
		str = string.gsub(str, " ", "+")
	end
	return str	
end

--
-- SendSMS() function
--
local function SendSMS(message, number)
	updateLabel("LabelStatus", "...")
	updateLabel("LabelMessage", message)
	updateLabel("LabelDate", os.date("%d/%m/%Y %H:%M:%S"))
	local erreur = 0
	local server = Net.FHttp(ip, tonumber(port))
	local payload = "/?action=sendSms&number="..number.."&message="..urlencode(tostring(message or "empty"))
	for i=1, retry_max do
		response, status, errorCode = server:GET(payload)
		if tonumber(errorCode) == 0 and tonumber(status) == 200 then
			if (response ~= nil) then
				if tostring(response):match("OK - ") then
					Message("green", response)
					updateLabel("LabelStatus", "OK - SMS sent")
					fibaro:log("SMS envoyé")
					erreur = 0
					break
				else
					Message("red", "Error : incorrect response")
					Message("red", "status="..status..", errorCode="..errorCode..", response="..response)
					erreur = erreur + 1
				end
			else
				Message("red", "Error : empty response")
				Message("red", "status="..status..", errorCode="..errorCode)
				erreur = erreur + 1
			end
		else
			Message("red", "Error !")
			Message("red;", "status="..status..", errorCode="..errorCode..", response="..(response or "<i>nil</i>"))
			erreur = erreur + 1
		end
		fibaro:sleep(retry_sleep*1000)
	end

	-- Error management
	if erreur > 0 then
		updateLabel("LabelStatus", "Error - SMS not sent")
		fibaro:log("Error")
		Message("red", "Unable to send the message, SMS Gateway was unavailable !")
		Notification("Erreur lors de l'envoi du SMS : "..message, {"push", "email"})
																									  
	end
end


--
-- Main 
--

Message("", os.date("%d/%m/%Y"))

-- Create Variable if not exist
createGlobalIfNotExists("SMS", "")

-- Get SMS content
local data = fibaro:getGlobalValue("SMS")

-- Reset global variable value
--fibaro:setGlobal("SMS", "")

-- Prepare data
if not string.find(data, '"\s*:\s*"') then 
	data = '{"Message":"'..data..'"}'
end

if string.find(data, "{") ~= 1 then
	data = '{'..data..'}'
end

local status, data = pcall(function() return json.decode(data) end)

if data.Message ~= "" then
  	local numbers = {};																					   
	if data.SendTo then
		local j
		for j = #data.SendTo, 1, -1 do
			local ContactnotFound = 1
			Message("yellow", "Try to send the message '" ..data.Message.. "' to "..data.SendTo[j])
			-- Envoi vers un numéro spécifique
			if data.SendTo[j]:match("%d%d%d%d%d%d%d%d%d%d") then
				Message("white", "Send message : "..data.Message)
				Message("white", "To number : "..data.SendTo[j])
				table.insert(numbers, data.SendTo[j]);				  
				ContactnotFound = 0
			else
				-- Envoi vers un contact spécifique présent dans la variable Contacts
				local i
				for i = #Contacts, 1, -1 do
					if Contacts[i].Name == data.SendTo[j] then
						Message("white", "Send message : "..data.Message)
						Message("white", "To : "..Contacts[i].Name)
						table.insert(numbers, Contacts[i].number);									 
						ContactnotFound = 0
					end
				end
			end
			if ContactnotFound == 1 then
				Message("red", "Contact "..data.SendTo[j].." not found in Param !")
				Notification("Contact "..data.SendTo[j].." not found", {"push", "email"})
			end
		end
	else
		-- Envoi vers l'ensemble des numéros
		local i
		for i = #Contacts, 1, -1 do
			Message("yellow", "Try to send the message '" ..data.Message.. "' to "..Contacts[i].Name)
			table.insert(numbers, Contacts[i].number);											   
		end
	end
	SendSMS(data.Message,table.concat(numbers, ";"))											 
else
	Message("red", "Unable to send SMS, field Message is empty")
	Notification("Unable to send SMS, field Message is empty", {"push", "email"})
end

 

Code Bouton MMS v3

 

---------------------------------------------------------------------
-- Module permettant d'envoyer des SMS/MMS par l'intermédiaire de JPI
-- Nom	   : JPI Gateway
-- Author  : ADN182 / Lazer 
-- Date    : 18-02-2018 / 10-12-2018
-- History : v3.0
-- Thanks  : All Members of www.domotique-fibaro.fr forum
---------------------------------------------------------------------

-- Examples :
-- Send a MMS to a specific contact Lazer (must present in Contacts) and to number 0606060606
-- fibaro:setGlobal("MMS", '{"Image":"http://user:pass@www.doorbird.com/bha-api/image.cgi", "Message":"Doorbird", "SendTo":["0606060606", "Lazer"]}')
-- fibaro:setGlobal("MMS", '"Image":"http://user:pass@www.doorbird.com/bha-api/image.cgi", "Message":"Doorbird", "SendTo":["0606060606", "ADN182"]')
																 

-- Send a MMS to All contact of DefaultContact Variable
-- fibaro:setGlobal("MMS", '{"Image":"Cam_Salon"}')
-- fibaro:setGlobal("MMS", '"Image":"Cam_Salon"')
-- fibaro:setGlobal("MMS", "DoorBird")


-- User configurable variables
local Contacts = {
	{Name="ADN182", number="0707070707"},
	{Name="Lazer", number="0606060606"}								 
}
local userID = {       -- Email User ID if MMS not Sent
	2,
	"Lazer",
}
local smartphoneID = {  -- Push Smartphone ID if MMS not Sent
	600,
	"Google Pixel 2 XL",
}	 
local retry_max = 3;  -- Number of Retry if sent MMS failed
local retry_sleep = 10; -- Sleep in second between each retry

-- System variables
local selfID = fibaro:getSelfId()
local ip = fibaro:get(selfID, 'IPAddress')
local port = fibaro:get(selfID, 'TCPPort')


--
-- Message() function
--
local function Message(color, text)
	if color and color ~= "" then
		fibaro:debug('<span style="color:'..color..';">'..(text or "<i>nil</i>")..'</span>')
	else
		fibaro:debug(text or "<i>nil</i>")
	end
end

--
-- updateLabel() function
--
local function updateLabel(label, value)
	if fibaro:get(selfID, "ui."..label..".value") ~= value then
		if debug then
			Message("", "Update label : ui." .. label .. ".value => " .. (value or ""))
		end
		fibaro:call(selfID, "setProperty", "ui."..label..".value", value or "")
	end
end

--
-- Notification() function
--
local function Notification(message, param)
	local message = message or "<vide>"
	Message("yellow", "Notification : "..message)
	if param then
		local notif
		for _, notif in ipairs(param) do
			if debug then
				Message("", notif)
			end
			-- Envoi Push
			if notif == "push" and type(smartphoneID) == "table" then
				local id
				for _, id in ipairs(smartphoneID) do
					if type(id) == "number" then
						if debug then
							Message("", "Send Push smartphone ID : " .. tostring(id))
						end
						fibaro:call(id, "sendPush", message)
					elseif type(id) == "string" then
						local response = api.get("/iosDevices")
						if type(response) == "table" then
							local smartphone
							for _, smartphone in ipairs(response) do
								if smartphone.id and smartphone.name and smartphone.name == id then
									if debug then
										Message("", "Send Push smartphone ID : " .. tostring(smartphone.id))
									end
									fibaro:call(smartphone.id, "sendPush", message)
								end
							end
						else
							Message("red", "Error : can't get smartphones API")
						end
					else
						Message("red", 'Error : invalid smartphoneID type "' .. type(id) .. '"')
					end
				end
			-- Envoi Email
			elseif notif == "email" and type(userID) == "table" then
				local id
				for _, id in ipairs(userID) do
					if type(id) == "number" then
						if debug then
							Message("", "Send Email user ID : " .. tostring(id))
						end
						fibaro:call(id, "sendEmail", "JPI SMS Gateway", message)
					elseif type(id) == "string" then
						local response = api.get("/users")
						if type(response) == "table" then
							local user
							for _, user in ipairs(response) do
								if user.id and user.name and user.name == id then
									if debug then
										Message("", "Send Email user ID : " .. tostring(user.id))
									end
									fibaro:call(user.id, "sendEmail", "JPI SMS Gateway", message)
								end
							end
						else
							Message("red", "Error : can't get users API")
						end
					else
						Message("red", 'Error : invalid userID type "' .. type(id) .. '"')
					end
				end
			end
		end
	else
		Message("orange", "Warning : no notification options given")
	end
end

--
-- Create Variable function
--
local function createGlobalIfNotExists(varName, defaultValue)
	if varName and fibaro:getGlobal(varName) == nil then
		Message("blue", "Création de la variable "..varName)
		newVar = {}
		newVar.name = varName
		newVar.value = defaultValue or ""
		local HC2 = Net.FHttp("127.0.0.1", 11111)
		HC2:POST("/api/globalVariables", json.encode(newVar))
		HC2 = nil
	end
end

  
-- URL Encode function
  
local function urlencode(str)
	if str then
		str = string.gsub (str, "\n", "\r\n")
		str = string.gsub (str, "([^%w %-%_%.%~])", function (c) return string.format ("%%%02X", string.byte(c)) end)
		str = string.gsub (str, " ", "+")
	end
	return str	
end

  
local function CamToUrl(name)
	local HC2 = Net.FHttp("127.0.0.1", 11111)
	i = 0;
	response, status, errorCode = HC2:GET("/api/devices")
	if tonumber(errorCode) == 0 and tonumber(status) == 200 and response ~= nil and response ~= "" then
		jsonTable = json.decode(response)
		for j = 1, #jsonTable do
			if jsonTable[j].baseType == "com.fibaro.camera" or jsonTable[j].baseType == "com.fibaro.ipCamera" then
				if name == jsonTable[j].name then
					i = 1;
					url1 = "http://".. jsonTable[j].properties.username..":"..jsonTable[j].properties.password.."@"..jsonTable[j].properties.ip.."/"..jsonTable[j].properties.jpgPath
					break;
				end
			end
		end
		if i == 0 then
			Message("red", "Erreur Cam : "..name.." Inconnu")
			return nil;
		else
			Message("green", "Camera "..name.." trouvé")
			return url1
		end
	end
	HC2 = nil;
end

-- SendMMS function
local function SendMMS(message,number,url)
	updateLabel("LabelStatus", "...")
	updateLabel("LabelMessage", message)
	updateLabel("LabelDate", os.date("%d/%m/%Y %H:%M:%S"))
	local erreur = 0
	local server = Net.FHttp(ip, tonumber(port))
	local payload = "/?action=sendMms&number="..number.."&message="..urlencode(tostring(message or "empty")).."&imagePath="..urlencode(tostring(url or "empty"))
  for i=1, retry_max do
      response, status, errorCode = server:GET(payload)
      if tonumber(errorCode) == 0 and tonumber(status) == 200 then
      	if (response ~= nil) then
              if tostring(response):match("OK") then
                  Message("green", response)
                  updateLabel("LabelStatus", "OK - MMS sent")
                  fibaro:log("MMS envoyé")
                  erreur = 0
                  break
              else
                  Message("red", "Error : incorrect response")
                  Message("red", "status="..status..", errorCode="..errorCode..", response="..response)
                  erreur = erreur + 1
              end
          else
              Message("red", "Error : empty response")
              Message("red", "status="..status..", errorCode="..errorCode)
              erreur = erreur + 1
          end
      else
          Message("red", "Error !")
		  Message("red;", "status="..status..", errorCode="..errorCode..", response="..(response or "<i>nil</i>"))
          erreur = erreur + 1
      end
      fibaro:sleep(retry_sleep*1000)
  end

  -- Error management
  if erreur > 0 then
      updateLabel("LabelStatus", "Error - MMS not sent")
      fibaro:log("Error")
      Message("red", "Unable to send the message, MMS Gateway was unavailable !")
	  Notification("Erreur lors de l'envoi du MMS : "..message, {"push", "email"})
						   
  end
end


  
-- Main
  

Message("", os.date("%d/%m/%Y"))								

-- Create Variable if not exist
createGlobalIfNotExists("MMS", "")

				  
local data = fibaro:getGlobalValue("MMS")

-- Reset global variable value
fibaro:setGlobal("MMS", "")

-- Prepare data			   
if not string.find(data, '"\s*:\s*"') then 
 data = '{"Image":"'..data..'"}'
end

if string.find(data, "{") ~= 1 then
	data = '{'..data..'}'
end

local status, data = pcall(function() return json.decode(data) end)

if data.Image then
	if string.find(data.Image, "http") then
		Message("white", "URL : "..data.Image)
	else
		if not data.Message then data.Message = data.Image end
		Message("white", "Recherche de la Camara "..data.Image.." dans la HC2")
		data.Image = CamToUrl(data.Image)
	end
	if not data.Message then data.Message = "" end
	if data.Image then
		local numbers = {};
		if data.SendTo then
			local j
			for j = #data.SendTo, 1, -1 do
				local ContactnotFound = 1
				Message("yellow", "Try to send the Image '" ..data.Image.. "' to "..data.SendTo[j])
				-- Envoi vers un numéro spécifique
				if data.SendTo[j]:match("%d%d%d%d%d%d%d%d%d%d") then
					Message("white", "Send message : "..data.Message)
					Message("white", "To number : "..data.SendTo[j])
					table.insert(numbers, data.SendTo[j]);
					ContactnotFound = 0
				else
				-- Envoi vers un contact spécifique présent dans la variable Contacts
					local i
					for i = #Contacts, 1, -1 do
						if Contacts[i].Name == data.SendTo[j] then
							Message("white", "Send message : "..data.Message)
							Message("white", "To : "..Contacts[i].Name)												  
							table.insert(numbers, Contacts[i].number);									 
							ContactnotFound = 0
						end
					end
			end
			  if ContactnotFound == 1 then
				Message("red", "Contact "..data.SendTo[j].." not found in Param !")
				Notification("Contact "..data.SendTo[j].." not found", {"push", "email"})
			  end
			end
		else
		  -- Envoi vers l'ensemble des numéros
			local i
			for i = #Contacts, 1, -1 do
				Message("yellow", "Try to send Image '" ..data.Image.. "' to "..Contacts[i].Name)
			    table.insert(numbers, Contacts[i].number);
			end
		end
		SendMMS(data.Message,table.concat(numbers, ";"), data.Image)
	end
else
	Message("red", "Unable to send MMS, field Image is Empty")
	Notification("Unable to send MMS, field Image is empty", {"push", "email"})
end

 

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

×