Como escuchar Apple Music en un dispositivo Alexa

La música es la alegre sonrisa que endulza nuestro día a día. Hace unos años la forma tradicional para escuchar música era sintonizar una emisora de radio, o comprar en alguno de los formatos disponibles, según la época; vinilo, CD o casete de audio, nuestro grupo o solista preferido. Con la llegada de Internet y el desarrollo de tecnologías como el streaming, la tendencia actual para escuchar música es precisamente el uso del streaming.

Existen diferentes alternativas para poder escuchar millones de canciones en streaming; Apple Music, Amazon Music, Spotify, Pandora, Tidal o Soundcloud, por poner las más famosas y reconocidas.

Si tienes una cuenta en Apple Music, puedes pedirle a Alexa que ponga tu música favorita en tus dispositivos Alexa.

Para ello debes instalar la Skill de “Apple Music“. Una vez instalada debes configurar la skill para enlazarla con tu cuenta de Apple Music.

Una vez realizadas las acciones anteriores, ve a “Más / Configuración / Música“. Si Apple Music no te sale en la lista, pulsa en “Vincular servicio nuevo” y selecciona el servicio de Apple Music.

Para configurar el orden de los servicios predeterminados, pulsa sobre “Servicios predeterminados“. En la nueva pantalla selecciona el servicio que por defecto se iniciara en tu dispositivo al solicitar una canción o emisora de radio a Alexa.

El order actual es el que verás debajo de “Servicios predeterminados“.

También puedes decirle a Alexa con que servicio quieres que reproduzca una cación, pero el comando de voz es más largo, ejemplo: “Alexa pon una canción de Madonna en Apple Music“.



Si encuentras esta noticia interesante la puedes compartir en tus redes sociales, a tus seguidores les puede gustar. Utiliza los botones que tienes más abajo.

Share

Convertir Arduino en un controlador de dispositivos con Alexa

Vamos a convertir, una tarjeta Arduino Wemos (Con modulo wifi), utilizando un modulo de reles, en un accesorio para encender/apagar diferentes dispositivos; luces, ventiladores, calefactores, discos duros o cualquier otro dispositivo que se te ocurra.

Para realizar esta tarea nos hace falta:

  • Una tarjeta Wemos.
  • Un modulo de reles, puede ser de 1, 2, 4 u 8 reles.
  • Darnos de alta en la web https://sinric.com/
  • Instalar la skill Sinric en Amazon Alexa.

Sinric es una Api gratuita desde la que vamos a poder crear todos aquellos dispositivos que necesitemos controlar. Por cada dispositivo que creamos, Sinric asigna un ID para su identificación.

Para añadir un nuevo dispositivo pulsamos en el botón “ADD” de la sección “Smart Home Device“, se abrira un panel como el de la imagen superior.

  • Friendly Name. Es el nombre con el que invocaremos a Alexa, para gestionar nuestro dispositivo, encender / apagar.
  • Description. La descripción del dispositivo.
  • Device Type. De la lista desplegable seleccionamos el que más se adapte a nuestro tipo de dispositivo.

Guardamos el nuevo dispositivo, y realizamos la misma operación para crear todos los que necesitemos.

En la pantalla principal de sinric veremos todos los dispositivos creados, es importante apuntar los ID que la aplicación ha generado. También debemos anotar el “Your API Key“, se encuentra en la parte superior, con estos datos podremos controlar los dispositivos desde nuestra Arduino.

En este repositorio de github podemos encontrar los archivos “ino” para la tarjeta Arduino, existen diferentes ejemplos para el uso de la api de sinric.

Aqui tienes el código que utilizo para gestionar mis dispositivos a traves de Alexa. Se pueden controlar 4 dispositivos, pero es muy fácil añadir más.

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsClient.h> //  https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries
#include <ArduinoJson.h> // https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries
#include <StreamString.h>

ESP8266WiFiMulti WiFiMulti;
WebSocketsClient webSocket;
WiFiClient client;

