tech explorers, welcome!

Autor: TRW (Página 1 de 4)

Soporte para mando PS5

Simplicidad en su máxima expresión.

Hoy comparto este simple pero efectivo y elegante soporte para mando de PS5.

Algunas imágenes/diseños de concepto:

Se sostiene por sí solo sin tornillos ni pegamento. Se cuelga directamente del lateral de la PS5 y es expandible por diseño (probablemente quepan hasta 4 mandos en cada lado).

Algunas fotos reales:

Y, por último, los .stl listos para imprimir:

https://theroamingworkshop.cloud/demos/PS5-DualSense-Holder-A_v1.stl

https://theroamingworkshop.cloud/demos/PS5-DualSense-Holder-B_v1.stl

🎅 Feliz Navidad! 🎁

También disponible en Cults3D como descarga gratuita 💌

Carcasa + pantalla OLED con panel de estado para Raspberry Pi

Estaba tentado de intercambiar la carcasa de mi Raspberry Pi 4 a la Pi 5, pero mírala…

  • 16×2 pantalla LCD de un Arduino Starter Kit
  • Programa en C++ con la librería WiringPi
  • Carcasa casera

Estaba realmente orgulloso de ella en su momento y fue un buen aprendizaje allá por 2020, pero seguro que lo podía hacer mejor. Seguro que me podía currar un pedazo panel de estado!!

Componentes

  • Raspberry Pi (probablemente sirva en cualquiera de ellas)
  • Pantalla OLED (RGB de 1.5 pulgadas es ideal)
  • PCB placa de prototipos
  • Cables
  • Material de soldadura
(cortesía del modelo epiCRealism en ComfyUI)
  • Carcasa (impresa en 3D o elaborada a mano)

Configuración de software

Configuraré la Raspberry para interactuar con la pantalla usando python, mediante la librería de Adafruit Circuitpython para el controlador SSD1351 de la pantalla:
https://learn.adafruit.com/adafruit-1-5-color-oled-breakout-board/python-wiring-and-setup#setup-3042417

Es tan simple como instalar Circuitpython con el siguiente comando:

sudo pip3 install --upgrade click setuptools adafruit-python-shell build adafruit-circuitpython-rgb-display

Si tienes problemas con tu versión de python para encontrar Circuitpython, incluye --break-system-packages al final. (No romperá nada hoy, pero no te acostumbres a ello...)

sudo pip3 install --upgrade click setuptools adafruit-python-shell build adafruit-circuitpython-rgb-display --break-system-packages

Cableado

Ahora conectaremos la pantalla según las indicaciones del fabricante. La mía es esta de BuyDisplay:

https://www.buydisplay.com/full-color-1-5-inch-arduino-raspberry-pi-oled-display-module-128x128

