My Own Memory Hole

My Own Tmux Cheat Sheet

Il s'agit ici pour moi de réunir en un lien unique, clairement identifiable — pour moi du moins — un certain nombre de ressources consacrées à Tmux, collant le plus possible à mes petits besoins et à mon usage limité de ce « multiplexeur de terminaux ».

Installation et préparation de base

Tmux est disponible dans les dépôts et il suffit pour l'installer d'un :

sudo apt install tmux

Ensuite, on récupère et on place dans notre /home les fichiers de configuration proposé par Gregory Pakosz sur GitHub :

cd /home/$USER
git clone https://github.com/gpakosz/.tmux.git
ln -s -f .tmux/.tmux.conf
cp .tmux/.tmux.conf.local .

Configuration personnelle

...

Raccourcis claviers

Avec cette configuration proposée par Gregory Pakosz, le préfixe à utiliser est soit Ctrl+b, celui par défaut de tmux, soit Ctrl+a.

<prefix> " ou <prefix> - : partager le panneau horizontalement
<prefix> % ou <prefix> _ : partager le panneau verticalement
<prefix> c : créer un nouveau panneau
<prefix> x : détruire le panneau actif

<prefix> m : (dés)activer le mode souris

Copier-Coller

Pour profiter pleinement du copier-coller, il convient d'installer le paquet xclip et de bien avoir dans le fichier ~/.tmux.conf.local la ligne suivante :

tmux_conf_copy_to_os_clipboard=true

À la souris, il suffit de surligner le texte à copier et d'utiliser Alt+w.

Sinon, au clavier, il faut commencer par utiliser <prefix> [ pour entrer en mode copie, se rendre au début du texte à copier, appuyer sur Espace, se rendre à la fin et simplement appuyer sur Entrée.

MPD, PulseAudio et Bluetooth sous Raspbian Buster

Alors que je venais juste de mettre en place la cohabitation entre MPD et mon ampli connecté en Bluetooth sur mon Raspberry Pi 2 (voir ici), je basculais sur un modèle 4, modifiant quelque peu mes usages et utiisant cette fois-ci l'interface graphique (afin de profiter notamment de Spotify, une fois la gestion des DRM ajoutée). Et du coup, afin d'avoir une maîtrise plus fine de mes sorties audio, j'ai opté pour l'utilisation de PulseAudio.

On commence par purger bluealsa s'il est installé :

$ sudo apt purge bluealsa

puis on installe tout ce qui concerne le Bluetooth et PulseAudio :

 $ sudo apt install pi-bluetooth pulseaudio pulseaudio-module-bluetooth paprefs pavumeter pavucontrol pasystray

On vérifie la configuration de PulseAudio (/etc/pulse/default.pa) notamment pour ce qui est du Bluetooth :

### Automatically load driver modules for Bluetooth hardware
.ifexists module-bluetooth-policy.so
load-module module-bluetooth-policy
.endif

.ifexists module-bluetooth-discover.so
load-module module-bluetooth-discover
.endif

et on ajoute ces éléments :

# automatically switch to newly-connected devices
load-module module-switch-on-connect

load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 # IP of localhost

On tue PulseAudio :

$ pulseaudio -k

S'il ne redémarre pas tout seul, il suffit de lancer la commande :

$ pulseaudio -D

On veille à bien connecter notre enceinte Bluetooth via l'utilitaire en ligne de commande bluetoothctl : on commence par rechercher les périphériques disponibles (scan on), puis on lui accorde notre confiance (pas d'authentification nécessaire, trust) avant de faire l'appairage avec le bon device (pair) et de nous y connecter (connect)&bvsp;; on peut alors cesser la recherche (scan off) :

$ bluetoothctl 
Agent registered
[bluetooth]# scan on
Discovery started
[CHG] Controller 00:1A:7D:DA:71:15 Discovering: yes
[CHG] Device FC:58:FA:14:27:BC RSSI: -71
[CHG] Device FC:58:FA:14:27:BC TxPower: 4
[...]
[bluetooth]# pair FC:58:FA:14:27:BC 
Attempting to pair with FC:58:FA:14:27:BC
[CHG] Device FC:58:FA:14:27:BC Connected: yes
[...]
[CHG] Device FC:58:FA:14:27:BC ServicesResolved: yes
[CHG] Device FC:58:FA:14:27:BC Paired: yes
Pairing successful
[CHG] Device FC:58:FA:14:27:BC ServicesResolved: no
[CHG] Device FC:58:FA:14:27:BC Connected: no
[bluetooth]# trust FC:58:FA:14:27:BC 
[CHG] Device FC:58:FA:14:27:BC Trusted: yes
Changing FC:58:FA:14:27:BC trust succeeded
[bluetooth]# connect FC:58:FA:14:27:BC 
Attempting to connect to FC:58:FA:14:27:BC
[CHG] Device FC:58:FA:14:27:BC Connected: yes
Connection successful
[CHG] Device FC:58:FA:14:27:BC ServicesResolved: yes
[Tangent Ampster BT]# scan off
Discovery stopped
[...]
[Tangent Ampster BT]# exit

