Categorías
Linux

Can’t login Elementary OS after changing icon set

After trying to change the default icon set in Elementary OS, I was not able to log in again into the desktop. This happened to me after installing the Qogir-icon-theme. After trying to restore to the default values changing at /etc/lightdm/lightdm.conf and /etc/lightdm/io.elementary.greeter.conf, the only thing that restored the graphical login was the following:

1. On the login screen, press Ctrl + Alt + F1 or Ctrl + Alt + F2 to open a virtual console.
2. Remove elementary-tweaks:

sudo apt purge elementary-tweaks

3. Remove all icon related folders at /usr/share/icons and ~/.local/share/icons
4. Reboot and hopefully, you will be able to login again in graphic mode.
5. The icons might not be the ‘elementary’ default set. So to fix this you will need to install again elementary-tweaks and configure it:

sudo apt install elementary-tweaks
Categorías
Linux

Transfer data from Android to PC using rsync

  1. Install SimpleSSHD in your mobile
  2. Start the data transfer with the rsync command:
rsync --update --progress -e 'ssh -p 2222' -azv 192.168.1.112:/sdcard/DCIM/Camera /computer-path

The password will be autogenerated and shown in the mobile display for every SSH connection.

Categorías
Linux

Send audio from mobile phone (Android/iOS) to Raspberry

Platform used: Raspberry Pi 3 B+
Bluetooth module: built-in
First, update firmware to make sure you have latest version:

sudo rpi-update

Now, install all the needed pulse-audio packages:

 sudo apt install pulseaudio-*.

Configure the bluetooth in the Raspberry:

pi@raspberrypi:~ $ bluetoothctl
[NEW] Controller XX:XX:XX:XX:XX:XX raspberrypi [default]
[bluetooth]# power on
Changing power on succeeded
[bluetooth]# agent NoInputNoOutput
Agent registered
[bluetooth]# default-agent
Default agent request successful
[bluetooth]# discoverable on
Changing discoverable on succeeded
[CHG] Controller B8:27:EB:DB:58:46 Discoverable: yes
[bluetooth]# pairable on
Changing pairable on succeeded

In your mobile phone, search for the raspberry bluetooth signal and pair to it:

[Noname]# connect XX:XX:XX:XX:XX:XX
Attempting to connect to XX:XX:XX:XX:XX:XX
[CHG] Device XX:XX:XX:XX:XX:XX ServicesResolved: yes
Connection successful
[Noname]# trust XX:XX:XX:XX:XX:XX
Changing XX:XX:XX:XX:XX:XX trust succeeded
[CHG] Controller XX:XX:XX:XX:XX:XX Discoverable: no
[Noname]# exit

Now, you can try to play some audio in your mobile and it should be reproduced in the the Raspberry.
In my case, audio was driven out to the HDMI. In case you want to switch it through the Jack 3.5 mm output you can run:

sudo raspi-config

Then, select Advanced Options > Audio > Force 3.5 mm (‘headphone’) jack
With this all set, you can stream any audio such as the built-in music player, Spotify or YouTube to the Raspberry and from it to the connected speakers or HDMI display.

Finally, as the device has been stored as a trusted device, every time the Raspberry is booted, you won’t need to repeat this process. It will be so easy as connecting your mobile phone to the available raspberry bluetooth signal.

If sound sounds distorted, try restarting pulseaudio with:

pulseaudio -k

Handling with several devices

If you pair several devices, only first connected device will be able to stream audio. If I connect my computer to the raspberry and then I try to connect my mobile phone (both previously paired and trusted), phone connection will fail. First, I’ll need to disconenct my computer and only then I’ll be able to successfully connect to the raspberry with my mobile phone.

Categorías
Linux

Añadir bibliografía en LaTeX

Para añadir bibliografía en LaTeX a partir de un archivo BibTeX .bib, el archivo BibTeX debe tener la siguiente estrutura:

@article{CrystekMicrowave,
author = {{Crystek Microwave}},
title = {{CATTEN-0100-BNC}},
url = {http://www.crystek.com/microwave/spec-sheets/attenuator/CATTEN-0100-BNC.pdf}
}

En el archivo .tex, hay que añadir las siguientes intrucciones:

\bibliography{fileNameWithoutExtension}
\bibliographystyle{unsrt}

En \bibliographystyle{unsrt} el argumento puede ser:

plain Estilo normal. Se listan en orden alfabético
unsrt Igual que plain pero aparecen en orden de citación
alpha Igual que plain pero utiliza las etiquetas para identificar la cita en lugar de números
abbrv Igual que plain pero utiliza abreviaciones para los nombres, meses o nombres de revistas

Ahora para citar la referencia en el texto, hay que hacerlo con:

\cite{CrystekMicrowave}

Solo aquellas citas que se hayan llamado en el texto aparecerán en el apartado de referencias.
Si se está usando TexMaker, será necesario compilar varias veces BibTeX y varias veces la compilación rápida para ver los cambios reflejados.

Categorías
Linux

Solucionar configuración de brillo en ASUS ROG GL552W con Linux Mint

En el terminal:

sudo nano /etc/default/grub

Cambiar:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"

por:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_idle.max_cstate=1 acpi_osi= acpi_backlight=native"

Una vez hecho el cambio, guardar el archivo.

sudo update-grub

Finalmente, reiniciar el equipo.

Las teclas(Fn+F5/F6) deberían volver a funcionar.

Quizá sea necesario reconfigurar después de cada actualización del sistema.

Categorías
Electrónica Linux Telemática

Conexión Telegram-Raspberry

Gracias a los bots de Telegram, es sencillo interaccionar entre Telegram y una Raspberry. La idea es la siguiente:
Telegram-Raspberry
Desde la aplicación de Telegram, enviaremos un comando al servidor de Telegram. Se puede configurar mediante webhooks que redireccione este mensaje a un servidor propio con SSL, tal y como expliqué en una entrada anterior.. Este servidor con SSL reenviará la información a otro servidor montado sobre la Raspberry. En la Raspberry, recibiremos las notificaciones enviadas por el usuario. Para conseguir que el que el servidor con cifrado SSL consiga enviar a nuestra Raspberry la información, será necesario configurar la Raspberry con un IP estática y utilizar un servidor de DNS dinámicas, configurar nuestro router de casa para redireccionar todas las peticiones provinientes del exterior (de Internet) en el puerto 80 al puerto 80 de nuestra Raspberry. Este paso quizá sea el más complicado debido a la cantidad de pasos que hay que hacer, sin embargo es posible.

Sería posible utilizar un solo servidor para entregar el comando de Telegram directamente sobre la Raspberry. Sin embargo, es necesario que el servidor de la Raspberry cuente con un certificado SSL. La API de Telegram permite utilizar certificados autofirmados, sin embargo yo no lo he probado ya que disponía en el servidor de un certificado SSL de Let’s Encrypt.

En el servidor con SSL el código del archivo PHP es:

<?php
 
$bottoken = "myToken";
$website = "https://api.telegram.org/bot".$bottoken;
 
$update = file_get_contents('php://input');
$update = json_decode($update, TRUE);
 
$chatId = $update["message"]["chat"]["id"];
$message = $update["message"]["text"];
 
switch($message) {
        case "/radio":
		$result = file_get_contents('http://raspberryLocation/test.php');
		if(!strcmp($result, "Encendido"))
			sendMessage($chatId, "Enchufando radio");
		else
			sendMessage($chatId, "Apagando radio");
                break;
        case "/temperatura1":
                sendMessage($chatId, "La temperatura es de 18 ºC");
                break;
        default:
                sendMessage($chatId, "default");
}
 
function sendMessage ($chatId, $message) {
 
        $url = $GLOBALS['website']."/sendMessage?chat_id=".$chatId."&text=".urlencode($message);
        file_get_contents($url);
 
}
 
?>

Para interactuar con los pines GPIO de la Raspberry, es necesario utilizar la librería WiringPi. El principal problema que existe con esta librería es que se necesitan permisos de super usuario para poder utilizarla. Para hacer una prueba rápida, le he dado permisos de superusuario al usuario www-data, que es el que ejecuta los archivos PHP. Sin embargo, esto es potencialmente peligroso. En cuanto encuentre una solución la subiré.

En mi prueba, he hecho que al enviar un comando desde Telegram, ponga a nivel alto o bajo un pin GPIO. El script que corre en el servidor de la Raspberry cuenta de dos partes. Una escrita en C que se encarga de interaccionar con la libreria WiringPi y otra en PHP que ejecuta el programa en C propio para cada comando.

La parte de PHP es la siguiente (archivo test.php que es llamado por el servidor con SSL):

<?php
	exec("sudo ./switch", $return);
	echo($return[0]);
?>

El programa en C es el que se ejecuta con la instrucción exec() es el siguiente:

 
#include <stdio.h>    // Used for printf() statements
#include <wiringPi.h> // Include WiringPi library!
#include <fcntl.h>  //File management
#include <unistd.h>  //File checker
 
// Pin number declarations. We're using the Broadcom chip pin numbers.
const int radioPin = 4; // Radio pin
 
char radio[] = "radio";
 
int main(void)
{
 
    wiringPiSetupGpio(); // Initializa wiringPi -- utilizando los números de pines de Broadcom
    pinMode(radioPin, OUTPUT);
    FILE *fp;
    if(access(radio, F_OK) != -1){
    // file exists
        printf("Apagado");
        remove(radio);
        digitalWrite(radioPin, LOW);
    } else {
    // file doesn't exist
        printf("Encendido");
        fp = fopen(radio, "w+");
        fclose(fp);
        digitalWrite(radioPin, HIGH);
    }
        return 0;
}

Este programa es muy sencillo y simplemente comprueba que exista un archivo llamado radio en la carpeta donde se encuentra. Si el archivo existe, entonces quiere decir que la radio estaba encendida y por tanto elimina el archivo y apaga la radio. Si el archivo no existe, la radio estaba apagada y enciende la radio poniendo el pin a nivel alto y crea el archivo radio.

Para compilar este programa es necesario utilizar la siguiente instrucción:

gcc -Wall -o switch switch.c -lwiringPi

Es posible que sea necesario ejecutar el compilador gcc como superusuario añadiendo sudo si estáis en la carpeta del servidor (es decir /var/www).

De esta manera, es posible encender y apagar un relé, por ejemplo, si conectamos el pin en cuestión a la Raspberry. Por tanto, estaríamos controlando una lampara, una luz o una radio.

El resultado es el siguiente:

Categorías
Linux Telemática

Desde el año pasado, Telegram permite crear bots para poder interaccionar con un servidor de manera automática.

La manera de crear un bot se realiza a través del BotFather, un bot de Telegram que permite crear el tuyo propio. Una vez hayamos creado nuestro bot, BotFather nos dará un token. Este token es un identificador único que solo debes saber tú ya que te dará acceso a realizar cualquier acción sobre tu bot.

Una vez creado el bot, podemos enviarle mensajes, sin embargo, nadie contestará. Existen dos maneras para acceder a los mensajes que se hayan enviado por un usuario. La primera es mediante el método getUpdates, que básicamente consiste en una escucha activa mediante un bucle para detectar que alguien nos ha enviado un mensaje. Para comprobar rápidamente que los mensajes no están llegando, podemos pegar esta URL en el navegador, cambiando MYTOKEN por nuestro token real:

https://api.telegram.org/botMYTOKEN/getUpdates

De esta manera podremos ver qué mensajes están pendientes de ser respondidos.

Para responder desde el navegador, podemos utilizar el método sendMessage:

https://api.telegram.org/botMYTOKEN/sendMessage?chat_id=CHATID&text=TEXTO

En el que tendremos que cambiar MYTOKEN por nuestro token, CHATID por el ID del chat al cual queramos respondes y que habremos obtenido del método getUpdates (ver captura anterior), y TEXT por el texto que queramos enviar.

Sin embargo, con este método ya se ve que no es demasiado cómodo utilizar un bot de Telegram.

La mejor opción es utilizar un webhook. Un webhook es un archivo PHP (o cualquier otro lenguaje que podamos correr en nuestro servidor como Python, Ruby o Java) en el que cada vez que alguien envíe un mensaje a nuestro bot, Telegram hará una llamada automática a este archivo.

De esta manera podremos automatizar totalmente la interacción con nuestro bot.
Para decirle a Telegram dónde se encuentra nuestro webhook, es necesario ejecutar la siguiente URL:

https://api.telegram.org/botMYTOKEN/setWebhook?url=https://example.com/folder/file.php

Es muy importante que nuestro servidor tenga cifrado SSL para poder hacer peticiones HTTPS sobre él. Si no dispones de uno, te recomiendo que instales el certificado de Let’s Encrypt, el cual permite crear un certificado SSL de manera totalmente gratuita. Si por el contrario tienes un certificado autofirmado, Telegram te explica como enviarles tu clave pública del certificado.

El código PHP que he utilizado para mi bot es el siguiente:

<?php
 
$bottoken = "MYTOKEN";
$website = "https://api.telegram.org/bot".$bottoken;
 
$update = file_get_contents('php://input');
$update = json_decode($update, TRUE);
 
$chatId = $update["message"]["chat"]["id"];
$message = $update["message"]["text"];
 
switch($message) {
        case "/comando1":
                sendMessage($chatId, "Has enviado el comando 1");
                break;
        case "/comando2":
                sendMessage($chatId, "Has enviado el comando 2");
                break;
        default:
                sendMessage($chatId, "default");
}
 
function sendMessage ($chatId, $message) {
 
        $url = $GLOBALS['website']."/sendMessage?chat_id=".$chatId."&text=".urlencode($message);
        file_get_contents($url);
 
}
 
?>

De esta manera, podemos responder a cada comando que hayamos definido en el BotFather de manera personalizada.

Categorías
Linux

RSync

rsync es una herramienta para copiar archivos que es de gran utilidad cuando el número de archivos es bastante elevado. De esta manera podemos realizar copias de seguridad de manera mucho más rápida que a través de FTP o SFTP.

Para ello, necesitaremos hacer login a través de SSH. Cuando el puerto SSH no sea el predeterminado, lo podemos indicar de la siguiente manera

Servidor remoto -> Ordenador local

rsync -av --progress --rsh='ssh -pXXX' user@IP:/path-to-files/ --port=XXX ./local_destination

Donde

  • XXX es el puerto SSH,
  • /path-to-files es la carpeta o archivo que queremos copiar
  • local_destionation es la carpeta de nuestro ordenador donde queremos guardar los archivos.
Categorías
Linux

FFT de audio con Python

Una manera sencilla de realizar FFT desde cualquier sistema operativo sin necesidad de disponer de programas como MATLAB, Octave o Mathematica, es utilizando un script de Python. Este lenguaje cuenta con la ventaja de ser muy sencillo y además de disponer una ingente cantidad de librerías para poder hacer casi cualquier cosa.
El objetivo de este pequeño programa es realizar una FFT de un trozo de audio grabado directamente desde un micrófono. Para ello se realiza una escucha pasiva a la espera de un sonido cuyo volumen esté por encima de un determinado umbral. Este umbral se puede modificar con la variable threshold, y dependiendo del micrófono y su sensibilidad debe de ser ajustado de manera diferente. Una vez detectado, se graba unos pocos segundos de audio, cuya longitud puede ser modificada en el segundo bucle for. Actualmente graba aproximadamente 1 segundo, pero si se cambia el 7 por un 100 la longitud es de 13 segundos.
El audio se guarda como un archivo para ser posteriormente utilizado en el cálculo de la FFT y ser graficada al momento. Todo este procedimiento está dentro de un bucle infinito, por lo que, aunque la ventana de la gráfica es bloqueante, está continuamente escuchando.

Las librerías necesarias para poder ejecutar este script son: numpy, matplotlib, pyaudio y scipy.

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import pyaudio
import struct
import math
import wave
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
#import urllib  
#import urllib2 
import os
 
class Microphone:
 
    def rms(self,frame):
        count = len(frame)/2
        format = "%dh"%(count)
        shorts = struct.unpack( format, frame )
        sum_squares = 0.0
        for sample in shorts:
            n = sample * (1.0/32768.0)
            sum_squares += n*n
        rms = math.pow(sum_squares/count,0.5);
        return rms * 1000
 
 
    def passiveListen(self,persona):
 
        CHUNK = 1024; RATE = 8000; THRESHOLD = 200; LISTEN_TIME = 5
 
        didDetect = False
 
        # prepare recording stream
        p = pyaudio.PyAudio()
        stream = p.open(format=pyaudio.paInt16, channels=1, rate=RATE, input=True, frames_per_buffer=CHUNK)
 
        # stores the audio data
        all =[]
 
        # starts passive listening for disturbances 
        print RATE / CHUNK * LISTEN_TIME
        for i in range(0, RATE / CHUNK * LISTEN_TIME):
            input = stream.read(CHUNK)
            rms_value = self.rms(input)
            print rms_value
            if (rms_value < THRESHOLD):
                didDetect = True
                print "Listening...\n"
                break
 
        if not didDetect:
            stream.stop_stream()
            stream.close()
            return False
 
 
        # append all the chunks
        all.append(input)
        for i in range(0, 7):
            data = stream.read(CHUNK)
            all.append(data)
 
        # save the audio data   
        data = ''.join(all)
        stream.stop_stream()
        stream.close()
        wf = wave.open('audio.wav', 'wb')
        wf.setnchannels(1)
        wf.setsampwidth(p.get_sample_size(pyaudio.paInt16))
        wf.setframerate(RATE)
        wf.writeframes(data)
        wf.close()
 
        return True
 
if __name__ == '__main__':
    mic = Microphone()
    while True:
        if  mic.passiveListen('ok Google'):
            fs, data = wavfile.read('audio.wav')
            L = len(data)
            c = np.fft.fft(data) # create a list of complex number
            freq = np.fft.fftfreq(L)
            #freq = np.linspace(0, 1/(2L), L/2)
            print freq
            freq_in_hertz = abs(freq * fs)
            plt.plot(freq_in_hertz, abs(c))
            plt.show()
Categorías
Linux

Añadir ruta al $PATH

¿Cuantas veces hemos hecho ejecutado el siguiente comando desde el terminal de Linux?

$ ls -l

Lo que hace el sistema operativo es buscar un ejecutable llamado “ls” y lo abre. Las carpetas donde busca son las que componen la variable $PATH. Si queremos añadir una carpeta distinta que las que hay por defecto, lo que podemos hacer es:

$ gedit ~/.bashrc

Una vez gedit se haya abierto, si queremos añadir una única carpeta, simplemente pegamos la siguiente línea al final del archivo:

$ export PATH=${PATH}:$HOME/folder1/subfolder1$PATH

Para poder añadir más de una carpeta hay que escribirla a continuación de la anterior separándola con dos puntos de la siguiente manera:

$ export PATH=${PATH}:$HOME/folder1/subfolder1:/path/to/second/folder$PATH

Una vez guardado, cerramos gedit, cerramos el terminal y volvemos a abrir otro.
Ahora al ejecutar

$ echo $PATH

aparecerá la carpeta que hemos acabado de añadir, con lo que podremos ejecutar cualquier archivo ejecutable que haya dentro sin tener que especificar la ruta.