OLED DisplayRaspberry Pi (pin #)
GNDGND (20)
VCC3V3 (17)
SCLSPI0 SCLK (23)
SDASPI0 MOSI (19)
RESGPIO25 (22)
DCGPIO 24 (18)
CSSPI0 CE0 (24)

Usa un sitio como pinout.xyz para encontrar una configuración adecuada para tu cableado.

Estás listo para hacer algunos tests antes de mover tu diseño a la PCB.

Configuración de script

Puedes probar el script demo de Adafruit. Solo asegúrate de escoger la pantalla adecuada y actualiza los cambios en la asignación de pines (usa los números/nombres IO en lugar de los números físicos del pin):

# Configuration for CS and DC pins (adjust to your wiring):
cs_pin = digitalio.DigitalInOut(board.CE0)
dc_pin = digitalio.DigitalInOut(board.D24)
reset_pin = digitalio.DigitalInOut(board.D25)

# Setup SPI bus using hardware SPI:
spi = board.SPI()

disp = ssd1351.SSD1351(spi, rotation=270,                         # 1.5" SSD1351
    cs=cs_pin,
    dc=dc_pin,
    rst=reset_pin,
    baudrate=BAUDRATE
)

Ensamblaje

Aquí están los archivos STL en 3D para este diseño de carcasa:

Ahora pongámoslo todo junto:

  1. Atornilla el marco a la pantalla
  2. Suelda los 7 pines de la pantalla a los 7 cables a través de la PCB
  3. Cablea todas las conexiones a la Raspberry Pi
  4. Atornilla las partes superiores e inferiores de la carcasa entre sí
  5. Coloca la pantalla sobre el soporte

Resultado final

He compartido el script que se ve en las imágenes a través de github:

https://github.com/TheRoam/RaspberryPi-SSD1351-OLED

Actualmente muestra:

  • Fecha y hora
  • Estadísticas del sistema (SO, uso del disco y temperatura de CPU)
  • Tiempo local de la World Meteorological Organization (actualizado cada hora)

Y así es como acaba quedando. Mucho mejor verdad?

Como siempre, disfruta cacharreando, y hazme llegar tus comentarios o dudas a través de Twitter!

🐦 @RoamingWorkshop

Batman con su pistola gancho colgando de tu salón

La verdad es que imprimir con resina es otro nivel. A pesar de las complicaciones de la limpieza, el resultado es realmente increíble, y hoy te enseño mi primera impresión con la Anycubic Photon Mono X2: un Batman para colgar de tu salón con su pistola gancho.

Modelos

La impresión que ves consta de dos modelos gratuitos. Por ello, mi enorme agradecimiento a los autores y mi referencia a su trabajo:

Lo único que he hecho yo es añadirle un esqueleto al modelo y darle la postura deseada, uniéndole luego la pistola a la mano. Asique aquí tienes mi modelo para que lo puedas imprimir tal y como se muestra en las imágenes.

Vista previa

Extras

Para completar el modelo, deberás crearle una capa y un gancho o pinza con el cual colgarlo.

Capa

Para la capa yo he recortado un trozo de tela de una prenda de deporte antigua. Solemos tener prendas de este estilo en color negro y suelen tener también una buena textura y brillo que dan el pego.

Empieza cortando un rectángulo y luego dale forma.

En la parte superior, enrolla un alambre o un clip que te permita ajustar la capa alrededor del cuello de la figura.

Gancho

Simplemente busca un enganche que te venga bien para colgarlo. Yo he usado una pinza a la cual he atado un fino hilo negro, lo que me permite enrollarlo sobre sí para ajustar la altura. De esta forma lo puedo colgar de algún libro de una estantería.

Y así tienes tu genial Batman colgando de tu salón. Espero te guste! Otras ideas o comentarios? Al twitter!

🐦 @RoamingWorkshop

UNIHIKER-PAL: asistente del hogar simplificado, de código abierto en python

PAL es una versión simplificada de mi asistente del hogar en python, que se ejecuta en una placa UNIHIKER de DFRobot, y que lanzo en código abierto gratuito.

Esta es solo una pequeña demostración de la simplicidad de la ejecución de comandos con reconocimiento de voz en python, y con suerte servirá de guía para tu propio asistente.

Version actual: v0.2.0 (actualizado septiembre 2024)

Características

La versión actual incluye lo siguiente:

  • Reconocimiento de voz: usando la librería de código abierto SpeechRecognition, se obtiene una lista con las cadenas de texto reconocidas.
  • Pronóstico del tiempo: usando la API de datos de World Meteorological Organization, devuelve el tiempo de hoy y el pronóstico de los próximos 3 días. Incluye los iconos de la WMO.
  • Temperatura local: reads local BMP-280 temperature sensor to provide a room temperature indicator.
  • Comandos HTTP para IoT: flujo de trabajo básico para controlar dispositivos inteligentes de IoT mediante comandos HTTP. Actualmente ENCIENDE y APAGA un interruptor inteligente Shelly2.5.
  • Modo ahorro de energía: controla el brillo para reducir el consumo de energía.
  • Gestor de conexión: periódicamente comprueba el wifi y llama a internet para restaurar la conexión cuando se pierda.
  • Muestra de voces de PAL: voz clonada de PAL de "Los Mitchells contra las Máquinas" usando el modelo de IA de voz CoquiAI-TTS v2.
  • Botones UNIHIKER: botón A despliega un simple menú (está pensado para desarrollar un menú más complejo en el futuro).
  • Controles táctiles: restaura el brillo (centro), cambia de programa (izquierda) y cierra el programa (derecha) pulsando en distintas zonas de la pantalla.

Instalación

  1. Instala dependencias:
    pip install SpeechRecognition pyyaml
  2. Descarga el repositorio de github:
    https://github.com/TheRoam/UNIHIKER-PAL
  3. Sube los archivos y carpetas a la UNIHIKER en /root/upload/PAL/
  4. Configura en PAL_config.yaml las credenciales WIFI, dispositivos IoT, etc.
  5. Lanza el script de python python /root/upload/PAL/PAL_020.py desde la terminal de Mind+ o desde la interfaz táctil de UNIHIKER.

Si habilitas Auto boot en el menú de Service Toggle, el script se ejecutará automáticamente cada vez que se reinicie la UNIHIKER

https://www.unihiker.com/wiki/faq#Error:%20python3:%20can't%20open%20file…

Configuración

Version 0.2.0 includes configuration using a yaml file that is read when the program starts.

CREDENTIALS:
ssid: "WIFI_SSID"
pwd: "WIFI_PASSWORD"

DEVICES:
light1:
brand: "Shelly25"
ip: "192.168.1.44"
channel: 0

light2:
brand: "Shelly25"
ip: "192.168.1.44"
channel: 1

light3:
brand: "Shelly1"
ip: "192.168.1.42"
channel: 0

PAL:
power_save_mode: 0
temperature_sensor: 0
wmo_city_id: "195"

Localización

La variable "CityID" se usa para proporcionar un pronóstico del tiempo de WMO más cercano a tu localización.

Elige una de las localizaciones disponibles en su listado oficial:

https://worldweather.wmo.int/en/json/full_city_list.txt

Dispositivos IoT

En este momento, PAL v0.2.0 solo incluye compatibilidad con Shelly2.5 para fines demostrativos.

Usa las variables lampBrand, lampChannel y lampIP para ajustar tu configuración de Shelly2.5.

Esto es solo un ejemplo para mostrar cómo se pueden configurar distintos dispositivos. Estas variables se deberían usar para cambiar las peculiaridades de los comandos HTTP que se envían a cada dispositivo IoT.

Se añadirán más dispositivos en futuras actualizaciones, como Shelly1, ShellyDimmer, Sonoff D1, etc.

Modo ahorro de energía

El ahorro de energía disminuye el brillo del dispositivo para reducir el consumo de energía de la UNIHIKER. Esto se hace usando el comando del sistema "brightness".

Cambia la variable "ps_mode" para habilitar ("1") o deshabilitar ("0") el modo ahorro de energía.

Temperatura de habitación

Cambia la variable "room_temp" para habilitar ("1") o deshabilitar ("0") el módulo de lectura de sensor de temperatura. Esto requiere un sensor BMP-280 instalado mediante el conector I2C.

Comprueba este otro post para los detalles de la instalación del sensor:

https://theroamingworkshop.cloud/b/en/2490/

Otras configuraciones desde el código fuente:

Tema

Se habilita la personalización de la imagen de fondo que representa los ojos de PAL.

Usa las variables "eyesA" y "eyesB" para especificar uno de los siguientes valores y cambia la expresión del PAL:

  • "happy"
  • "angry"
  • "surprised"
  • "sad"

"eyesA" se usa como fondo por defecto y "eyesB" se usa como transición cuando el reconocimiento de voz se activa y PAL habla.

El valor por defecto de "eyesA" es "surprised" y cambiará a "happy" cuando se reconoce un comando.

Comandos personalizados

Añadir tus propios comandos a PAL es simple usando la función "comandos".

Cada audio reconocido por SpeechRecognition se envía como una cadena a la función "comandos", que filtra y lanza uno u otro comando coincidente con la orden.

Solo define todas las posibles cadenas que pueden ser reconozidas para lanzar tu comando (a veces SpeechRecognition devuelve transcripciones erróneas o imprecisas).

Finalmente, define el comando que se lanza cuando la cadena coincide.

def comandos(msg):
    # LAMP ON
    if any(keyword in msg for keyword in ["turn on the lamp", "turn the lights on","turn the light on", "turn on the light", "turn on the lights"]):
        turnLAMP("on")
        os.system("aplay '/root/upload/PAL/mp3/Turn_ON_lights.wav'")

Palabra clave para la activación

Puedes personalizar las palabras clave o cadenas que activan las funciones de comandos. Si cualquiera de las palabras clave en la lista es reconocida, toda la frase se envía a la función "comandos" para buscar un comando coincidente y ejecutarlo.

En caso de PAL v0.2, estas son las palabras clave que lo activan (el 90% de las veces es Paypal...):

activate=[
    "hey pal",
    "hey PAL",
    "pal",
    "pall",
    "Pall",
    "hey Pall",
    "Paul",
    "hey Paul",
    "pol",
    "Pol",
    "hey Pol",
    "poll",
    "pause",
    "paypal",
    "PayPal",
    "hey paypal",
    "hey PayPal"
]

Puedes cambiar esto a cualquier otra frase o nombre para activar a PAL cuando la llames de esa manera.

Voz de PAL

Usa la muestra de audio "PAL_full" abajo (también en el repositorio de github en /mp3) como audio de referencia para la clonación de voz de CoquiAI-TTS v2 y genera tus propias voces:

https://huggingface.co/spaces/coqui/xtts

TIP!
Comprueba este otro post sobre clonación de voz con CoquiAI-XTTS:
https://theroamingworkshop.cloud/b/2429

Demo

A continuación hay algunos ejemplos de consultas y respuestas de PAL:

"Hey PAL, turn on the lights!"
"Hey PAL, turn the lights off"
"Hey PAL, what's the weather like?"

Futuros lanzamientos (To-Do list)

Iré desarrollando estas características en mi asistente personal, e iré actualizando la versión de código abierto de vez en cuando. Ponte en contacto via github si tienes especial interés en alguna de ellas:

  • Menú avanzado: añadir configuración y comandos manuales.
  • Dispositivos IoT: incluir todos los comandos HTTP de Shelly y Sonoff.
  • Consultar la hora: requiere clonar la voz de todas las combinaciones de números...
  • Consulta de Wikipedia/internet: requiere generar voz en tiempo real...
  • Mejoradas animaciones / temas.

Comentarios, problemas o mejoras, me encantará recibirlos en github o Twitter!

🐦 @RoamingWorkshop

🌡UNIHIKER sensor de temperatura en tiempo real funcionando en 2 minutos

Sigo experimentando con la placa UNIHIKER de DFRobot y es increíblemente rápido hacer que las cosas funcionen en ella. Hoy traigo cómo configurar en 2 minutos la visualización en tiempo real de un sensor de temperatura, usando un módulo BMP-280 y absolutamente nada de programación.

Prerrequisitos

Aquí está el truco, y es que esperaba que tuvieras un par de cosas configuradas antes de activar el cronómetro:

  • Descarga e instala Mind+, el IDE para UNIHIKER de DFRobot.
    En Linux se trata de fichero .deb que se toma su tiempo para instalar:
    https://mindplus.cc/download-en.html
  • Suelda un modulo de presión y temperatura BMP-280 y conéctalo a un cable I2C que vienen con la placa. Tendrás que doblar ligeramente algunos pines para que encajen en el conector que parece un nano JST de 1mm.

Ya estás listo!

Configuración

  1. En Mind+, ve al Blocks editor y abre el menú Extensions.
  2. En la pestaña pinpong selecciona el propio módulo pinpong (que habilita la interacción con los pines de la UNIHIKER) y el módulo de extensión BMP-280, que añade la interacción con estos módulos.
  1. Vuelve al Blocks editor y comienza a construir tu bloque de código. Simplemente navega por el menú lateral izquierdo y arrastra todo lo que necesitas debajo del bloque Python program start:
    • pinpong - initialize board.
    • bmp280 - initialize I2C address 0x76 para inicializar el módulo.
    • control - bloque forever (introduce un bucle while True).
    • unihiker - añade objetos a la pantalla. Primero añado un objeto filled rectangle para limpiar texto anterior, luego añado el objeto text. Especifica coordenadas X,Y donde se mostrará cada objeto, al igual que su color.
    • bmp280 - objeto read temperature. Arrástralo dentro del campo de texto del objeto text.
    • python - (opcional) añade un objeto print para mostrar los datos en terminal. Yo he incluido todas las otras propiedades que devuelve el sensor.
    • control - añade un objeto wait para detener el programa durante 1 segundo antes del siguiente bucle.

      Debería quedar todo así (haz click para ampliar)

Ejecución

Y ya está todo el programa montado, sin programar! Pulsa RUN en la parte superior de Mind+ y observa cómo se carga y se muestra por la pantalla de la UNIHIKER. Toca el sensor ligeramente con el dedo para ver cómo varían los valores con el incremento de temperatura.

Han sido sólo 2 minutos no?

🐦 @RoamingWorkshop

Carcasa DFRobot para UNIHIKER

El pequeño y eficiente factor de forma de la UNIHIKER hace que sea muy fácil diseñar una carcasa para ella.

Para my asistente inteligente buscaba un estilo tipo androide, y el logo de DFRobot es perfecto para la UNIHIKER, haciendo un guiño a sus desarrolladores.

Repositorio Github

He publicado un repositorio donde abriré las fuentes (open-source) de todos los archivos de los modelos, pudiendo cualquiera contribuir con los suyos, así que anímate a crear una solicitud de cambios (pull request) y comparte tus diseños!

https://github.com/TheRoam/DFRobot-UNIHIKER-case/

También se incluye una página github donde se pueden previsualizar los modelos:

https://theroam.github.io/DFRobot-UNIHIKER-case/

Unihiker_DFRcase_v1

Mi primer lanzamiento, usado para testear e incluir las funcionalidades básicas para mi asistente.

Archivos

https://github.com/TheRoam/DFRobot-UNIHIKER-case/tree/main/blender

Características

  • Aperturas superiores para mostrar texto en la pantalla táctil.
  • Apertura lateral para conexión de USB-C.
  • Apertura trasera para cableado de sensores externos.
  • Extrusiones traseras para colocación de altavoces de 40mm.
  • Pie de soporte para posicionamiento vertical.

Partes de la carcasa

  1. Pieza inferior: actúa como envoltorio.
  2. Pieza de soporte interior: sostiene la placa UNIHIKER a la pieza inferior usando los tornillos de la placa.
  3. Pieza superior: actúa como tapa encajándose en la pieza inferior.
  4. Pie de soporte: permite posicionamiento vertical.
  5. Antenas: le dan el toque final al logo de DFRobot.

Ensamblaje

  1. Coloca los tornillos en el soporte interior y atorníllalo a la placa UNIHIKER.
  1. Coloca la UNIHIKER dentro de la pieza inferior. Si vas a usar sensores exteriores, saca el cableado por la apertura trasera.
  1. Sujeta la placa a la carcasa con un par de tornillos de 2.5mm desde la parte trasera.
  1. Coloca la pieza superior y encájala con la inferior. Hará click con dos pestañas laterales.
  1. Coloca el pie de soporte y las antenas en su sitio. Puedes pegarlos con pegamento para asegurarte de que no se mueven.

Y ahí tienes tu carcasa montada con un look muy droide!

No olvides compartir tus impresiones en Twitter!

🐦 @RoamingWorkshop

🐸Coqui-AI/TTS: ultra rápida generación y clonación de voz a partir de texto multilenguaje

Hace unos meses traía el repositorio TorToiSe-TTS que facilitaba muchísmo la generación de voz a partir de texto, aunque solo se disponía de modelos en inglés.

https://theroamingworkshop.cloud/b/2066

Pero el mundo de la IA avanza tan rápido, que hoy os traigo una evolución que desbanca por completo al anterior post, con generación de voces complejas en cuestión de segundos y multilenguaje: Coqui-AI TTS.

https://github.com/coqui-ai/TTS

Versión web

Si tienes prisa y no quieres liarte, puedes usar el espacio gratuito de huggingface, y tendrás tu clonación de voz en pocos segundos:

https://huggingface.co/spaces/coqui/xtts

  1. Escribe el texto a generar
  2. Selecciona el idioma
  3. Sube tu fichero de referencia
  4. Configura el resto de opciones (marca las casillas: Cleanup Reference Voice, Do not use language auto-detect, Agree)
  5. Solicita tu clonación al servidor (Send)

Instalación

En cuanto a la instalación local:

  • Necesitarás python > 3.9, < 3.12.
  • RAM: no necesita tanta como para generación de imágenes. 4GB deberían bastar.
  • Crea una carpeta para el proyecto, por ejemplo "text-2-speech". Usando un terminal de Linux:
    mkdir text-2-speech
  • Es conveniente crear un entorno de python específico para evitar incompatibilidad de paquetes, para lo que debes instalar el paquete python3-venv. Yo crearé el entorno TTSenv:
    cd text-2-speech
    python3 -m venv TTSenv
  • Activa el entorno en el terminal:
    source TTSenv/bin/activate
  • Si solo necesitas generación de voz (sin clonación ni entrenamiento), instala directamente TTS en python:
    pip install TTS
  • Sin embargo, yo instalaré el repositorio completo de Coqui-AI TTS:
    git clone https://github.com/coqui-ai/TTS
    cd TTS
    pip install -e .[all]

Comprobación de modelos de lenguaje y voces

Lo primero que puedes hacer es comprobar los modelos disponibles para transformar tu texto a voz en distintos idiomas.

En el terminal escribe lo siguiente:

tts --list_models

No API token found for 🐸Coqui Studio voices - https://coqui.ai
Visit 🔗https://app.coqui.ai/account to get one.
Set it as an environment variable `export COQUI_STUDIO_TOKEN=`


Name format: type/language/dataset/model
1: tts_models/multilingual/multi-dataset/xtts_v2 [already downloaded]
2: tts_models/multilingual/multi-dataset/xtts_v1.1 [already downloaded]
3: tts_models/multilingual/multi-dataset/your_tts
4: tts_models/multilingual/multi-dataset/bark [already downloaded]
5: tts_models/bg/cv/vits
6: tts_models/cs/cv/vits
7: tts_models/da/cv/vits
8: tts_models/et/cv/vits
9: tts_models/ga/cv/vits
10: tts_models/en/ek1/tacotron2
11: tts_models/en/ljspeech/tacotron2-DDC
12: tts_models/en/ljspeech/tacotron2-DDC_ph
13: tts_models/en/ljspeech/glow-tts
14: tts_models/en/ljspeech/speedy-speech
15: tts_models/en/ljspeech/tacotron2-DCA
16: tts_models/en/ljspeech/vits
17: tts_models/en/ljspeech/vits--neon
18: tts_models/en/ljspeech/fast_pitch
19: tts_models/en/ljspeech/overflow
20: tts_models/en/ljspeech/neural_hmm
21: tts_models/en/vctk/vits
22: tts_models/en/vctk/fast_pitch
23: tts_models/en/sam/tacotron-DDC
24: tts_models/en/blizzard2013/capacitron-t2-c50
25: tts_models/en/blizzard2013/capacitron-t2-c150_v2
26: tts_models/en/multi-dataset/tortoise-v2
27: tts_models/en/jenny/jenny
28: tts_models/es/mai/tacotron2-DDC [already downloaded]
29: tts_models/es/css10/vits [already downloaded]
30: tts_models/fr/mai/tacotron2-DDC
31: tts_models/fr/css10/vits
32: tts_models/uk/mai/glow-tts
33: tts_models/uk/mai/vits
34: tts_models/zh-CN/baker/tacotron2-DDC-GST
35: tts_models/nl/mai/tacotron2-DDC
36: tts_models/nl/css10/vits
37: tts_models/de/thorsten/tacotron2-DCA
38: tts_models/de/thorsten/vits
39: tts_models/de/thorsten/tacotron2-DDC
40: tts_models/de/css10/vits-neon
41: tts_models/ja/kokoro/tacotron2-DDC
42: tts_models/tr/common-voice/glow-tts
43: tts_models/it/mai_female/glow-tts
44: tts_models/it/mai_female/vits
45: tts_models/it/mai_male/glow-tts
46: tts_models/it/mai_male/vits
47: tts_models/ewe/openbible/vits
48: tts_models/hau/openbible/vits
49: tts_models/lin/openbible/vits
50: tts_models/tw_akuapem/openbible/vits
51: tts_models/tw_asante/openbible/vits
52: tts_models/yor/openbible/vits
53: tts_models/hu/css10/vits
54: tts_models/el/cv/vits
55: tts_models/fi/css10/vits
56: tts_models/hr/cv/vits
57: tts_models/lt/cv/vits
58: tts_models/lv/cv/vits
59: tts_models/mt/cv/vits
60: tts_models/pl/mai_female/vits
61: tts_models/pt/cv/vits
62: tts_models/ro/cv/vits
63: tts_models/sk/cv/vits
64: tts_models/sl/cv/vits
65: tts_models/sv/cv/vits
66: tts_models/ca/custom/vits
67: tts_models/fa/custom/glow-tts
68: tts_models/bn/custom/vits-male
69: tts_models/bn/custom/vits-female
70: tts_models/be/common-voice/glow-tts

Name format: type/language/dataset/model
1: vocoder_models/universal/libri-tts/wavegrad
2: vocoder_models/universal/libri-tts/fullband-melgan [already downloaded]
3: vocoder_models/en/ek1/wavegrad
4: vocoder_models/en/ljspeech/multiband-melgan
5: vocoder_models/en/ljspeech/hifigan_v2
6: vocoder_models/en/ljspeech/univnet
7: vocoder_models/en/blizzard2013/hifigan_v2
8: vocoder_models/en/vctk/hifigan_v2
9: vocoder_models/en/sam/hifigan_v2
10: vocoder_models/nl/mai/parallel-wavegan
11: vocoder_models/de/thorsten/wavegrad
12: vocoder_models/de/thorsten/fullband-melgan
13: vocoder_models/de/thorsten/hifigan_v1
14: vocoder_models/ja/kokoro/hifigan_v1
15: vocoder_models/uk/mai/multiband-melgan
16: vocoder_models/tr/common-voice/hifigan
17: vocoder_models/be/common-voice/hifigan
Name format: type/language/dataset/model
1: voice_conversion_models/multilingual/vctk/freevc24 [already downloaded]

O fíltralo según tu idioma con grep, por ejemplo para español:

tts --list_models | grep "/es"

28: tts_models/es/mai/tacotron2-DDC [already downloaded]
29: tts_models/es/css10/vits [already downloaded]

Texto a voz

Con esto ya puedes generar voz a partir de texto en cuestión de segundos y en el idioma que prefieras.

En el terminal, escribe lo siguiente, especificando el modelo adecuado:

tts --text "Ahora puedo hablar en español!" --model_name "tts_models/es/css10/vits" --out_path output/tts-es.wav

Asegúrate de que el directorio de salida existe, y de que eliges el nombre dle modelo correto. La primera vez se descargarán los archivos necesarios y deberás aceptar la licencia de Coqui-AI. Después la generación se realiza en cuestión de segundos:

Clonación de voz

Por último, lo realmente impresionante de este modelo es la clonación de voz a partir de unos pocos segundos de grabación de audio.

Igual que en el post anterior, yo he tomado unos 30 segundos de la voz de Ultrón de escenas de la película Los Vengadores: la era de Ultrón.

Muestra en español:

Muestra en inglés:

Ahora, preparamos un script de python donde parametrizaremos todo lo necesario, que a grandes rasgos hará lo siguiente:

  • Importar torch y TTS
    import torch
    from TTS.api import TTS
  • Definir dispositivo de memoria (cuda o cpu). Con usar cpu sobra. Cuda puede petar.
    device="cpu"
  • Definir el texto a generar.
    txt="Voz generada a partir de texto"
  • Definir la muestra de audio de referencia (archivos .wav de unos 30 segundos)
    sample="/voice-folder/voice.wav"
  • Llamada al modelo TTS
    tts1=TTS("model_name").to(device)
  • Creación del fichero
    tts1.tts_to_file(txt, speaker_wav=sample, language="es", file_path="output-folder/output-file.wav")

Yo lo he llamado TRW-clone.py y queda así:

import torch
from TTS.api import TTS

# Get device ('cuda' or 'cpu')
device="cpu"

#Define text
txt="Bienvenido a este nuevo artículo del blog. Disfruta de tu visita."
#txt="Welcome to this new block post... Enjoy your visit!"

#Define audio sample
sample="../my-voices/ultron-es/mix.wav"
#sample="../my-voices/ultron-en/mix.wav"

#Run cloning
tts1 = TTS("tts_models/multilingual/multi-dataset/xtts_v2").to(device)

tts1.tts_to_file(txt, speaker_wav=sample, language="es", file_path="../output/ultron-es.wav")

Ejecútalo desde la carpeta TTS donde se encuentra el repositorio completo:

cd TTS
python3 TRW-clone.py

Resultados

Aquí te dejo los resultados obtenidos en mis primeras pruebas.

Español:

Inglés:

Con un par de iteraciones podrás obtener resultados realmente espectaculares.

Cualquier duda o comentario aún la puedes dejar en Twitter/X

🐦 @RoamingWorkshop

Shelly 1: interruptor/programador wifi, configuración de API HTTP local y ensamblaje en caja de enchufe.

Hoy os traigo mi segunda oportunidad que le voy a dar a Shelly. Y es que mi primer Shelly Dimmer petó por exceso de temperatura, al tenerlo dentro de una caja de conexiones, pero el Shelly 2.5 que controla dos luces está aguantando también insertado en la pared.

Quizás la diferencia son los 5ºC más que soportan, así que hoy voy a montar un enchufe de pared con interruptor/programador wifi añadiéndole un diminuto Shelly 1, y esperemos que aguante.

Además de su pequeño tamaño, los Shelly son muy fáciles de configurar, así que también veremos cómo controlarlos localmente mediante su API HTTP.

Requisitos

Mi objetivo es habilitar un enchufe de pared que pueda controlar y programar mediante WIFI, en mi caso, para controlar el calentador de agua eléctrico. Veamos qué voy a usar:

  • Shelly 1.
  • Cable eléctrico de dos hilos (fase y neutro).
  • Clavija de enchufe macho.
  • Clavija de enchufe hembra.
  • Material para ensamblar una carcasa (impresora 3D, madera, etc).

Conexión eléctrica

Veamos el manual de Shelly a ver cómo nos indica que realicemos las conexiones:

https://www.shelly.com/documents/user_guide/shelly_1_multi_language.pdf

La idea de este esquema estándar es que conectes el Shelly 1 a una luz y a su interruptor, significando cada símbolo lo siguiente:

  • L: línea o fase
  • N: neutro
  • SW: switch (interruptor)
  • I: input o entrada
  • O: output o salida

Como quiero habilitar una clavija de enchufe, el esquema variará ligeramente, ya que no usaré el interruptor y puedo conectar la línea directamente a la entrada. Por otro lado, y por motivos que desconozco, no tengo cableado en esta caja de conexiones, así que traigo la línea eléctrica mediante un cable que va a otro enchufe... En fin, queda todo así:

TIP! Juraría que me he rayado confundiendo los colores, pero en este caso el circuito propio es cerrado así que no importa demasiado si no eres maniático, ya que el circuito está conectado correctamente.

Ensamblaje

Como verás, me he hecho un pequeño soporte en 3D para guiar las conexiones y también una tapa para cubrir el hueco del enchufe. Además, simular las piezas en 3D, con medidas reales , te ayudará a distribuir bien el espacio y asegurarte de que tu solución se acopla correctamente:

Te dejo los modelos 3D en .stl para mandar a imprimir en software slicer.

Shelly-Plug_support_v1.stl

https://theroamingworkshop.cloud/demos/Shelly-Plug_support_v1.stl

Shelly-Plug_tapa_v1.stl

https://theroamingworkshop.cloud/demos/Shelly-Plug_tapa_v1.stl

Al final, queda todo así montado. No es el ajuste perfecto, pero me vale para cumplir su función.

Conexión a internet

Ahora veamos como traer a la vida al Shelly 1 y manejarlo localmente.

Al contrario que los Sonoff, Shelly nos lo pone mucho más fácil y solo hay que seguir su manual.

  1. Enchufa el Shelly 1 a la corriente mediante el cable con clavija macho.
  2. Se activará un AP (Access Point) o red Wi-Fi con una SSID del estilo "shelly1-01A3B4". Conéctate a esta red Wi-Fi mediante un smartphone o PC.
  3. Cuando te conectes, usa un navegador web para acceder a la IP 192.168.33.1 y accederás a la interfaz web de configuración del dispositivo.
  1. Una vez dentro, deberás configurar el dispositivo (en el menú Internet & Security) para que se conecte automáticamente a tu red Wi-Fi, así como también es recomendable que bloquees el acceso al dispositivo con usuario y contraseña, por lo que pudiera ocurrir...

Con esto ya podemos comunicarnos localmente con nuestro Shelly 1.

Uso de Shelly HTTP API

Para usar los comandos de la API HTTP deberás conocer la IP del dispositivo en la red local.

Averiguar IP mediante router

Puedes acceder al mapa de red de tu router, normalmente mediante la dirección http://192.168.1.1

Tanto la dirección como la contraseña de acceso deberían aparecer en una pegatina en tu router. Luego verás tu dispositivo con algún nombre tipo shelly1-XXXXXXXXXXXX:

Averiguar IP mediante nmap

Mediante un terminal, puedes usar el programa nmap para escanear tu red local.

  • Descárgalo si no lo tienes:
    sudo apt-get update
    sudo apt-get install nmap
  • Escanea tu red (con sudo aportará también la dirección MAC, útil por que la IP podría llegar a cambiar al reiniciar tu router)
    sudo nmap -v -sn 192.168.1.0/24

Enviar solicitudes HTTP al dispositivo

La API HTTP de Shelly viene documentada en su web dedicada:

https://shelly-api-docs.shelly.cloud/gen1/#common-http-api

Para poder comunicarte con el dispositivo necesitas enviar solicitudes HTTP mediante algún programa tipo Postman o mediante curl o wget en un terminal.

La solicitud se hará a la IP del dispositivo con:

$ curl -X GET http://192.168.1.XX/command

Si has definido usuario y contraseña, deberás ingresarlo también en la URL de esta manera o devolverá una respuesta "401 unauthorized":

$ curl -X GET http://user:[email protected]/command

Ahora veamos algunos casos concretos:

Información del dispositivo

http://[user]:[pass]@[ip]/status

  • curl

curl -X GET 'http://user:[email protected]/status

  • Respuesta
{"wifi_sta":{"connected":true,"ssid":"MYWIFINETWORK","ip":"192.168.1.XX","rssi":-70},"cloud":{"enabled":false,"connected":false},"mqtt":{"connected":false},"time":"19:30","unixtime":1699295403,"serial":1,"has_update":false,"mac":"A4CF12F407B1","cfg_changed_cnt":0,"actions_stats":{"skipped":0},"relays":[{"ison":false,"has_timer":false,"timer_started":0,"timer_duration":0,"timer_remaining":0,"source":"input"}],"meters":[{"power":0.00,"is_valid":true}],"inputs":[{"input":0,"event":"","event_cnt":0}],"ext_sensors":{},"ext_temperature":{},"ext_humidity":{},"update":{"status":"idle","has_update":false,"new_version":"20230913-112003/v1.14.0-gcb84623","old_version":"20230913-112003/v1.14.0-gcb84623"},"ram_total":51688,"ram_free":39164,"fs_size":233681,"fs_free":146333,"uptime":2679}

Encender/apagar (on/off)

http://[usr]:[pass]@[ip]/relay/0?turn=[on/off]

  • curl

curl -X GET http://user:[email protected]/relay/0?turn=on

  • Respuesta
{"ison":true,"has_timer":false,"timer_started":0,"timer_duration":0,"timer_remaining":0,"source":"http"}

El valor de 0 en la URL corresponde con el número del relay o interruptor interno del Shelly. En este caso solo hay uno, pero en caso del Shelly 2.5 tienes dos relays, por lo que puedes manejarlos individualmente cambiando este número.

Programador

http://[usr]:[pass]@[ip]/settings/relay/0?schedule_rules=[HHMM]-[0123456]-[on/off]

  • curl

curl -X GET http://user:[email protected]/settings/relay/0?schedule_rules=1945-0123456-on

  • Respuesta
{"name":"CALENTADOR","appliance_type":"General","ison":false,"has_timer":false,"default_state":"off","btn_type":"toggle","btn_reverse":0,"auto_on":0.00,"auto_off":0.00,"power":0.00,"schedule":true,"schedule_rules":["1945-0123456-on"]}

En este caso, en la URL se definen los siguientes parámetros de las reglas:

  • HHMM: hora y minuto que activan la regla
  • 0123456: los días de la semana en los que se produce la regla
  • on/off: estado que se produce al activarse la regla

De esta forma, para programar el encendido y apagado del dispositivo (excepto fines de semana), tendrías una solicitud de este estilo:

curl -X GET http://192.168.1.XX/settings/relay/0?schedule_rules=2300-01234-on,0700-01234-off

Obviamente, también podrás configurar las reglas de programación desde la interfaz web, o comprobar que los comandos han funcionado:

Y con eso estaría todo. Lánzate a llenar tu casa de discretos Shellys totalmente personalizables. Cualquier duda o comentario, al Twitter 🐦, gracias! (aunque visto lo de X, no sé yo lo que me durará...)

🐦 @RoamingWorkshop

☮️ #WarTraces : la huella aérea de un mundo en guerra.

Todo empezó como un ejercicio de curiosidad, pensando si el ataque al puente de Kerch en Crimea se habría visto desde el espacio.

Para mi sorpresa, este será uno de los menos visibles de los ataques ocurridos durante la guerra de Ucrania.

Con cada noticia, comprobaba las imágenes satélite (accesibles públicamente) de la Agencia Espacial Europea y encontré evidencias de muchas de las informaciones. Las imágenes satélite son puramente objetivas. No hay manipulación o un discurso detrás.

Esto es totalmente opuesto a tomar un bando. Se trata de mostrar la realidad y la escala de la guerra. La auténtica y única verdad es que la violencia y la guerra tienen que ser condenadas en todas sus formas y prevenidas con cada mínimo esfuerzo que uno pueda hacer.

#WarTraces empieza en Ucrania, porque está cerca de los europeos, 24/7 en TV, y afectando a muchas y poderosas economías. Pero hay muchos otros conflictos activos en el mundo. Muchos otros que parecen olvidados. Muchos otros que no parecen tener importancia. Muchos otros que deben cesar igual que este.

Sígueme en 🐦 Twitter para saber cuando se actualiza este post!

🐦 @RoamingWorkshop

PAZ ☮ HERMANOS

TIP! Haz click en una imagen para ampliarla.

Guerra de Ucrania: 24 Feb 2022 - hoy

📖 Cronología de Wikipedia.

Guerra Civil Siria: 2011 - hoy

📖 Cronología de Wikipedia.

Conflicto Palestino-Israelí : 1948-hoy

📖 Cronología de Wikipedia.

endleZZ v0.2: actualización de aniversario

Hace un año que surgió endleZZ en una sala de espera sin cobertura, como una forma de desarrollar un juego offline que no requiriese nada especial: solo un navegador y un fichero .html en tu móvil.

La idea es genial, me ha servido muchas veces para matar el tiempo, pero se merecía una mínima actualización visual y funcional.

Así que aquí está la versión 0.2: actualización de aniversario! 🎉

Versión web

Accede a la versión web oficial que hospedo en este servidor:

https://theroamingworkshop.cloud/endlezz

Versión local

O juega en local (y offline) descargando el código fuente del anterior enlace, o bien el fichero .html de github:

https://github.com/TheRoam/endleZZ

Registro de cambios

Nuevas características:

  • menú de opciones
  • controles de tiempo: pausa, restaurar y salir
  • nuevos elementos del mapa (árboles y rocas) que se generan aleatoriamente en cada partida
  • concepción inicial de sistema climático: añadida generación de nubes aleatorias

Corrección de errores:

  • las balas ahora alcanzan el final del mapa, a pesar de donde se pulse
  • ajustes del cálculo del tiempo en las pausas
  • mejoras generales de rendimiento e interacción
« Entradas anteriores