Pour la configuration de MPD, il est nécessaire d'identifier alors les sorties disponibles grâce à la commande suivante :

$ pacmd list-sinks
3 sink(s) available.
    index: 0
    name: <alsa_output.platform-bcm2835_audio.analog-mono>
    driver: <module-alsa-card.c>
    flags: HARDWARE DECIBEL_VOLUME LATENCY FLAT_VOLUME 
    state: SUSPENDED
    suspend cause: IDLE
    priority: 9009
    volume: mono: 38011 /  58% / -14,19 dB
            balance 0,00
    base volume: 65536 / 100% / 0,00 dB
    volume steps: 65537
    muted: no
    current latency: 0,00 ms
    max request: 0 KiB
    max rewind: 0 KiB
    monitor source: 0
    sample spec: s16le 1ch 44100Hz
    channel map: mono
                 Mono
    used by: 0
    linked by: 0
    fixed latency: 99,95 ms
    card: 0 <alsa_card.platform-bcm2835_audio>
    module: 6
    properties:
        alsa.resolution_bits = "16"
        device.api = "alsa"
        device.class = "sound"
        alsa.class = "generic"
        alsa.subclass = "generic-mix"
        alsa.name = "bcm2835 HDMI 1"
        alsa.id = "bcm2835 HDMI 1"
        alsa.subdevice = "0"
        alsa.subdevice_name = "subdevice #0"
        alsa.device = "0"
        alsa.card = "0"
        alsa.card_name = "bcm2835 HDMI 1"
        alsa.long_card_name = "bcm2835 HDMI 1"
        alsa.driver_name = "snd_bcm2835"
        device.bus_path = "platform-bcm2835_audio"
        sysfs.path = "/devices/platform/soc/fe00b840.mailbox/bcm2835_audio/sound/card0"
        device.form_factor = "internal"
        device.string = "hw:0"
        device.buffering.buffer_size = "8816"
        device.buffering.fragment_size = "2208"
        device.access_mode = "mmap"
        device.profile.name = "analog-mono"
        device.profile.description = "Mono analogique"
        device.description = "Audio interne Mono analogique"
        alsa.mixer_name = "Broadcom Mixer"
        module-udev-detect.discovered = "1"
        device.icon_name = "audio-card"
    ports:
        analog-output: Sortie analogique (priority 9900, latency offset 0 usec, available: unknown)
            properties:

    active port: <analog-output>
    index: 1
    name: <alsa_output.platform-bcm2835_audio.analog-mono.2>
    driver: <module-alsa-card.c>
    flags: HARDWARE HW_MUTE_CTRL HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY FLAT_VOLUME 
    state: SUSPENDED
    suspend cause: IDLE
    priority: 9009
    volume: mono: 7864 /  12% / -55,25 dB
            balance 0,00
    base volume: 56210 /  86% / -4,00 dB
    volume steps: 65537
    muted: no
    current latency: 0,00 ms
    max request: 0 KiB
    max rewind: 0 KiB
    monitor source: 1
    sample spec: s16le 1ch 44100Hz
    channel map: mono
                 Mono
    used by: 0
    linked by: 0
    fixed latency: 99,95 ms
    card: 1 <alsa_card.platform-bcm2835_audio.2>
    module: 7
    properties:
        alsa.resolution_bits = "16"
        device.api = "alsa"
        device.class = "sound"
        alsa.class = "generic"
        alsa.subclass = "generic-mix"
        alsa.name = "bcm2835 Headphones"
        alsa.id = "bcm2835 Headphones"
        alsa.subdevice = "0"
        alsa.subdevice_name = "subdevice #0"
        alsa.device = "0"
        alsa.card = "1"
        alsa.card_name = "bcm2835 Headphones"
        alsa.long_card_name = "bcm2835 Headphones"
        alsa.driver_name = "snd_bcm2835"
        device.bus_path = "platform-bcm2835_audio"
        sysfs.path = "/devices/platform/soc/fe00b840.mailbox/bcm2835_audio/sound/card1"
        device.form_factor = "internal"
        device.string = "hw:1"
        device.buffering.buffer_size = "8816"
        device.buffering.fragment_size = "2208"
        device.access_mode = "mmap"
        device.profile.name = "analog-mono"
        device.profile.description = "Mono analogique"
        device.description = "Audio interne Mono analogique"
        alsa.mixer_name = "Broadcom Mixer"
        module-udev-detect.discovered = "1"
        device.icon_name = "audio-card"
    ports:
        analog-output-headphones: Casque audio (priority 9000, latency offset 0 usec, available: unknown)
            properties:
                device.icon_name = "audio-headphones"
    active port: <analog-output-headphones>
  * index: 2
    name: <bluez_sink.FC_58_FA_14_27_BC.a2dp_sink>
    driver: <module-bluez5-device.c>
    flags: HARDWARE DECIBEL_VOLUME LATENCY FLAT_VOLUME 
    state: RUNNING
    suspend cause: (none)
    priority: 9550
    volume: front-left: 65536 / 100% / 0,00 dB,   front-right: 65536 / 100% / 0,00 dB
            balance 0,00
    base volume: 65536 / 100% / 0,00 dB
    volume steps: 65537
    muted: no
    current latency: 58,01 ms
    max request: 3 KiB
    max rewind: 0 KiB
    monitor source: 2
    sample spec: s16le 2ch 44100Hz
    channel map: front-left,front-right
                 Stéréo
    used by: 1
    linked by: 1
    fixed latency: 45,32 ms
    card: 2 <bluez_card.FC_58_FA_14_27_BC>
    module: 28
    properties:
        bluetooth.protocol = "a2dp_sink"
        device.description = "Tangent Ampster BT"
        device.string = "FC:58:FA:14:27:BC"
        device.api = "bluez"
        device.class = "sound"
        device.bus = "bluetooth"
        device.form_factor = "speaker"
        bluez.path = "/org/bluez/hci0/dev_FC_58_FA_14_27_BC"
        bluez.class = "0x240414"
        bluez.alias = "Tangent Ampster BT"
        device.icon_name = "audio-speakers-bluetooth"
    ports:
        speaker-output: Haut-parleur (priority 0, latency offset 0 usec, available: yes)
            properties:

    active port: <speaker-output>