#define MyApiKey "Tu-Api-Key-de-Sinric" // TODO: Change to your sinric API Key. Your API Key is displayed on sinric.com dashboard
#define MySSID "El-Nombre-de-tu-WIFI" // TODO: Change to your Wifi network SSID
#define MyWifiPassword "La-Contraseña-de-tu-WIFI" // TODO: Change to your Wifi network password

#define HEARTBEAT_INTERVAL 300000 // 5 Minutes 

const int relayPin1 = D1;
const int relayPin2 = D2;
const int relayPin3 = D3;
const int relayPin4 = D4;

uint64_t heartbeatTimestamp = 0;
bool isConnected = false;

void setPowerStateOnServer(String deviceId, String value);
void setTargetTemperatureOnServer(String deviceId, String value, String scale);

// deviceId is the ID assgined to your smart-home-device in sinric.com dashboard. Copy it from dashboard and paste it here

void turnOn(String deviceId) {

  // Device 1
  if (deviceId == "El-ID-de-tu-Dispositivo") // Device ID of first device
  {
    Serial.print("Turn on device id: ");
    Serial.println(deviceId);

    digitalWrite(relayPin1, HIGH); // turn on relay with voltage HIGH
  }
  else {
    Serial.print("Turn on for unknown device id: ");
    Serial.println(deviceId);
  }

  // Device 2
  if (deviceId == "El-ID-de-tu-Dispositivo") // Device ID of first device
  {
    Serial.print("Turn on device id: ");
    Serial.println(deviceId);

    digitalWrite(relayPin2, HIGH); // turn on relay with voltage HIGH
  }
  else {
    Serial.print("Turn on for unknown device id: ");
    Serial.println(deviceId);
  }

  // Device 3
  if (deviceId == "El-ID-de-tu-Dispositivo") // Device ID of first device
  {
    Serial.print("Turn on device id: ");
    Serial.println(deviceId);

    digitalWrite(relayPin3, HIGH); // turn on relay with voltage HIGH
  }
  else {
    Serial.print("Turn on for unknown device id: ");
    Serial.println(deviceId);
  }

  // Device 4
  if (deviceId == "El-ID-de-tu-Dispositivo") // Device ID of first device
  {
    Serial.print("Turn on device id: ");
    Serial.println(deviceId);

    digitalWrite(relayPin4, HIGH); // turn on relay with voltage HIGH
  }
  else {
    Serial.print("Turn on for unknown device id: ");
    Serial.println(deviceId);
  }
}

void turnOff(String deviceId) {

  // Device 1
  if (deviceId == "El-ID-de-tu-Dispositivo") // Device ID of first device
  {
    Serial.print("Turn off Device ID: ");
    Serial.println(deviceId);

    digitalWrite(relayPin1, LOW);  // turn off relay with voltage LOW
  }
  else {
    Serial.print("Turn off for unknown device id: ");
    Serial.println(deviceId);
  }

  // Device 2
  if (deviceId == "El-ID-de-tu-Dispositivo") // Device ID of first device
  {
    Serial.print("Turn off Device ID: ");
    Serial.println(deviceId);

    digitalWrite(relayPin2, LOW);  // turn off relay with voltage LOW
  }
  else {
    Serial.print("Turn off for unknown device id: ");
    Serial.println(deviceId);
  }

  // Device 3
  if (deviceId == "El-ID-de-tu-Dispositivo") // Device ID of first device
  {
    Serial.print("Turn off Device ID: ");
    Serial.println(deviceId);

    digitalWrite(relayPin3, LOW);  // turn off relay with voltage LOW
  }
  else {
    Serial.print("Turn off for unknown device id: ");
    Serial.println(deviceId);
  }

  // Device 4
  if (deviceId == "El-ID-de-tu-Dispositivo") // Device ID of first device
  {
    Serial.print("Turn off Device ID: ");
    Serial.println(deviceId);

    digitalWrite(relayPin4, LOW);  // turn off relay with voltage LOW
  }
  else {
    Serial.print("Turn off for unknown device id: ");
    Serial.println(deviceId);
  }
}

