¿cuanta gente a visto el blog?

EXPANSION DE LA CENTRAL TELEFONICA

Verificar estado de Asterist

sudo asterisk -rvvv




crear mas usuarios

 sudo nano /etc/asterisk/pjsip.conf


[transport-udp]
type=transport
protocol=udp    ;udp,tcp,tls,ws,wss,flow
bind=0.0.0.0
[1001]
type=endpoint
transport=transport-udp
context=default
disallow=all
allow=ulaw
auth=auth1001
aors=1001
message_context = messages

[auth1001]
type=auth
auth_type=userpass
password=admin
username=1001

[1001]
type=aor
max_contacts=1

[1002]
type=endpoint
transport=transport-udp
context=default
disallow=all
allow=ulaw
auth=auth1002
aors=1002
message_context = messages

[auth1002]
type=auth
auth_type=userpass
username=1002
password=admin

[1002]
type=aor
max_contacts=1

[1003]
type=endpoint
transport=transport-udp
context=default
disallow=all
allow=ulaw
auth=auth1003
aors=1003
message_context = messages

[auth1003]
type=auth
auth_type=userpass
username=1003
password=admin

[1003]
type=aor
max_contacts=1


[2000]
type=endpoint
transport=transport-udp
context=default
disallow=all
allow=ulaw
auth=auth2000
aors=2000

[auth2000]
type=auth
auth_type=userpass
username=2000
password=admin

[2000]
type=aor
max_contacts=1

[2001]
type=endpoint
transport=transport-udp
context=default
disallow=all
allow=ulaw
auth=auth2001
aors=2001
message_context = messages
[auth2001]
type=auth
auth_type=userpass
username=2001
password=admin

[2001]
type=aor
max_contacts=1

[2002]
type=endpoint
context=default
transport=transport-udp
disallow=all
allow=ulaw
auth=auth2002
aors=2002
message_context = messages
[auth2002]
type=auth
auth_type=userpass
username=2002
password=admin

[2002]
type=aor
max_contacts=1

[2003]
type=endpoint
transport=transport-udp
context=default
disallow=all
allow=ulaw
auth=auth2003
aors=2003
message_context = messages
[auth2003]
type=auth
auth_type=userpass
username=2003
password=admin

[2003]
type=aor
max_contacts=1
[message]
type=service
outbound_transport=transport-udp


[3001]
type=endpoint
context=default
disallow=all
allow=ulaw
auth=3001_auth
aors=3001

[3001_auth]
type=auth
auth_type=userpass
username=3001
password=admin
[3001_aor]
type=aor
max_contacts=1


sudo asterisk -rx "pjsip reload"
sudo asterisk -rx "dialplan reload"

sudo asterisk -rx "pjsip show endpoints"

probar llamada


au

http://10.10.10.138/phpmyadmin/

añadir mensajeria


sudo nano /etc/asterisk/pjsip.conf

[1001]
type = endpoint
context = default
transport = transport-udp
auth = auth1001
aors = 1001
message_context = messages

 


sudo nano /etc/asterisk/extensions.conf

[messages]
exten => _X.,1,NoOp(Recibiendo mensaje para: ${EXTEN})
same => n,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,NoOp(Estado del envío: ${MESSAGE_SEND_STATUS})
same => n,Hangup()



sudo asterisk -rx "dialplan reload"
sudo asterisk -rx "pjsip reload"
 




[default]
exten => 1001,1,Dial(PJSIP/1001)
exten => 1001,n,Hangup()

exten => 1002,1,Dial(PJSIP/1002)
exten => 1002,n,Hangup()

exten => 1003,1,Dial(PJSIP/1003)
exten => 1003,n,Hangup()

exten => 2001,1,Dial(PJSIP/2001)
exten => 2001,n,Hangup()

exten => 2002,1,Dial(PJSIP/2002)
exten => 2002,n,Hangup()

exten => 2003,1,Dial(PJSIP/2003)
exten => 2003,n,Hangup()

exten => 2000,1,Dial(PJSIP/1000)
exten => 2002,n,Hangup()
sudo asterisk -rx "dialplan reload"
sudo asterisk -rx "pjsip reload"

 crear la base de datos cdop

mysql -u root -p

CREATE DATABASE cdop;

USE cdop;

