hi, is it possible to use domoticz to make a call when a switch is on?
i would like to configure my home alarm to call me if there is some issue.
is it possible to do that?
thanks
call mobile number
Moderator: leecollings
-
megamarco83
- Posts: 109
- Joined: Friday 21 September 2018 15:07
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
- waaren
- Posts: 6028
- Joined: Tuesday 03 January 2017 14:18
- Target OS: Linux
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: call mobile number
hi @Marco, Yes is possible. (and probably in more than one way)megamarco83 wrote: Wednesday 17 April 2019 15:19 hi, is it possible to use domoticz to make a call when a switch is on?
i would like to configure my home alarm to call me if there is some issue.
is it possible to do that?
thanks
My method: using dzVents domoticz.triggerIFTTT (available in dzVents >= 2.4.18 = domoticz >= 4.10603)
to a maker event in IFTTT connected to woopla.
woopla can make calls in your native language (Italian available) but is not a free service.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
-
DutchHans
- Posts: 230
- Joined: Friday 03 April 2015 20:44
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Location: Germany (near dutch border)
- Contact:
Re: call mobile number
Yes it is... I have it working...
I have changed the code from Binerry.de
Take a look there... In my case the text is formatted, send to google.. a mp3 is returned...a sip call is initiated and the mp3 is played..
Cheers, Hans
I have changed the code from Binerry.de
Take a look there... In my case the text is formatted, send to google.. a mp3 is returned...a sip call is initiated and the mp3 is played..
Cheers, Hans
-
megamarco83
- Posts: 109
- Joined: Friday 21 September 2018 15:07
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: call mobile number
hi thanks both for the answers.
@Hans could you please share the code that you modify from binerry.de?
thanks
@Hans could you please share the code that you modify from binerry.de?
thanks
-
DutchHans
- Posts: 230
- Joined: Friday 03 April 2015 20:44
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Location: Germany (near dutch border)
- Contact:
Re: call mobile number
Sure.. I am not near my server but I will asap.
Cheers, Hans
Cheers, Hans
-
DutchHans
- Posts: 230
- Joined: Friday 03 April 2015 20:44
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Location: Germany (near dutch border)
- Contact:
Re: call mobile number
My modified sipcall.c file
My simple LUA file:
Hope this helps,
Cheers, Hans
Code: Select all
/*
=================================================================================
Name : sipcall.c
Version : 0.1 alpha
Copyright (C) 2012 by Andre Wussow, 2012, [email protected]
Description :
Tool for making automated calls over SIP/VOIP with PJSUA library and eSpeak.
Dependencies:
- PJSUA API (PJSIP)
- eSpeak
References :
http://www.pjsip.org/
http://www.pjsip.org/docs/latest/pjsip/docs/html/group__PJSUA__LIB.htm
http://espeak.sourceforge.net/
http://binerry.de/post/29180946733/raspberry-pi-caller-and-answering-machine
================================================================================
This tool is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This tool is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
================================================================================
*/
// definition of endianess (e.g. needed on raspberry pi)
#define PJ_IS_LITTLE_ENDIAN 1
#define PJ_IS_BIG_ENDIAN 0
// includes
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pjsua-lib/pjsua.h>
// some espeak options
#define ESPEAK_LANGUAGE "en"
#define ESPEAK_AMPLITUDE 100
#define ESPEAK_CAPITALS_PITCH 20
#define ESPEAK_SPEED 150
#define ESPEAK_PITCH 75
// disable pjsua logging
#define PJSUA_LOG_LEVEL 0
// struct for app configuration settings
struct app_config {
char *sip_domain;
char *sip_user;
char *sip_password;
char *phone_number;
char *tts;
char *tts_file;
int record_call;
char *record_file;
int repetition_limit;
int silent_mode;
} app_cfg;
// global helper vars
int call_confirmed = 0;
int media_counter = 0;
int app_exiting = 0;
// global vars for pjsua
pjsua_acc_id acc_id;
pjsua_player_id play_id = PJSUA_INVALID_ID;
pjmedia_port *play_port;
pjsua_recorder_id rec_id = PJSUA_INVALID_ID;
// header for new functions
static void default_configs(void);
void verify_arguments(int argc);
static void handle_help_request(const char* arg);
int check_sip_argument(int arg, int argc, char *argv[]);
int check_call_options(int arg, int argc, char *argv[]);
static void parse_arguments(int argc, char *argv[]);
// header of helper-methods
static void create_player(pjsua_call_id);
static void create_recorder(pjsua_call_info);
static void log_message(char *);
static void make_sip_call();
static void register_sip(void);
static void setup_sip(void);
//static void synthesize_speech(char *);
static void tts_google(char *);
static void usage(int);
static int try_get_argument(int, char *, char **, int, char *[]);
// header of callback-methods
static void on_call_media_state(pjsua_call_id);
static void on_call_state(pjsua_call_id, pjsip_event *);
static pj_status_t on_media_finished(pjmedia_port *, void *);
static void signal_handler(int);
// header of app-control-methods
static void app_exit();
static void error_exit(const char *, pj_status_t);
// main application
int main(int argc, char *argv[])
{
// first set some default values
default_configs();
// verify number of arguments
verify_arguments(argc);
// parse arguments
parse_arguments(argc, argv);
if (!app_cfg.sip_domain || !app_cfg.sip_user || !app_cfg.sip_password || !app_cfg.phone_number || !app_cfg.tts)
{
// too few arguments specified - display usage info and exit app
usage(1);
exit(1);
}
// print infos
log_message("SIP Call - Simple TTS-based Automated Calls\n");
log_message("===========================================\n");
// register signal handler for break-in-keys (e.g. ctrl+c)
signal(SIGINT, signal_handler);
signal(SIGKILL, signal_handler);
// synthesize speech
//synthesize_speech(app_cfg.tts_file);
tts_google(app_cfg.tts_file);
// setup up sip library pjsua
setup_sip();
// create account and register to sip server
register_sip();
// initiate call
make_sip_call();
// app loop
for (;;) { }
// exit app
app_exit();
return 0;
}
// helper for displaying usage infos
static void usage(int error)
{
if (error == 1)
{
puts("Error, to few arguments.");
puts ("");
}
puts ("Usage:");
puts (" sipcall [options]");
puts ("");
puts ("Mandatory options:");
puts (" -sd=string Set sip provider domain.");
puts (" -su=string Set sip username.");
puts (" -sp=string Set sip password.");
puts (" -pn=string Set target phone number to call");
puts (" -tts=string Text to speak");
puts ("");
puts ("Optional options:");
puts (" -ttsf=string TTS speech file name to save text");
puts (" -rcf=string Record call file name to save answer");
puts (" -mr=int Repeat message x-times");
puts (" -s=int Silent mode (hide info messages) (0/1)");
puts ("");
fflush(stdout);
}
// helper for parsing command-line-argument
static int try_get_argument(int arg, char *arg_id, char **arg_val, int argc, char *argv[])
{
int found = 0;
// check if actual argument is searched argument
if (!strcasecmp(argv[arg], arg_id))
{
// check if actual argument has a value
if (argc >= (arg+1))
{
// set value
*arg_val = argv[arg+1];
found = 1;
}
}
return found;
}
// helper for logging messages to console (disabled if silent mode is active)
static void log_message(char *message)
{
if (!app_cfg.silent_mode)
{
fprintf(stderr, message);
}
}
// helper for setting up sip library pjsua
static void setup_sip(void)
{
pj_status_t status;
log_message("Setting up pjsua ... ");
// create pjsua
status = pjsua_create();
if (status != PJ_SUCCESS) error_exit("Error in pjsua_create()", status);
// configure pjsua
pjsua_config cfg;
pjsua_config_default(&cfg);
// enable just 1 simultaneous call
cfg.max_calls = 1;
// callback configuration
cfg.cb.on_call_media_state = &on_call_media_state;
cfg.cb.on_call_state = &on_call_state;
// logging configuration
pjsua_logging_config log_cfg;
pjsua_logging_config_default(&log_cfg);
log_cfg.console_level = PJSUA_LOG_LEVEL;
// initialize pjsua
status = pjsua_init(&cfg, &log_cfg, NULL);
if (status != PJ_SUCCESS) error_exit("Error in pjsua_init()", status);
// add udp transport
pjsua_transport_config udpcfg;
pjsua_transport_config_default(&udpcfg);
udpcfg.port = 5060;
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &udpcfg, NULL);
if (status != PJ_SUCCESS) error_exit("Error creating transport", status);
// initialization is done, start pjsua
status = pjsua_start();
if (status != PJ_SUCCESS) error_exit("Error starting pjsua", status);
// disable sound - use null sound device
status = pjsua_set_null_snd_dev();
if (status != PJ_SUCCESS) error_exit("Error disabling audio", status);
log_message("Done.\n");
}
// helper for creating and registering sip-account
static void register_sip(void)
{
pj_status_t status;
log_message("Registering account ... ");
// prepare account configuration
pjsua_acc_config cfg;
pjsua_acc_config_default(&cfg);
// build sip-user-url
char sip_user_url[40];
sprintf(sip_user_url, "sip:%s@%s", app_cfg.sip_user, app_cfg.sip_domain);
// build sip-provder-url
char sip_provider_url[40];
sprintf(sip_provider_url, "sip:%s", app_cfg.sip_domain);
// create and define account
cfg.id = pj_str(sip_user_url);
cfg.reg_uri = pj_str(sip_provider_url);
cfg.cred_count = 1;
cfg.cred_info[0].realm = pj_str(app_cfg.sip_domain);
cfg.cred_info[0].scheme = pj_str("digest");
cfg.cred_info[0].username = pj_str(app_cfg.sip_user);
cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
cfg.cred_info[0].data = pj_str(app_cfg.sip_password);
// add account
status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
if (status != PJ_SUCCESS) error_exit("Error adding account", status);
log_message("Done.\n");
}
// helper for making calls over sip-account
static void make_sip_call()
{
pj_status_t status;
log_message("Starting call ... ");
// build target sip-url
char sip_target_url[40];
sprintf(sip_target_url, "sip:%s@%s", app_cfg.phone_number, app_cfg.sip_domain);
// start call with sip-url
pj_str_t uri = pj_str(sip_target_url);
status = pjsua_call_make_call(acc_id, &uri, 0, NULL, NULL, NULL);
if (status != PJ_SUCCESS) error_exit("Error making call", status);
log_message("Done.\n");
}
// helper for creating call-media-player
static void create_player(pjsua_call_id call_id)
{
// get call infos
pjsua_call_info ci;
pjsua_call_get_info(call_id, &ci);
pj_str_t name;
pj_status_t status = PJ_ENOTFOUND;
log_message("Creating player ... ");
// create player for playback media
status = pjsua_player_create(pj_cstr(&name, app_cfg.tts_file), 0, &play_id);
if (status != PJ_SUCCESS) error_exit("Error playing sound-playback", status);
// connect active call to media player
pjsua_conf_connect(pjsua_player_get_conf_port(play_id), ci.conf_slot);
// get media port (play_port) from play_id
status = pjsua_player_get_port(play_id, &play_port);
if (status != PJ_SUCCESS) error_exit("Error getting sound player port", status);
// register media finished callback
status = pjmedia_wav_player_set_eof_cb(play_port, NULL, &on_media_finished);
if (status != PJ_SUCCESS) error_exit("Error adding sound-playback callback", status);
log_message("Done.\n");
}
// helper for creating call-recorder
static void create_recorder(pjsua_call_info ci)
{
// specify target file
pj_str_t rec_file = pj_str(app_cfg.record_file);
pj_status_t status = PJ_ENOTFOUND;
log_message("Creating recorder ... ");
// Create recorder for call
status = pjsua_recorder_create(&rec_file, 0, NULL, 0, 0, &rec_id);
if (status != PJ_SUCCESS) error_exit("Error recording answer", status);
// connect active call to call recorder
pjsua_conf_port_id rec_port = pjsua_recorder_get_conf_port(rec_id);
pjsua_conf_connect(ci.conf_slot, rec_port);
log_message("Done.\n");
}
// synthesize speech / create message via espeak
/*static void synthesize_speech(char *file)
{
log_message("Synthesizing speech ... ");
int speech_status = -1;
char speech_command[200];
sprintf(speech_command, "espeak -v%s -a%i -k%i -s%i -p%i -w %s '%s'", ESPEAK_LANGUAGE, ESPEAK_AMPLITUDE, ESPEAK_CAPITALS_PITCH, ESPEAK_SPEED, ESPEAK_PITCH, file, app_cfg.tts);
speech_status = system(speech_command);
if (speech_status != 0) error_exit("Error while creating phone text", speech_status);
log_message("Done.\n");
}
*/
static void tts_google(char *file)
{
log_message("Google TTS ... ");
int speech_status = -1;
char wget_command[200];
sprintf(wget_command, "wget -q -U Mozilla -O wget.mp3 \"https://translate.google.com/translate_tts?ie=UTF-8&tl=en&client=tw-ob&q=%s\"", app_cfg.tts);
speech_status = system(wget_command);
if (speech_status != 0) error_exit("Error in Google TTS API", speech_status);
char sox_command[200];
sprintf(sox_command, "sox wget.mp3 -r 22050 -b 16 -c 1 %s", file);
speech_status = system(sox_command);
if (speech_status != 0) error_exit("Error while converting mp3 to wav", speech_status);
log_message("Done.\n");
}
// handler for call-media-state-change-events
static void on_call_media_state(pjsua_call_id call_id)
{
// get call infos
pjsua_call_info ci;
pjsua_call_get_info(call_id, &ci);
pj_status_t status = PJ_ENOTFOUND;
// check state if call is established/active
if (ci.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
log_message("Call media activated.\n");
// create and start media player
create_player(call_id);
// create and start call recorder
if (app_cfg.record_call)
{
create_recorder(ci);
}
}
}
// handler for call-state-change-events
static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
{
// get call infos
pjsua_call_info ci;
pjsua_call_get_info(call_id, &ci);
// prevent warning about unused argument e
PJ_UNUSED_ARG(e);
// check call state
if (ci.state == PJSIP_INV_STATE_CONFIRMED)
{
log_message("Call confirmed.\n");
call_confirmed = 1;
// ensure that message is played from start
if (play_id != PJSUA_INVALID_ID)
{
pjmedia_wav_player_port_set_pos(play_port, 0);
}
}
if (ci.state == PJSIP_INV_STATE_DISCONNECTED)
{
log_message("Call disconnected.\n");
// exit app if call is finished/disconnected
app_exit();
}
}
// handler for media-finished-events
static pj_status_t on_media_finished(pjmedia_port *media_port, void *user_data)
{
PJ_UNUSED_ARG(media_port);
PJ_UNUSED_ARG(user_data);
if (call_confirmed)
{
// count repetition
media_counter++;
// exit app if repetition limit is reached
if (app_cfg.repetition_limit <= media_counter)
{
app_exit();
}
}
pj_status_t status;
return status;
}
// handler for "break-in-key"-events (e.g. ctrl+c)
static void signal_handler(int signal)
{
// exit app
app_exit();
}
// clean application exit
static void app_exit()
{
if (!app_exiting)
{
app_exiting = 1;
log_message("Stopping application ... ");
// check if player/recorder is active and stop them
if (play_id != -1) pjsua_player_destroy(play_id);
if (rec_id != -1) pjsua_recorder_destroy(rec_id);
// hangup open calls and stop pjsua
pjsua_call_hangup_all();
pjsua_destroy();
log_message("Done.\n");
exit(0);
}
}
// display error and exit application
static void error_exit(const char *title, pj_status_t status)
{
if (!app_exiting)
{
app_exiting = 1;
pjsua_perror("SIP Call", title, status);
// check if player/recorder is active and stop them
if (play_id != -1) pjsua_player_destroy(play_id);
if (rec_id != -1) pjsua_recorder_destroy(rec_id);
// hangup open calls and stop pjsua
pjsua_call_hangup_all();
pjsua_destroy();
exit(1);
}
}
// sets default values for app_cfg
static void default_configs(void)
{
app_cfg.tts_file = "play.wav";
app_cfg.record_call = 0;
app_cfg.repetition_limit = 3;
app_cfg.silent_mode = 0;
}
void verify_arguments(int argc)
{
if (argc == 1)
{
// no arguments specified - display usage info and exit app
usage(1);
exit(1);
}
}
// parse and handle arguments
static void parse_arguments(int argc, char *argv[])
{
int arg;
for( arg = 1; arg < argc; arg+=2 )
{
// check if usage info needs to be displayed
handle_help_request(argv[arg]);
// check for sip domain, user or password
if (check_sip_argument(arg, argc, argv) == 1)
{
continue;
}
// check for target phone number
if (try_get_argument(arg, "-pn", &app_cfg.phone_number, argc, argv) == 1)
{
continue;
}
// check for text to speak, record call option, message repetition option, and silent mode option
if (check_call_options(arg, argc, argv) == 1)
{
continue;
}
}
}
// if usage info is needed, provides it and exits
static void handle_help_request(const char *arg)
{
if (!strcasecmp(arg, "--help"))
{
// display usage info and exit app
usage(0);
exit(0);
}
}
int check_sip_argument(int arg, int argc, char *argv[])
{
// check for sip domain
if (try_get_argument(arg, "-sd", &app_cfg.sip_domain, argc, argv) == 1)
{
return 1;
}
// check for sip user
if (try_get_argument(arg, "-su", &app_cfg.sip_user, argc, argv) == 1)
{
return 1;
}
// check for sip password
if (try_get_argument(arg, "-sp", &app_cfg.sip_password, argc, argv) == 1)
{
return 1;
}
return 0;
}
int check_call_options(int arg, int argc, char *argv[])
{
// check for text to speak
if (try_get_argument(arg, "-tts", &app_cfg.tts, argc, argv) == 1)
{
return 1;
}
// check for record call option
if (try_get_argument(arg, "-ttsf", &app_cfg.tts_file, argc, argv) == 1)
{
return 1;
}
// check for record call option
if (try_get_argument(arg, "-rcf", &app_cfg.record_file, argc, argv) == 1)
{
app_cfg.record_call = 1;
return 1;
}
// check for message repetition option
char *mr;
if (try_get_argument(arg, "-mr", &mr, argc, argv) == 1)
{
app_cfg.repetition_limit = atoi(mr);
return 1;
}
// check for silent mode option
char *s;
try_get_argument(arg, "-s", &s, argc, argv);
if (!strcasecmp(s, "1"))
{
app_cfg.silent_mode = 1;
return 1;
}
}
Code: Select all
commandArray = {}
receiver = "004912345678"
if devicechanged['CallSwitch'] == 'On' then
Message='This is the home automationsystem from Hans in Germany. Smokedetector has been activated!'
Message = string.gsub(Message, " ", "%%20")
os.execute('(sudo /home/pi/domoticz/scripts/SIP-Pi/sipcall -sd sip.yoursipprovider.nl -su xxxxxx -sp xxxxxx -pn '..receiver..' -tts "'..Message..'"> /dev/null)&')
commandArray['CallSwitch']='Off'
end
return commandArrayCheers, Hans
Who is online
Users browsing this forum: No registered users and 1 guest