void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
  switch (type) {
    case WStype_DISCONNECTED:
      isConnected = false;
      Serial.printf("[WSc] Webservice disconnected from sinric.com!\n");
      break;
    case WStype_CONNECTED: {
        isConnected = true;
        Serial.printf("[WSc] Service connected to sinric.com at url: %s\n", payload);
        Serial.printf("Waiting for commands from sinric.com ...\n");
      }
      break;
    case WStype_TEXT: {
        Serial.printf("[WSc] get text: %s\n", payload);
        // Example payloads

        // For Switch or Light device types
        // {"deviceId": xxxx, "action": "setPowerState", value: "ON"} // https://developer.amazon.com/docs/device-apis/alexa-powercontroller.html

        // For Light device type
        // Look at the light example in github

        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject((char*)payload);
        String deviceId = json ["deviceId"];
        String action = json ["action"];

        if (action == "setPowerState") { // Switch or Light
          String value = json ["value"];
          if (value == "ON") {
            turnOn(deviceId);
          } else {
            turnOff(deviceId);
          }
        }
        else if (action == "SetTargetTemperature") {
          String deviceId = json ["deviceId"];
          String action = json ["action"];
          String value = json ["value"];
        }
        else if (action == "test") {
          Serial.println("[WSc] received test command from sinric.com");
        }
      }
      break;
    case WStype_BIN:
      Serial.printf("[WSc] get binary length: %u\n", length);
      break;
  }
}