CREATE TABLE sensores (
    id INT AUTO_INCREMENT PRIMARY KEY,
    luz FLOAT NOT NULL,
    temperatura FLOAT NOT NULL,
    humedad FLOAT NOT NULL,
    fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

DESCRIBE sensores;

INSERT INTO sensores (luz, temperatura, humedad) VALUES (100.5, 25.2, 60.8);

SELECT * FROM sensores;
http://10.10.10.138/phpmyadmin

mensaje personal por llamada 

sudo nano /etc/asterisk/extensions.conf

[play_audio]
exten => play_audio,1,Answer()                ; Responde la llamada
exten => play_audio,n,Playback(prueba)        ; Reproduce el archivo prueba.gsm
exten => play_audio,n,Hangup()                ; Cuelga la llamada

 
 
sudo nano /etc/asterisk/manager.conf

[general]
enabled = yes
port = 5038
bindaddr = 0.0.0.0

[admin]
secret = admin
read = all
write = all


sudo netstat -tuln | grep 5038
 






sudo asterisk -rx "dialplan reload"

sudo chmod 644 /var/lib/asterisk/sounds/prueba.gsm

sudo asterisk -rx "dialplan show play_audio"

DEBE VERSE: [ Context 'play_audio' created by 'extensions' ]
  'play_audio' =>   1. Answer()                              [extensions.conf:1]
                    2. Playback(prueba)                      [extensions.conf:2]
                    3. Hangup()                              [extensions.conf:3]

sudo systemctl restart asterisk

python3 play_audio_call.py


sudo asterisk -rvvv

channel originate PJSIP/1001 application Playback prueba
El Audio se reproduce correctamente 

enviar mensajes al numero

sudo nano /etc/asterisk/extensions.conf


[messages]
exten => _X.,1,NoOp(Recibiendo mensaje para: ${EXTEN})
same => n,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
same => n,NoOp(Estado del envío: ${MESSAGE_SEND_STATUS})
same => n,Hangup()


sudo nano send_message.py

import socket

# Configuración de AMI
ASTERISK_HOST = "127.0.0.1"  # Dirección IP del servidor Asterisk
ASTERISK_PORT = 5038         # Puerto de AMI
ASTERISK_USER = "admin"      # Usuario definido en manager.conf
ASTERISK_SECRET = "admin"    # Contraseña definida en manager.conf

def enviar_mensaje(destinatario, mensaje):
    try:
        # Crear conexión al AMI
        ami_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        ami_socket.connect((ASTERISK_HOST, ASTERISK_PORT))

        # Login en AMI
        ami_socket.sendall(b"Action: Login\r\n")
        ami_socket.sendall(f"Username: {ASTERISK_USER}\r\n".encode())
        ami_socket.sendall(f"Secret: {ASTERISK_SECRET}\r\n".encode())
        ami_socket.sendall(b"\r\n")

        # Esperar respuesta
        respuesta = ami_socket.recv(4096).decode()
        print(f"Respuesta del login:\n{respuesta}")

        # Enviar mensaje
        ami_socket.sendall(b"Action: MessageSend\r\n")
        ami_socket.sendall(f"To: pjsip:{destinatario}\r\n".encode())
        ami_socket.sendall(f"From: pjsip:server\r\n".encode())
        ami_socket.sendall(f"Body: {mensaje}\r\n".encode())
        ami_socket.sendall(b"\r\n")

        # Esperar respuesta
        respuesta = ami_socket.recv(4096).decode()
        print(f"Respuesta del envío:\n{respuesta}")

        # Cerrar conexión
        ami_socket.close()

    except Exception as e:
        print(f"Error al enviar el mensaje: {e}")

if __name__ == "__main__":
    enviar_mensaje("1001", "Tienes un mensaje nuevo")



chmod +x send_message.py


python3 send_message.py


pip install mysql-connector-python

Enviar datos de la base de datos

sudo yum install -y unixODBC unixODBC-devel libodbc1
sudo yum install -y mysql-connector-odbc

sudo nano /etc/asterisk/res_odbc.conf


[ivast]
dsn = ivast  ; Nombre configurado en odbc.ini
username = root
password = admin
pre-connect = yes


sudo nano /etc/asterisk/func_odbc.conf


[GET_TEMP]
dsn=ivast
readsql=SELECT valor FROM ultemp ORDER BY id DESC LIMIT 1

[GET_NUM]
dsn=ivast
readsql=SELECT numero FROM ultnum ORDER BY id DESC LIMIT 1


sudo asterisk -rx "module reload res_odbc.so"
sudo asterisk -rx "module reload func_odbc.so"


sudo asterisk -rx "odbc show"



sudo nano /etc/odbcinst.ini

sudo nano /etc/odbc.ini


[asterisk-connector]
Description=ODBC Connection for Asterisk
Driver=MySQL
Server=localhost
Database=cdop
User=root
Password=admin
Port=3306


isql -v asterisk-connector
isql -v ivast

sudo nano /etc/asterisk/extensions.conf

[send_db_message]
exten => 1001,1,NoOp(Enviando datos de la base de datos)
   same => n,Set(TEMP=${ODBC_GET_TEMP()})
   same => n,Set(NUM=${ODBC_GET_NUM()})
   same => n,Set(MESSAGE(body)=Datos del sensor: TEMP=${TEMP}, NUM=${NUM})
   same => n,Set(MESSAGE(from)=pjsip:server)
   same => n,MessageSend(pjsip:${EXTEN},${MESSAGE(from)})
   same => n,NoOp(Mensaje enviado a ${EXTEN}: TEMP=${TEMP}, NUM=${NUM})
   same => n,Hangup()


sudo asterisk -rx "dialplan reload"



sudo asterisk -rvvv

channel originate Local/1001@send_db_message application MessageSend

Enviar a otros

sudo nano /etc/asterisk/extensions.conf


[send_db_message]
exten => 1001,1,NoOp(Enviando datos de la base de datos)
   same => n,Set(TEMP=${ODBC_GET_TEMP()})
   same => n,Set(NUM=${ODBC_GET_NUM()})
   same => n,Set(MESSAGE(body)=Datos del sensor: TEMP=${TEMP}, NUM=${NUM})
   same => n,Set(MESSAGE(from)=pjsip:server)

   ; Enviar al 1001
   same => n,MessageSend(pjsip:1001,${MESSAGE(from)})
   same => n,NoOp(Mensaje enviado a 1001: TEMP=${TEMP}, NUM=${NUM})

   ; Enviar al 1002
   same => n,MessageSend(pjsip:1002,${MESSAGE(from)})
   same => n,NoOp(Mensaje enviado a 1002: TEMP=${TEMP}, NUM=${NUM})

   ; Enviar al 2003
   same => n,MessageSend(pjsip:2003,${MESSAGE(from)})
   same => n,NoOp(Mensaje enviado a 2003: TEMP=${TEMP}, NUM=${NUM})

   same => n,Hangup()

sudo asterisk -rx "dialplan reload"


channel originate Local/1001@send_db_message application MessageSend



Configurar Asterisk con AGI

 sudo nano /etc/asterisk/pjsip.conf
[1001]
type=endpoint
context=authenticated
auth=auth1001
aors=1001

[auth1001]
type=auth
auth_type=userpass
username=1001
password=admin

[aor1001]
type=aor
max_contacts=1

[1002]
type=endpoint
context=authenticated
auth=auth1002
aors=1002

[auth1002]
type=auth
auth_type=userpass
username=1002
password=admin

[aor1002]
type=aor
max_contacts=1

[2003]
type=endpoint
context=authenticated
auth=auth2003
aors=2003

[auth2003]
type=auth
auth_type=userpass
username=2003
password=admin

[aor2003]
type=aor
max_contacts=1


sudo asterisk -rx "module reload"

sudo nano /etc/asterisk/extensions.conf

[authenticated]
exten => 100,1,NoOp(Consulta del clima y control de actuadores)
   same => n,AGI(control_clima.agi)
   same => n,Hangup()
sudo asterisk -rx "dialplan reload"


sudo nano /var/lib/asterisk/agi-bin/control_clima.agi

#!/usr/bin/env python3
import mysql.connector
import sys

def obtener_datos_climaticos():
    """Consulta los datos más recientes de la base de datos."""
    try:
        conexion = mysql.connector.connect(
            host="localhost",
            user="root",
            password="admin",
            database="ivast"
        )
        cursor = conexion.cursor(dictionary=True)
        cursor.execute("SELECT luz, temperatura, viento FROM ultemp ORDER BY id DESC LIMIT 1")
        resultado = cursor.fetchone()
        conexion.close()
        return resultado
    except Exception as e:
        print(f"VERBOSE Error al consultar la base de datos: {e}")
        return None

def enviar_comando_actuador(comando):
    """Simula el envío de un comando a la ESP32."""
    print(f"VERBOSE Enviando comando al actuador: {comando}")

def main():
    print("Content-type: text/plain\n")
    print("VERBOSE Iniciando script AGI de control climático")

    datos = obtener_datos_climaticos()
    if datos:
        luz = datos["luz"]
        temperatura = datos["temperatura"]
        viento = datos["viento"]

        print(f"VERBOSE Datos actuales - Luz: {luz}, Temperatura: {temperatura}, Viento: {viento}")

        if viento > 50:
            enviar_comando_actuador("cerrar_toldo")
            print("VERBOSE Actuador cerrado por viento fuerte")
        elif luz < 300 and temperatura > 30:
            enviar_comando_actuador("abrir_toldo")
            print("VERBOSE Actuador abierto por alta temperatura y poca luz")
        else:
            print("VERBOSE No se requiere acción en los actuadores")
    else:
        print("VERBOSE No se pudieron obtener datos del clima")

if __name__ == "__main__":
    main()
USE ivast;
ADD luz FLOAT NOT NULL,
ADD temperatura FLOAT NOT NULL,
ADD viento FLOAT NOT NULL,
ADD fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP;

sudo asterisk -rx "dialplan reload"

sudo nano /var/lib/asterisk/agi-bin/consulta_datos.agi


#!/usr/bin/env python3
import mysql.connector
import sys

def obtener_datos():
    """Consulta los datos más recientes de la tabla ultnum."""
    try:
        conexion = mysql.connector.connect(
            host="localhost",
            user="root",
            password="admin",
            database="ivast"
        )
        cursor = conexion.cursor(dictionary=True)
        cursor.execute("SELECT luz, temperatura, viento FROM ultnum ORDER BY id DESC LIMIT 1")
        datos = cursor.fetchone()
        conexion.close()
        return datos
    except Exception as e:
        print(f"VERBOSE Error al consultar la base de datos: {e}")
        return None

def main():
    print("Content-type: text/plain\n")
    print("VERBOSE Iniciando consulta de datos desde AGI")

    datos = obtener_datos()
    if datos:
        luz = datos["luz"]
        temperatura = datos["temperatura"]
        viento = datos["viento"]

        mensaje = f"Luz: {luz}, Temperatura: {temperatura}, Viento: {viento}"
        print(f"VERBOSE {mensaje}")
        print(f"SAY PHRASE \"{mensaje}\" 0")
    else:
        print("VERBOSE No se encontraron datos en la base de datos")
        print("SAY PHRASE \"No se encontraron datos en la base de datos\" 0")

if __name__ == "__main__":
    main()



sudo chmod +x /var/lib/asterisk/agi-bin/consulta_datos.agi



pip install gtts

sudo nano mimensaje.py

from gtts import gTTS
import os

# Texto para convertir en audio
texto = "Hola, este es un mensaje generado automáticamente."

# Generar audio
tts = gTTS(text=texto, lang='es')
tts.save("mensaje.mp3")

# Reproducir audio
os.system("mpg123 mensaje.mp3")

loquendo

pip install google-cloud-texttospeech


pip install gtts

sudo dnf install mpg123
y

sudo dnf install epel-release
sudo dnf install https://download1.rpmfusion.org/free/el/rpmfusion-free-release-$(rpm -E %rhel).noarch.rpm
y

sudo dnf install ffmpeg ffmpeg-devel
y
y

ffmpeg -version

nano generate_audio.py


from gtts import gTTS
import os

# Texto a convertir en audio
texto = "Hola, este es un mensaje generado automáticamente por gTTS."

# Configuración del idioma (es = español)
tts = gTTS(text=texto, lang='es')

# Guardar el archivo en formato MP3
tts.save("mensaje.mp3")
print("Archivo MP3 generado: mensaje.mp3")

# Convertir MP3 a GSM para Asterisk
os.system("ffmpeg -i mensaje.mp3 -ar 8000 -ac 1 mensaje.gsm")
print("Archivo GSM generado: mensaje.gsm")

python3 generate_audio.py
 

sudo mv mensaje.gsm /var/lib/asterisk/sounds/


sudo nano /etc/asterisk/extensions.conf

exten => 1001,1,Answer()
   same => n,Playback(mensaje)    ; Reproduce el archivo mensaje.gsm
   same => n,Hangup()


sudo asterisk -rx "dialplan reload"
pip install SpeechRecognition

sudo dnf groupinstall "Development Tools" -y
sudo dnf install portaudio portaudio-devel -y
 

pip install SpeechRecognition

pip install gtts
sudo dnf install mpg123 -y
 sudo dnf groupinstall "Development Tools" -y
sudo dnf install python3-devel portaudio portaudio-devel -y

pip install pyaudio

python3 -m pip show pyaudio

pip install sounddevice

sudo dnf install alsa-utils

y

 

sudo pip3 install speechrecognition gtts
sudo dnf install ffmpeg sox -y

pip install openai
pip install SpeechRecognition pyaudio

pip install google-cloud-speech

sudo dnf install portaudio-devel
pip install pyaudio






export GOOGLE_APPLICATION_CREDENTIALS="/root/cdop-key.json"

nano ~/.bashrc


export GOOGLE_APPLICATION_CREDENTIALS="/root/cdop-key.json"

source ~/.bashrc


echo $GOOGLE_APPLICATION_CREDENTIALS


from google.cloud import speech

# Inicializa el cliente
client = speech.SpeechClient()

print("Conexión exitosa con Google Speech-to-Text API.")



 


pip install google-cloud-dialogflow
pip install google-cloud-dialogflow

api mate

 sudo nano /etc/asterisk/extensions.conf


[messages]
exten => 9000,1,NoOp(Recibiendo mensaje para cálculo: ${MESSAGE(body)})  ; Muestra el mensaje recibido
    same => n,System(python3 /root/process_math_message.py "${MESSAGE(body)}")  ; Procesa la expresión matemática
    same => n,MessageSend(pjsip:${MESSAGE(from)},service)  ; Envía el resultado como mensaje de texto
    same => n,Hangup()


nano /root/process_math_message.py


import requests
import sys

if len(sys.argv) < 2:
    print("No se recibió ningún mensaje.")
    sys.exit(1)

# Recibir el cuerpo del mensaje
expresion = sys.argv[1].strip()
url = f"https://api.mathjs.org/v4/?expr={expresion}"

try:
    # Consultar la API Math.js
    response = requests.get(url)
    if response.status_code == 200:
        resultado = response.text.strip()
        respuesta = f"El resultado de '{expresion}' es: {resultado}"
        print(respuesta)

        # Guardar el resultado en un archivo temporal para Asterisk
        with open("/tmp/respuesta.txt", "w") as archivo:
            archivo.write(respuesta)
    else:
        print(f"Error en la API: {response.status_code}")
        with open("/tmp/respuesta.txt", "w") as archivo:
            archivo.write("Error procesando la expresión.")
except Exception as e:
    print(f"Error: {e}")
    with open("/tmp/respuesta.txt", "w") as archivo:
        archivo.write("Error procesando la expresión.")



sudo asterisk -rx "dialplan reload"

API de Cat Facts

sudo nano /etc/asterisk/extensions.conf


exten => 9001,1,Answer()
   same => n,System(/usr/bin/python3 /path/to/cat_facts.py)
   same => n,Playback(cat_fact)
   same => n,Hangup()


sudo asterisk -rx "dialplan reload"


nano /path/to/cat_facts.py


import requests
from gtts import gTTS
import os

# Consultar la API de Cat Facts
URL = "https://catfact.ninja/fact"
response = requests.get(URL)
data = response.json()

if "fact" in data:
    cat_fact = data["fact"]
    print(f"Dato sobre gatos: {cat_fact}")

    # Convertir el dato curioso en audio usando gTTS
    tts = gTTS(text=f"Dato curioso: {cat_fact}", lang='es')
    tts.save("/tmp/cat_fact.mp3")

    # Convertir MP3 a GSM para Asterisk
    os.system("ffmpeg -i /tmp/cat_fact.mp3 -ar 8000 -ac 1 /var/lib/asterisk/sounds/cat_fact.gsm")
else:
    print("No se pudo obtener un dato sobre gatos.")


chmod +x /path/to/cat_facts.py


pip install gtts requests



chistes en ingles


sudo nano /etc/asterisk/extensions.conf



exten => 9002,1,Answer()
   same => n,System(/usr/bin/python3 /path/to/chuck_jokes.py)
   same => n,Playback(chuck_joke)
   same => n,Hangup()


sudo asterisk -rx "dialplan reload"


nano /path/to/chuck_jokes.py


import requests
from gtts import gTTS
import os

# Consultar la API de Chuck Norris Jokes
URL = "https://api.chucknorris.io/jokes/random"
response = requests.get(URL)
data = response.json()

if "value" in data:
    joke = data["value"]
    print(f"Chiste de Chuck Norris: {joke}")

    # Convertir el chiste en audio usando gTTS
    tts = gTTS(text=f"Chiste de Chuck Norris: {joke}", lang='es')
    tts.save("/tmp/chuck_joke.mp3")

    # Convertir MP3 a GSM para Asterisk
    os.system("ffmpeg -i /tmp/chuck_joke.mp3 -ar 8000 -ac 1 /var/lib/asterisk/sounds/chuck_joke.gsm")
else:
    print("No se pudo obtener un chiste de Chuck Norris.")


chmod +x /path/to/chuck_jokes.py



pip install gtts requests

curioso

sudo nano /etc/asterisk/extensions.conf

exten => 9003,1,Answer()
   same => n,System(/usr/bin/python3 /path/to/random_facts.py)
   same => n,Playback(random_fact)
   same => n,Hangup()


sudo asterisk -rx "dialplan reload"


nano /path/to/random_facts.py


import requests
from gtts import gTTS
import os

# Consultar la API de Random Facts
URL = "https://uselessfacts.jsph.pl/random.json?language=en"
response = requests.get(URL)
data = response.json()

if "text" in data:
    fact = data["text"]
    print(f"Random Fact: {fact}")

    # Convertir el dato curioso en audio usando gTTS
    tts = gTTS(text=f"Dato curioso: {fact}", lang='es')
    tts.save("/tmp/random_fact.mp3")

    # Convertir MP3 a GSM para Asterisk
    os.system("ffmpeg -i /tmp/random_fact.mp3 -ar 8000 -ac 1 /var/lib/asterisk/sounds/random_fact.gsm")
else:
    print("No se pudo obtener un dato curioso.")
.

chmod +x /path/to/random_facts.py


pip install gtts requests


ffmpeg -version


fase 3

sudo dnf install asterisk mariadb-server unixODBC unixODBC-devel libodbc mariadb-connector-odbc -y
sudo systemctl enable --now mariadb
sudo systemctl enable --now asterisk

Autentificacion

sudo nano /etc/asterisk/pjsip.conf


; Usuario 2000
[2000]
type=endpoint
context=authenticated
disallow=all
allow=ulaw
auth=auth2000
aors=2000

[auth2000]
type=auth
auth_type=userpass
username=2000
password=admin

[2000]
type=aor
max_contacts=1

; Usuario 2001
[2001]
type=endpoint
context=authenticated
disallow=all
allow=ulaw
auth=auth2001
aors=2001

[auth2001]
type=auth
auth_type=userpass
username=2001
password=admin

[2001]
type=aor
max_contacts=1

; Usuario 2002
[2002]
type=endpoint
context=authenticated
disallow=all
allow=ulaw
auth=auth2002
aors=2002

[auth2002]
type=auth
auth_type=userpass
username=2002
password=clave2002

[2002]
type=aor
max_contacts=1

; Usuario 2003
[2003]
type=endpoint
context=authenticated
disallow=all
allow=ulaw
auth=auth2003
aors=2003

[auth2003]
type=auth
auth_type=userpass
username=2003
password=admin

[2003]
type=aor
max_contacts=1




sudo nano /etc/asterisk/extensions.conf


[authenticated]
exten => _2XXX,1,NoOp(Llamada autenticada desde ${CALLERID(num)})
   same => n,Dial(PJSIP/${EXTEN},30)
   same => n,Hangup()

exten => 9000,1,NoOp(Mensaje de autenticación)
   same => n,Playback(authenticated)
   same => n,Hangup()



sudo asterisk -rx "dialplan reload"


Autenticación con Base de Datos 

¿Qué es la autenticación en Asterisk?

En términos simples, autenticación en Asterisk significa que solo los usuarios que proporcionan un nombre de usuario y contraseña válidos pueden:

  1. Registrarse en el sistema (como un teléfono SIP).
  2. Realizar llamadas o enviar mensajes.

Esto garantiza que nadie más pueda usar tu sistema de comunicaciones sin permiso.


¿Qué configuraste?

  1. Usuarios autenticados: Configuraste usuarios SIP (2000, 2001, 2002 y 2003) en el archivo pjsip.conf. Cada uno tiene:

    • Un nombre de usuario (por ejemplo, 2000).
    • Una contraseña (por ejemplo, admin).
    • Restricciones para que solo ese usuario registrado pueda realizar o recibir llamadas

Crear las Tablas en la Base de Datos ivast

mysql -u root -p


USE ivast;

CREATE TABLE sensores (
    id INT AUTO_INCREMENT PRIMARY KEY,
    temperatura FLOAT NOT NULL,
    luz FLOAT NOT NULL,
    viento FLOAT NOT NULL,
    fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);


CREATE TABLE usuarios (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(50) NOT NULL,
    usuario VARCHAR(50) UNIQUE NOT NULL,
    clave VARCHAR(100) NOT NULL,
    nivel_acceso INT NOT NULL
);


Nivel de acceso sugerido:

  • 1: Usuario básico.
  • 2: Usuario avanzado (control de actuadores).
  • 3: Administrador. 

CREATE TABLE acciones (
    id INT AUTO_INCREMENT PRIMARY KEY,
    accion VARCHAR(255) NOT NULL,
    usuario_id INT NOT NULL,
    fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON DELETE CASCADE
);


INSERT INTO usuarios (nombre, usuario, clave, nivel_acceso)
VALUES
('Usuario1', '2000', 'admin', 1),
('Usuario2', '2001', 'admin', 2),
('Usuario3', '2002', 'admin', 2),
('Usuario4', '2003', 'admin', 3);

INSERT INTO sensores (temperatura, luz, viento)
VALUES
(25.3, 100.5, 10.2),
(24.1, 150.2, 8.5),
(30.0, 90.1, 12.3);


sudo nano /etc/asterisk/res_odbc.conf

[ivast]
enabled => yes
dsn => ivast
username => root
password => admin
pre-connect => yes


guardar datos de la bd

sudo nano /etc/asterisk/func_odbc.conf



[GET_LUZ]
dsn=ivast
readsql=SELECT luz FROM sensores ORDER BY id DESC LIMIT 1;

[GET_TEMPE]
dsn=ivast
readsql=SELECT temperatura FROM sensores ORDER BY id DESC LIMIT 1;


[GET_HUM]
dsn=ivast
readsql=SELECT vientoFROM sensores ORDER BY id DESC LIMIT 1;

[GET_USUARIO1]
dsn=ivast
readsql=SELECT id FROM usuarios ORDER BY id DESC LIMIT 1;

[GET_USUARIO2]
dsn=ivast
readsql=SELECT nombre FROM usuarios ORDER BY id DESC LIMIT 1;


[GET_USUARIO3]
dsn=ivast
readsql=SELECT usuario FROM usuarios ORDER BY id DESC LIMIT 1;


sudo asterisk -rx "module reload func_odbc.so"




sudo asterisk -rx "module reload res_odbc.so"
sudo asterisk -rx "module reload func_odbc.so"


sudo asterisk -rx "odbc show"


 sudo nano /etc/asterisk/extensions.conf


[send_dbusers_message]
exten => 1001,1,NoOp(Enviando datos de los usuarios)
   same => n,Set(USUARIO1=${ODBC_GET_USUARIO1()})
   same => n,Set(USUARIO2=${ODBC_GET_USUARIO2()})
   same => n,Set(USUARIO3=${ODBC_GET_USUARIO3()})
   same => n,Set(MESSAGE(body)=Datos de Usuarios: U1=${USUARIO1}, U2=${USUARIO2}, U3=${USUARIO3})
   same => n,Set(MESSAGE(from)=pjsip:server)
   ; Enviar mensaje al 1001
   same => n,MessageSend(pjsip:1001,${MESSAGE(from)})
   same => n,NoOp(Mensaje enviado a 1001: U1=${USUARIO1}, U2=${USUARIO2}, U3=${USUARIO3})
   same => n,Hangup()


[send_dbsens_message]
exten => _X.,1,NoOp(Enviando datos de sensores)
 same => n,Set(TEMP=${ODBC_GET_TEMPE()})
 same => n,Set(LUZ=${ODBC_GET_LUZ()})
 same => n,Set(HUM=${ODBC_GET_HUM()})
 same => n,MessageSend(pjsip:${EXTEN},pjsip:1001) ; Cambia "9000" por quien envía el mensaje
 same => n,NoOp(Mensaje enviado: Temp=${TEMP}, Luz=${LUZ}, Humedad=${HUM})
 same => n,MessageSend(pjsip:${EXTEN},pjsip:1002) ; Cambia "9000" por quien envía el mensaje
 same => n,NoOp(Mensaje enviado: Temp=${TEMP}, Luz=${LUZ}, Humedad=${HUM})
 same => n,MessageSend(pjsip:${EXTEN},pjsip:2000) ; Cambia "9000" por quien envía el mensaje
 same => n,NoOp(Mensaje enviado: Temp=${TEMP}, Luz=${LUZ}, Humedad=${HUM})
 same => n,MessageSend(pjsip:${EXTEN},pjsip:2001) ; Cambia "9000" por quien envía el mensaje
 same => n,NoOp(Mensaje enviado: Temp=${TEMP}, Luz=${LUZ}, Humedad=${HUM})
 same => n,MessageSend(pjsip:${EXTEN},pjsip:2002) ; Cambia "9000" por quien envía el mensaje
 same => n,NoOp(Mensaje enviado: Temp=${TEMP}, Luz=${LUZ}, Humedad=${HUM})
 same => n,MessageSend(pjsip:${EXTEN},pjsip:2003) ; Cambia "9000" por quien envía el mensaje
 same => n,NoOp(Mensaje enviado: Temp=${TEMP}, Luz=${LUZ}, Humedad=${HUM})
 same => n,Hangup()


sudo asterisk -rx "dialplan reload"


channel originate Local/1001@send_dbsens_message application MessageSend

channel originate Local/1001@send_dbusers_message application MessageSend

 

Crear la tabla actuadores

mysql -u root -p
USE ivast;


CREATE TABLE actuadores (
    id INT AUTO_INCREMENT PRIMARY KEY,
    control INT NOT NULL DEFAULT 0,
    estado INT NOT NULL DEFAULT 0
);

SELECT actuadores;

INSERT INTO actuadores (control, estado) VALUES (0, 0);
INSERT INTO actuadores (control, estado) VALUES (0, 0);

SELECT * FROM actuadores;

EXIT;



sudo nano /etc/asterisk/func_odbc.conf

[SET_CONTROL_ID1]
prefix=ODBC
dsn=ivast
writesql=UPDATE actuadores SET control=${ARG1} WHERE id=1

[SET_CONTROL_ID2]
prefix=ODBC
dsn=ivast
writesql=UPDATE actuadores SET control=${ARG1} WHERE id=2


sudo asterisk -rx "module reload func_odbc.so"



sudo nano /etc/asterisk/extensions.conf


[control_actuadores]
exten => id1_set0,1,NoOp(Cambiando control de ID1 a 0)
    same => n,Set(ODBC_SET_CONTROL_ID1(0))
    same => n,Hangup()

exten => id1_set1,1,NoOp(Cambiando control de ID1 a 1)
    same => n,Set(ODBC_SET_CONTROL_ID1(1))
    same => n,Hangup()

exten => id2_set0,1,NoOp(Cambiando control de ID2 a 0)
    same => n,Set(ODBC_SET_CONTROL_ID2(0))
    same => n,Hangup()

exten => id2_set1,1,NoOp(Cambiando control de ID2 a 1)
    same => n,Set(ODBC_SET_CONTROL_ID2(1))
    same => n,Hangup()


sudo asterisk -rx "dialplan reload"

pRENDER Y APAGAR EL ACTUADOR

.sudo nano /etc/asterisk/func_odbc.conf


[SET_CONTROL]
dsn=ivast
writesql=UPDATE actuadores SET control=${SQL_ESC(${ARG1})} WHERE id=1


sudo asterisk -rx "module reload res_odbc.so"
sudo asterisk -rx "module reload func_odbc.so"


sudo nano /etc/asterisk/extensions.conf


[set_control]
exten => 1,1,NoOp(Cambiando el valor de control para id=1)
   same => n,Set(ODBC_SET_CONTROL(1)=1)
   same => n,NoOp(Valor de control actualizado para id=1)
   same => n,Hangup()


sudo asterisk -rx "dialplan reload"


channel originate Local/1@set_control application Playback(beep)


mysql -u root -p -e "SELECT * FROM actuadores WHERE id=1" ivast


Prender y apagar los actuadores 

 
sudo nano /etc/asterisk/extensions.conf


 

[default] exten => 773,1,Answer() same => n,Playback(menuservo) ; Reproduce el audio del menú same => n,Goto(menu_servo,s,1) ; Entra al menú


[menu_servo]
exten => s,1,NoOp(Ingreso al menú Servo)
 same => n,Background(menuservo) ; Reproduce el audio del menú
 same => n,WaitExten(10) ; Espera 10 segundos para recibir entrada del usuario

; Opción 1: Cambiar el valor de control a 1 para id 1
exten => 1,1,NoOp(Opción 1 seleccionada: Cambiar control a 1 en id 1)
 same => n,Set(ODBC_UPDATE=${ODBC_IVAST(UPDATE actuadores SET control=1 WHERE id=1)})
 same => n,Playback(servocambio) ; Reproduce el audio del cambio
 same => n,Goto(menu_servo,s,1) ; Regresa al menú

; Opción 2: Cambiar el valor de control a 2 para id 1
exten => 2,1,NoOp(Opción 2 seleccionada: Cambiar control a 2 en id 1)
 same => n,Set(ODBC_UPDATE=${ODBC_IVAST(UPDATE actuadores SET control=2 WHERE id=1)})
 same => n,Playback(servocambio) ; Reproduce el audio del cambio
 same => n,Goto(menu_servo,s,1) ; Regresa al menú

; Opción 3: Cambiar el valor de control a 3 para id 1
exten => 3,1,NoOp(Opción 3 seleccionada: Cambiar control a 3 en id 1)
 same => n,Set(ODBC_UPDATE=${ODBC_IVAST(UPDATE actuadores SET control=3 WHERE id=1)})
 same => n,Playback(servocambio) ; Reproduce el audio del cambio
 same => n,Goto(menu_servo,s,1) ; Regresa al menú

; Opción 4: Cambiar el valor de control a 4 para id 1
exten => 4,1,NoOp(Opción 4 seleccionada: Cambiar control a 4 en id 1)
 same => n,Set(ODBC_UPDATE=${ODBC_IVAST(UPDATE actuadores SET control=4 WHERE id=1)})
 same => n,Playback(servocambio) ; Reproduce el audio del cambio
 same => n,Goto(menu_servo,s,1) ; Regresa al menú

; Opción 5: Cambiar el valor de control a 1 para id 2
exten => 5,1,NoOp(Opción 5 seleccionada: Cambiar control a 1 en id 2)
 same => n,Set(ODBC_UPDATE=${ODBC_IVAST(UPDATE actuadores SET control=1 WHERE id=2)})
 same => n,Playback(servocambio) ; Reproduce el audio del cambio
 same => n,Goto(menu_servo,s,1) ; Regresa al menú

; Opción 6: Cambiar el valor de control a 2 para id 2
exten => 6,1,NoOp(Opción 6 seleccionada: Cambiar control a 2 en id 2)
 same => n,Set(ODBC_UPDATE=${ODBC_IVAST(UPDATE actuadores SET control=2 WHERE id=2)})
 same => n,Playback(servocambio) ; Reproduce el audio del cambio
 same => n,Goto(menu_servo,s,1) ; Regresa al menú

; Opción 7: Cambiar el valor de control a 3 para id 2
exten => 7,1,NoOp(Opción 7 seleccionada: Cambiar control a 3 en id 2)
 same => n,Set(ODBC_UPDATE=${ODBC_IVAST(UPDATE actuadores SET control=3 WHERE id=2)})
 same => n,Playback(servocambio) ; Reproduce el audio del cambio
 same => n,Goto(menu_servo,s,1) ; Regresa al menú

; Opción 8: Cambiar el valor de control a 4 para id 2
exten => 8,1,NoOp(Opción 8 seleccionada: Cambiar control a 4 en id 2)
 same => n,Set(ODBC_UPDATE=${ODBC_IVAST(UPDATE actuadores SET control=4 WHERE id=2)})
 same => n,Playback(servocambio) ; Reproduce el audio del cambio
 same => n,Goto(menu_servo,s,1) ; Regresa al menú

  
 ; Opción 1-8 (ya programadas para cambiar valores de actuadores)

; Opción 9: Enviar datos de sensores por mensaje
exten => 9,1,NoOp(Opción 9 seleccionada: Enviar datos de sensores)
 same => n,Set(TEMP=${ODBC_GET_TEMPE()})
 same => n,Set(LUZ=${ODBC_GET_LUZ()})
 same => n,Set(HUM=${ODBC_GET_HUM()})
 same => n,Set(MESSAGE(body)=Datos del sensor: Temp=${TEMP}, Luz=${LUZ}, Humedad=${HUM})
 same => n,Set(MESSAGE(from)=pjsip:server)
 same => n,MessageSend(pjsip:1001,${MESSAGE(from)})
 same => n,NoOp(Mensaje enviado a 1001: Temp=${TEMP}, Luz=${LUZ}, Humedad=${HUM})
 same => n,Goto(menu_servo,s,1) ; Regresa al menú
 

; Opciones no válidas: Volver al menú
exten => i,1,Playback(invalid) ; Reproduce un mensaje indicando que la opción no es válida
 same => n,Goto(menu_servo,s,1) ; Regresa al menú

; Tiempo agotado: Reproduce un mensaje y vuelve al menú
exten => t,1,Playback(vm-intro) ; Reproduce un mensaje
 same => n,Goto(menu_servo,s,1) ; Regresa al menú




sudo asterisk -rx "dialplan reload"
sudo asterisk -rx "pjsip reload"