De là, on peut configurer les sorties dans MPD :

$ sudo nano /etc/mpd.conf
audio_output {
        type            "pulse"
        name            "Tangent Ampster BT"
        server          "127.0.0.1"            
        sink            "bluez_sink.FC_58_FA_14_27_BC.a2dp_sink"       
        mixer_type      "software"
}
audio_output {
        type            "pulse"
        name            "HDMI 1 Output"
        server          "127.0.0.1"            
        sink            "alsa_output.platform-bcm2835_audio.analog-mono"     
        mixer_type      "software"
}

On relance MPD et l'affaire est jouée :

$ sudo service mpd restart

Gestion des DRM sous Raspbian Buster

Le passage de mon Raspberry Pi dans sa vieillissante version 2 à une version 4 m'a permis d'étendre les usages que je fais de ce nano-ordinateur, et notamment de pouvoir regarder myCanal – sans avoir à brancher un autre ordinateur sur la télé... – ou encore de basculer sur le lecteur web de Spotify lorsque ma discothèque personnelle ne me suffit plus.
Mais ces plateformes, comme tant d'autres, protègent leurs contenus avec des DRM qui ne sont pas pris en charge sur l'architecture ARM...

La solution la plus simple à mettre en œuvre, sous réserve que vous ayiez opté pour une version 32 bit de Raspbian, c'est encore de délaisser Chromium pour Vivaldi et de suivre leurs astuces pour une utilisation sur le Raspberry Pi, qui renvoie notamment à ce script.

On commence par récupérer le contenu du script :

$ wget https://gist.githubusercontent.com/ruario/19a28d98d29d34ec9b184c42e5f8bf29/raw/6ff95fa30a291319700b5a75dd558038d3e202c5/widevine-flash_armhf.sh

On le rend exécutable et on le lance :

$ chmod +x widevine-flash_armhf.sh && ./widevine-flash_armhf.sh

avant de suivre les instructions fournies :