void setup() {
  Serial.begin(115200);

  // Relay PIN eg: https://github.com/wemos/D1_mini_Examples/blob/master/examples/04.Shields/Relay_Shield/Blink/Blink.ino
  pinMode(relayPin1, OUTPUT);
  pinMode(relayPin2, OUTPUT);
  pinMode(relayPin3, OUTPUT);
  pinMode(relayPin4, OUTPUT);
  

  WiFiMulti.addAP(MySSID, MyWifiPassword);
  Serial.println();
  Serial.print("Connecting to Wifi: ");
  Serial.println(MySSID);

  // Waiting for Wifi connect
  while (WiFiMulti.run() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  if (WiFiMulti.run() == WL_CONNECTED) {
    Serial.println("");
    Serial.print("WiFi connected. ");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  }

  // server address, port and URL
  webSocket.begin("iot.sinric.com", 80, "/");

  // event handler
  webSocket.onEvent(webSocketEvent);
  webSocket.setAuthorization("apikey", MyApiKey);

  // try again every 5000ms if connection has failed
  webSocket.setReconnectInterval(5000);   // If you see 'class WebSocketsClient' has no member named 'setReconnectInterval' error update arduinoWebSockets
}

void loop() {
  webSocket.loop();

  if (isConnected) {
    uint64_t now = millis();

    // Send heartbeat in order to avoid disconnections during ISP resetting IPs over night. Thanks @MacSass
    if ((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) {
      heartbeatTimestamp = now;
      webSocket.sendTXT("H");
    }
  }
}

// If you are going to use a push button to on/off the switch manually, use this function to update the status on the server
// so it will reflect on Alexa app.
// eg: setPowerStateOnServer("deviceid", "ON")

// Call ONLY If status changed. DO NOT CALL THIS IN loop() and overload the server.
void setPowerStateOnServer(String deviceId, String value) {
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["deviceId"] = deviceId;
  root["action"] = "setPowerState";
  root["value"] = value;
  StreamString databuf;
  root.printTo(databuf);

  webSocket.sendTXT(databuf);
}

//eg: setPowerStateOnServer("deviceid", "CELSIUS", "25.0")

// Call ONLY If status changed. DO NOT CALL THIS IN loop() and overload the server.
void setTargetTemperatureOnServer(String deviceId, String value, String scale) {
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["action"] = "SetTargetTemperature";
  root["deviceId"] = deviceId;

  JsonObject& valueObj = root.createNestedObject("value");
  JsonObject& targetSetpoint = valueObj.createNestedObject("targetSetpoint");
  targetSetpoint["value"] = value;
  targetSetpoint["scale"] = scale;

  StreamString databuf;
  root.printTo(databuf);

  webSocket.sendTXT(databuf);
}

Rellena los siguientes apartados con tus datos:

  • Tu-Api-Key-de-Sinric.
  • El-Nombre-de-tu-WIFI
  • La-Contraseña-de-tu-WIFI
  • El-ID-de-tu-Dispositivo

Carga el archivo “ino” en la tarjeta Arduino.

Ahora queda montar tu tarjeta Arduino Wemos con la placa de reles, hacer las conexiones entre Arduino y reles, y las conexiones para la corriente electrica de los enchufes que utilices.

Para comprobar que todo funciona correctamente, aun nos queda realizar un paso más.

Desde la aplicación “Amazon Aleza“, de tu dispositivo móvil, instala la skill de “Sinric“, puedes ver más información pinchando en el enlace.

Una vez configurada debes pulsar en “Más” y “Añadir dispositivo“. Pulsa sobre uno de los dispositivos, por ejemplo “Luz“, y en la siguiente pantalla, pulsa en “Otro“. Pulsa en el botón “Detectar Dispositivos“. Si todo fue bien, pasados unos minutos, Alexa habra detectado los nuevos dispositivos.

Dile a Alexa que encienda alguno de los dispositivos que has creado en Sinric.

Recuerda que estos dispositivos se comportan exactamente como cualquier otro dispositivo que has comprado. Creando rutinas, puedes programarlo para que se encienda/apage a una hora determinada o cuando se produzca un determinado evento.



Si encuentras esta noticia interesante la puedes compartir en tus redes sociales, a tus seguidores les puede gustar. Utiliza los botones que tienes más abajo.

Share

Crear notas adhesivas con HTML y CSS

CSS dispone de increíbles posibilidades para el diseño de los proyectos en HTML, casi cualquier cosa es posible.

Con CSS puedes convertir una lista en unas bonitas notas adhesivas muy llamativas, simulando las notas reales en papel. Al pasar el cursor del ratón por una de las notas, esta, creará un efecto de zoom.

Código HTML:

<!DOCTYPE html>
<html>
    <head>
        <title>Notas adhesivas</title>
        <link rel="stylesheet" href="style.css" type="text/css">
        <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Reenie+Beanie:regular" type="text/css">
    </head>


    <body>

        <div>
            <ul>
                <li>
                    <a href="#">
                    <h2>Nota #1</h2>
                    <p>Buscar cursos gratuitos de tecnologías para Inteligencia Artificial</p>
                    </a>
                </li>
                <li>
                    <a href="#">
                    <h2>Nota #2</h2>
                    <p>Compar el pan para el pinic de mañana</p>
                    </a>
                </li>
            </ul>
        </div>

        <div>
            <ul>
                <li>
                    <a href="#">
                    <h2>Nota #3</h2>
                    <p>Comprobar el funcionamiento correcto del calentador de agua</p>
                    </a>
                </li>
                <li>
                    <a href="#">
                    <h2>Nota #4</h2>
                    <p>Comprobar funcionamiento aplicación medición temperaturas</p>
                    </a>
                </li>
            </ul>
        </div>

    </body>

</html>

Código CSS:

* {
    margin: 0;
    padding: 0;
}

body {
    font-family: arial, sans-serif;
    font-size: 100%;
    margin: 3em;
    background: #666;
    color: #fff;
}

h2,
p {
    font-size: 100%;
    font-weight: normal;
}

ul,
li {
    list-style: none;
}

ul {
    overflow: hidden;
    padding: 3em;
}


/* Parametros de la nota, medidas, color, etc. */

ul li a {
    text-decoration: none;
    color: #000;
    background: #ffc;
    display: block;
    height: 25em;
    width: 25em;
    padding: 1em;
}

ul li {
    margin: 1em;
    float: left;
}

ul li h2 {
    font-size: 140%;
    font-weight: bold;
    padding-bottom: 10px;
}

ul li p {
    font-family: "Reenie Beanie", arial, sans-serif;
    font-size: 280%;
}


/* Añade el sombreado */

ul li a {
    text-decoration: none;
    color: #000;
    background: #ffc;
    display: block;
    height: 25em;
    width: 25em;
    padding: 1em;
    /* Firefox */
    -moz-box-shadow: 5px 5px 7px rgba(33, 33, 33, 1);
    /* Safari+Chrome */
    -webkit-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
    /* Opera */
    box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
}


/* Inclinar las notas */

ul li a {
    -webkit-transform: rotate(-6deg);
    -o-transform: rotate(-6deg);
    -moz-transform: rotate(-6deg);
}


/* Inclinar notas al azar */

ul li:nth-child(even) a {
    -o-transform: rotate(4deg);
    -webkit-transform: rotate(4deg);
    -moz-transform: rotate(4deg);
    position: relative;
    top: 5px;
}

ul li:nth-child(3n) a {
    -o-transform: rotate(-3deg);
    -webkit-transform: rotate(-3deg);
    -moz-transform: rotate(-3deg);
    position: relative;
    top: -5px;
}

ul li:nth-child(5n) a {
    -o-transform: rotate(5deg);
    -webkit-transform: rotate(5deg);
    -moz-transform: rotate(5deg);
    position: relative;
    top: -10px;
}


/* Añadir trancisión y colores suaves */

ul li a {
    text-decoration: none;
    color: #000;
    background: #ffc;
    display: block;
    height: 25em;
    width: 25em;
    padding: 1em;
    -moz-box-shadow: 5px 5px 7px rgba(33, 33, 33, 1);
    -webkit-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
    box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
    -moz-transition: -moz-transform .15s linear;
    -o-transition: -o-transform .15s linear;
    -webkit-transition: -webkit-transform .15s linear;
}

ul li:nth-child(even) a {
    -o-transform: rotate(4deg);
    -webkit-transform: rotate(4deg);
    -moz-transform: rotate(4deg);
    position: relative;
    top: 5px;
    background: #cfc;
}

ul li:nth-child(3n) a {
    -o-transform: rotate(-3deg);
    -webkit-transform: rotate(-3deg);
    -moz-transform: rotate(-3deg);
    position: relative;
    top: -5px;
    background: #ccf;
}


/* Zoom en las notas al pasar por encima */

ul li a:hover,
ul li a:focus {
    -moz-box-shadow: 10px 10px 7px rgba(0, 0, 0, .7);
    -webkit-box-shadow: 10px 10px 7px rgba(0, 0, 0, .7);
    box-shadow: 10px 10px 7px rgba(0, 0, 0, .7);
    -webkit-transform: scale(1.25);
    -moz-transform: scale(1.25);
    -o-transform: scale(1.25);
    position: relative;
    z-index: 5;
}
Ejemplo etiquetas adhesivas



Si encuentras esta noticia interesante la puedes compartir en tus redes sociales, a tus seguidores les puede gustar. Utiliza los botones que tienes más abajo.

Share

Al instalar Postgresql, no funciona el comando psql

Puede ser que ya realizaste la instalación de Postgresql, ese gran motor de bases de datos, profesional y open source, una maravilla para la realización de proyecto que requieren el almacenamiento de datos.

Un problema bastante común al realizar dicha instalación es que desde la terminal no tenemos acceso al comando “psql“.

Psql, es la herramienta que nos permite administrar nuestras bases de datos en Postgresql. Es cierto que también podemos realizar las mismas tareas y de forma gráfica con pgAdmin, u otras aplicaciones para gestionar bases de datos, Navicat o SQLpro.

En Mac OS X, Postgresql se instala en, “/Applications/Postgres.app/Contents/Versions/??“. Donde “??“, es la versión que se instalo.

Para poder utilizar psql, debemos añadir la siguiente ruta a “PATH“, “/Applications/Postgres.app/Contents/Versions/11/bin“, en el caso de que la versión sea la 11. Si tu versión es otra, debes cambiarlo por la tuya. Si no sabes que versión se ha instalado de postgresql, ve a la carpeta “Aplicaciones“, busca “Postgres.app“, pincha con el botón secundario del ratón y selecciona “Mostar contenido del paquete“. Se abrira una nueva carpeta, abre, Contents, Versions, y ya veras la versión de tu instalación de postgres.

Sabiendo ya este dato, ejecuta en la terminal el siguiente comando:

export PATH="/Applications/Postgres.app/Contents/Versions/11/bin:$PATH"

No te olvides de sustituir “11“, por tu versión.

Ahora ya puedes utilizar psql desde la terminal de Mac OS X.



Si encuentras esta noticia interesante la puedes compartir en tus redes sociales, a tus seguidores les puede gustar. Utiliza los botones que tienes más abajo.

Share

Crea un log fácilmente para tus proyectos en Python

Un fichero de registro o log nos permite llevar una cronología de lo que va sucediendo en nuestra aplicación. Podemos registrar con facilidad todos aquellos procesos, fallos y errores que consideramos oportunos, esto nos permite poder encontrar fallos y errores presentes en el script que ejecutamos.

Esta utilidad esta presente en el modulo “logging“. Nos permite crear de forma fácil y rápida los archivos log en nuestros proyectos.

Logging dispone de 5 métodos para notificar los diferentes mensajes:

  • Debug. Normalmente se utiliza cuando estamos desarrollando nuestra aplicación, nos permite depurar el proyecto.
  • Info. Mensajes informativos. Pueden indicar que los procesos se realizan de forma correcta.
  • Warning. Utilizado para realizar advertencias, algo puede no ir bien o causar problemas en un futuro proximo.
  • Error. Algo ha salido mal o el resultado no es el esperado.
  • Critical. Posiblemente el programa deje de funcionar o responder.

Podemos configurar logging para que cree un archivo de texto, en el cual se guardarán los mensajes que vamos colocando en el código.

import logging
from datetime import datetime, date, time

ahora = datetime.now()
fecha_log = ahora.strftime('%d-%m-%Y_%H-%M-%S')

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s : %(levelname)s : %(message)s',
                    filename = fecha_log + '_registro.log',
                    filemode = 'w',)
  • Level. Nivel del mensaje.
  • Format. El formato en el cual serán guardados los mensajes.
  • Filename. El archivo que contendrá el log.
  • Filemode. El modo del archivo.

Ejemplo del formato de salida de los mensajes:

Ahora solo nos queda añadir la salida de los mensajes en los lugares de nuestra aplicación que consideremos más oportunos, propensos a errores, criticos o simplemente informativos.

El formato para los mensajes es el siguiente:

logging.debug('Información detallada, generalmente de interés solo cuando se diagnostican problemas.')
logging.info('Confirmación de que las cosas funcionan como se esperaba.')
logging.warning('Una indicación de que sucedió algo inesperado o indicativo de algún problema en el futuro cercano (por ejemplo, "espacio en disco bajo"). El software sigue funcionando como se esperaba.')
logging.error('Debido a un problema más serio, el software no ha podido realizar alguna función.')
logging.critical('Un error grave que indica que el programa en sí no puede continuar ejecutándose.')

Aqui, puedes encontrar la documentación oficial de logging.



Si encuentras esta noticia interesante la puedes compartir en tus redes sociales, a tus seguidores les puede gustar. Utiliza los botones que tienes más abajo.

Share