¿cuanta gente a visto el blog?

Lo basico de ser Técnico en redes IP

 Info: https://capacitateparaelempleo.org/cursos/view/192 


La red de una empresa conecta dispositivos para usar servicios. 

La administración tiene tareas operaciones 


Las redes privadas son un sistema autonomo que no permite el uso de compus externasLas redes publicas permiten a todos conectarse [depende capacidad]


Arquitectura: Modelo en el que fisicamente estan conectados  los equipos 
Cliente servidor, una maquina principal punto a punto , todos son igual de responsables, fallo de uno no afecta   

hibrido conserva caracteristicas de ambos

Aplicaciones: Compartir impresora

    Compartir correos 

red sencilla vs compleja 


se dividen por area que cubren y forma en que estan conectadas 
LAN Para oficinas y casas 
caracter privado.
    Hardware y sofwate sensillo 
MAN comunica varias redes dispersas geograficamente a lo largo de la ciudad

    alta velocidad 

    seguridad 

WAN interconecta LAN y MAN [Paies y continentes ]


INTERNET amplio rango de redes y sevicios, conmuta redes wan de todo el mundo 
Puede incluir redes academicas, empresas , negocios o gobiernos.
TCP significa protocolo de control de transmision

[Para redes LAN]Los equipos se conectan a un conmutador o concentrador. 

[es la que permite meter mas equipis de forma sencilla]
En anillo las computadoras se conectan a distribuidor que administra la comunicacion entre equipos [Comunicacion por turnos]

se puede contectar redes anillo

MALLA todos conectados a todos {Poco flexible, poco escalable y cara]


ARBOL varias ramas , con repetidores [Para organisaciones con flexibilidad y escalabilidad ]












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"