$ sudo tar Cfx / widevine-flash-20200124_armhf.tgz
$ mkdir -p ~/.config/vivaldi{,-snapshot}/WidevineCdm
$ echo '{"Path":"/opt/WidevineCdm"}' | tee ~/.config/vivaldi/WidevineCdm/latest-component-updated-widevine-cdm > ~/.config/vivaldi-snapshot/WidevineCdm/latest-component-updated-widevine-cdm

Station météo Netatmo & WeeWX

Dans le cadre de la «digitalisation» de La Sculpture : les Pluies de Patrick Dubrac, nous cherchons à aller au-delà de ce que nous avons mis en place avec Le Calendrier des pluies, mis à jour mensuellement à partir des données météorologiques quotidiennes. D'où l'idée de développer un prototype associant une station météo Netatmo à un Raspberry Pi sur lequel serait installé WeeWX, un petit programme en Python qui permet d'interagir avec de multiples modèles de stations météo, de publier les données sur de multiples sites, de conserver les données dans des bases de données...

Cependant, le pilote pour les stations Netatmo (https://github.com/matthewwall/weewx-netatmo) n'est pas compatible avec la version 4 de WeeWX... On bascule donc sur la dernière des versions 3 de WeeWX disponibles, la 3.9.2 :

$ wget http://weewx.com/downloads/released_versions/weewx-3.9.2.tar.gz

On installe les dépendances nécessaires :

$ sudo apt install python-configobj python-pil python-serial python-usb python-pip python-cheetah python-ephem mariadb-client python-mysqldb

Puis on lance l'installation :

$ tar xvfz weewx-3.9.2.tar.gz
$ cd weewx-3.9.2
$ python2 setup.py build
$ sudo python setup.py install

L'ensemble des exécutables se trouve dans /home/weewx/bin/ ; le fichier de configuration est à l'emplacement /home/weewx/weewx.conf

On installe ensuite le pilote weewx-netatmo (https://github.com/matthewwall/weewx-netatmo) :

$ wget -O weewx-netatmo.zip https://github.com/matthewwall/weewx-netatmo/archive/master.zip
$ sudo /home/weewx/bin/wee_extension --install weewx-netatmo.zip

Puis on configure weewx :

$ sudo /home/weewx/bin/wee_config --reconfigure

On édite ensuite le fichier de configuration à la main  :

$ sudo nano /home/weewx/weewx.conf

On s'assure que nos identifiants Netatmo sont bien pris en compte et on bascule, dans la sous-section [[wx_binding]] de la section [DataBindings] sur une base de données MySQL :

database = archive_mysql

On crée une base de données avec les mêmes identifiants que ceux que nous avons indiqués dans la sous-section [[archive_mysql]] de la secion [Databases], par défaut :

    # MySQL
    [[archive_mysql]]
        database_name = weewx
        database_type = MySQL
$ sudo mysql -u root -p
MariaDB [(none)]> CREATE DATABASE weewx;
MariaDB [(none)]> CREATE USER 'weewx'@localhost IDENTIFIED BY 'weewx';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON weewx.* TO 'weewx'@localhost;
MariaDB [(none)]> FLUSH PRIVILEGES;

Enfin, on fait en sorte que WeeWX soit lancé au démarrage comme un service :

$ cd /home/weewx
$ sudo cp util/init.d/weewx.debian /etc/init.d/weewx
$ sudo chmod +x /etc/init.d/weewx
$ sudo update-rc.d weewx defaults 98
$ sudo /etc/init.d/weewx start

Générer des playlists pour MPD avec les dernières pistes ajoutées

Afin de retrouver facilement dans ncmpcpp les dernières pistes ajoutées à ma bibliothèque, j'ai trouvé et adapté le script suivant.

$ nano ~/bin/lastaddedmpd
#!/bin/bash

cd /home/$USER/NAS/Musique
find . -type f -ctime -1 | egrep '\.mp3$|\.flac$' | awk '{ sub(/^\.\//, ""); print }' | sort -n > /home/$USER/NAS/Musique/playlists/$(date +%d-%m-%Y)_last_$1_days.m3u
$ chmod +x ~/bin/lastaddedmpd

Et on lance la commande lastaddedmpd avec pour argument le nombre de jours à prendre en compte.

MPD et Bluetooth sur Raspberry Pi 2

Afin d'utiliser pleinement mon « système multimédia » à base d'un NAS et d'un Raspberry Pi – qui commence à se faire vieillissant puisque dans sa vesion 2 –sur lequel tourne un serveur MPD, je souhaitais connecter via Bluetooth ce dernier à mon petit amplificateur Tangent Ampster BT.

Connexion Bluetooth

J'ai fait l'aquisition d'un dongle USB/Bluetooth TP-Link reconnu, dans mon souvenir, nativement sous Raspbian Buster, sous réserve d'avoir bien installé le paquet pi-bluetooth :

sudo apt install pi-bluetooth

Pour connecter l'ampli au Raspberry Pi, on utilise l'utilitaire en ligne de commande bluetoothctl : on commence par rechercher les périphériques disponibles (scan on), puis on fait l'appairage avec le bon device (pair) et on lui accorde notre confiance (pas d'authentification nécessaire, trust) avant de nous y connecter (connect) et de cesser la recherche (scan off) :

$ bluetoothctl 
Agent registered
[bluetooth]# scan on
Discovery started
[CHG] Controller 00:1A:7D:DA:71:15 Discovering: yes
[CHG] Device FC:58:FA:14:27:BC RSSI: -71
[CHG] Device FC:58:FA:14:27:BC TxPower: 4
[...]
[bluetooth]# pair FC:58:FA:14:27:BC 
Attempting to pair with FC:58:FA:14:27:BC
[CHG] Device FC:58:FA:14:27:BC Connected: yes
[...]
[CHG] Device FC:58:FA:14:27:BC ServicesResolved: yes
[CHG] Device FC:58:FA:14:27:BC Paired: yes
Pairing successful
[CHG] Device FC:58:FA:14:27:BC ServicesResolved: no
[CHG] Device FC:58:FA:14:27:BC Connected: no
[bluetooth]# trust FC:58:FA:14:27:BC 
[CHG] Device FC:58:FA:14:27:BC Trusted: yes
Changing FC:58:FA:14:27:BC trust succeeded
[bluetooth]# connect FC:58:FA:14:27:BC 
Attempting to connect to FC:58:FA:14:27:BC
[CHG] Device FC:58:FA:14:27:BC Connected: yes
Connection successful
[CHG] Device FC:58:FA:14:27:BC ServicesResolved: yes
[Tangent Ampster BT]# scan off
Discovery stopped
[...]
[Tangent Ampster BT]# exit

Cependant, si à l'étape de la connexion à l'ampli, vous obtenez une erreur, il convient alors d'installer le paquet pulseaudio-module-bluetooth  :

$ sudo apt install pulseaudio-module-bluetooth

Ouvez ensuite le fichier /etc/pulse/default.pa et vérifiez aux alentours des lignes 65-67 que vous avez bien :

.ifexists module-bluetooth-discover.so
load-module module-bluetooth-discover
.endif

et ajoutez à la fin du fichier :

# automatically switch to newly-connected devices
load-module module-switch-on-connect

Lancez alors pulseaudio avec la commande pulseaudio -D après l'avoir tué si besoin (pulseaudio -k) puis relancez la commande connect dans l'outil bluetoothctl.

Configurer de nouvelles sorties dans MPD

Une nouvelle fois, je ne suis pas parvenu à configurer MPD pour qu'il utilise PulseAudio... On s'en tient donc à ALSA et au « Bluetooth Audio ALSA Backend » bluealsa que l'on commence par installer :

$ sudo apt install bluealsa

Puis on « crée » de nouveaux périphériques audio pour l'ensemble du système et de ses utilisateurs :

sudo nano /etc/asound.conf
pcm.tangent {
    type plug
    slave {
        pcm {
            type bluealsa
            device FC:58:FA:14:27:BC
            profile "a2dp"
        }
  }
  hint {
    show on
    description "Tangent Ampster BT"
    }
}

pcm.jblgo {
  type plug
  slave {
    pcm {
      type bluealsa
      device 78:44:05:61:4C:17
      profile "a2dp"
    }
  }
  hint {
    show on
    description "JBL Go"
  }
}

On en vient ensuite à la configuration de MPD auquel on doit déclarer les nouvelles sorties à utiliser :

audio_output {
        type            "alsa"
        name            "Tangent Ampster BT - ALSA Bluetooth"
        device          "tangent"
        mixer_type  "software"
    format          "44100:16:2"
}
audio_output {
        type            "alsa"
        name            "JBL Go - ALSA Bluetooth"
        device          "jblgo"
        mixer_type      "software"
}

Et on relance le service :

$ sudo service mpd restart