Raspberry Pi Bitcoin Ticker

Bricolage pour avoir un petit objet qui affiche en temps réel l’évolution d’un portefeuille de cryptomonnaies.

Coin Ticker Desaille.fr

L’idée du truc est d’afficher les variations d’un portefeuille de cryptomonnaies, dans mon cas du Bitcoin et de l’Ethereum, par rapport à un investissement initial en euros.

En gros on a :

  • Variation sur les dernières 24h
  • Variation sur la dernière heure
  • Variation sur les dernier 7 jours
  • Variation par rapport à l’investissement initial
  • Le nombre de block avant le fork Segwit2x

Pour monter ça je me suis basé sur le matériel suivant :

Pour le boitier j’ai commandé ce kit (PI + Boitier + GPIO) sur Amazon et j’ai légèrement adapté le boitier pour que cela rentre à peu près correctement.

Au niveau du montage rien de bien compliqué, prévoir un fer à souder pour monter les connecteur GPIO comme dans la vidéo ci dessous :

Ensuite il faut passer a la config du raspberry pi zero qui peut d’ailleurs se faire très simplement sans écran voir cet article.

Une fois connecté il faut paramétrer le système pour utiliser le GPIO et installer les drivers et librairies permettant de piloter l’afficher E-ink. La procédure est disponible ici, valider que tout fonctionne bien en utilisant le code de démonstration fourni par waveshare.

L’afficheur marche vraiment bien et niveau lisibilité c’est top par rapport à un écran LCD bas de gamme, de plus il n’y a de consommation électrique que lors du rafraîchissement de l’affichage, les données resteront affichées même l’alimentation débranchée.

Au niveau du code c’est du python le repo est disponible ici sur Github (package avec les librairies de l’afficheur E-Ink)
Pour résumer on va générer un fichier image avec toutes les infos que l’on souhaite afficher, l’enregistrer puis l’afficher sur le E-Ink Display, on renouvelle l’opération toutes les 30s. Les valeurs des cryptos sont récupérées depuis l’API de CoinMarketCap

Voici le script :

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import requests
import epd2in13
import time
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

# Valeurs des Cryptomonnaies
ETHBAL = float(1)
BTCBAL = float(0.55)
# Investissement initial (euros)
BASE = float(2700)

def connection_check():
    try:
        requests.get("http://google.com", timeout=3)
        return True
    except requests.ConnectionError:
        pass

    return False

def main():
    # Initialisation de l'afficheur
    epd = epd2in13.EPD()
    epd.init(epd.lut_full_update)
    epd.clear_frame_memory(0xFF)
    # Affichage d'une image noire pour "nettoyer" l'ecran
    image = Image.open('/opt/coin-ticker/start.bmp')
    epd.set_frame_memory(image, 0, 0)
    epd.display_frame()

    while True:
        # API call ETH value 
        gETH = requests.get('https://api.coinmarketcap.com/v1/ticker/ethereum/?convert=EUR')
        if gETH.status_code == 200:
            ETH = json.loads(gETH.text)
        else:
            ETH = 0
        gBTC = requests.get('https://api.coinmarketcap.com/v1/ticker/bitcoin/?convert=EUR')
        if gBTC.status_code == 200:
            BTC = json.loads(gBTC.text)
        else: 
            BTC = 0
        gBLK = requests.get('https://blockchain.info/fr/q/getblockcount')
        if gBLK.status_code == 200:
            BTCBLK = gBLK.text
        else:
            BTCBLK = 0  

        # Check si la connexion internet est fonctionnelle
        if connection_check():
            WAN = 'OK'
        else:
            WAN = 'FAIL'
        
        # Traitements et calculs des valeurs 
        # ETHEREUM
        ETH_PRICE_NOW = float(ETH[0]['price_eur'])
        ETH_PRICE_1H = ETH_PRICE_NOW - ((float(ETH[0]['percent_change_1h']) / 100) * ETH_PRICE_NOW)
        ETH_PRICE_24H = ETH_PRICE_NOW - ((float(ETH[0]['percent_change_24h']) / 100) * ETH_PRICE_NOW)
        ETH_PRICE_7D = ETH_PRICE_NOW - ((float(ETH[0]['percent_change_7d']) / 100) * ETH_PRICE_NOW)
        ETH_EUR_NOW = ETHBAL * ETH_PRICE_NOW
        ETH_EUR_1H = ETHBAL * ETH_PRICE_1H
        ETH_EUR_24H = ETHBAL * ETH_PRICE_24H
        ETH_EUR_7D = ETHBAL * ETH_PRICE_7D
        # BITCOIN
        BTC_PRICE_NOW = float(BTC[0]['price_eur'])
        BTC_PRICE_1H = BTC_PRICE_NOW - ((float(BTC[0]['percent_change_1h']) / 100) * BTC_PRICE_NOW)
        BTC_PRICE_24H = BTC_PRICE_NOW - ((float(BTC[0]['percent_change_24h']) / 100) * BTC_PRICE_NOW)
        BTC_PRICE_7D = BTC_PRICE_NOW - ((float(BTC[0]['percent_change_7d']) / 100) * BTC_PRICE_NOW)
        BTC_EUR_NOW = BTCBAL * BTC_PRICE_NOW
        BTC_EUR_1H = BTCBAL * BTC_PRICE_1H
        BTC_EUR_24H = BTCBAL * BTC_PRICE_24H
        BTC_EUR_7D = BTCBAL * BTC_PRICE_7D
        # TOTAL EUR
        TOTALEUR_NOW = ETH_EUR_NOW + BTC_EUR_NOW
        TOTALEUR_1H = ETH_EUR_1H + BTC_EUR_1H
        TOTALEUR_24H = ETH_EUR_24H + BTC_EUR_24H
        TOTALEUR_7D = ETH_EUR_7D + BTC_EUR_7D
        # TOTAL PERCENT VARIATION
        PERCENT_TOTAL_NOW_FROM_BASE = (TOTALEUR_NOW - BASE) / BASE * 100
        PERCENT_TOTAL_NOW_FROM_1H = (TOTALEUR_NOW - TOTALEUR_1H) / TOTALEUR_1H * 100
        PERCENT_TOTAL_NOW_FROM_24H = (TOTALEUR_NOW - TOTALEUR_24H) / TOTALEUR_24H * 100
        PERCENT_TOTAL_NOW_FROM_7D = (TOTALEUR_NOW - TOTALEUR_7D) / TOTALEUR_7D * 100
        # Initialisation Afficheur (mode partial update)
        epd.init(epd.lut_partial_update)
        image = Image.new('1', (255, 128), 255)
        draw = ImageDraw.Draw(image)
        # Gestion Police
        color = 0
        police = '/usr/share/fonts/truetype/freefont/FreeSans.ttf'
        big = ImageFont.truetype(police, 60)
        medium = ImageFont.truetype(police, 25)
        small = ImageFont.truetype(police, 16)
        # Generation de l'image a afficher
        draw.text((10, 0), time.strftime('%H:%M'), font = small, fill = 0)
        draw.text((183, 0), 'WAN '+ str(WAN), font = small, fill = 0)
        draw.text((115, 10), 'jour', font = small, fill = color)
        draw.text((70, 20), str("%.2f" % PERCENT_TOTAL_NOW_FROM_24H), font = big, fill = color)
        draw.text((10, 80), 'heure', font = small, fill = color)
        draw.text((10, 95), str("%.2f" % PERCENT_TOTAL_NOW_FROM_1H), font = medium, fill = color)
        draw.text((95, 80), 'semaine', font = small, fill = color)
        draw.text((95, 95), str("%.2f" % PERCENT_TOTAL_NOW_FROM_7D), font = medium, fill = color)
        draw.text((200, 80), 'base', font = small, fill = color)
        draw.text((193, 95), str("%.2f" % PERCENT_TOTAL_NOW_FROM_BASE), font = medium, fill = color)
        # Sauvegarde de l'image et rotation
        image.save('/opt/coin-ticker/image.jpg')
        rotate = Image.open('/opt/coin-ticker/image.jpg')
        result = rotate.rotate(90, expand = 1)
        result.save('/opt/coin-ticker/result.jpg')
        # Affichage et attente 
        epd.set_frame_memory(Image.open('/opt/coin-ticker/result.jpg'), 0, 0)
        epd.display_frame()
        epd.delay_ms(2000)
        time.sleep(30)

if __name__ == '__main__':
    # Attente de 30s avant de lancer le programme (temps pour le rapberry de se connecter au réseau au démarrage)
    time.sleep(30)
    main()

Voilà, ça fait un petit bricolage sympa pour une 40aine d’euros!

5 commentaires

  1. Bonjour Vincent, je commente cet article car je ne trouve nul autre endroit pour poser ma question.
    Est-il volontaire de demander d’être connecté pour lire certains articles ? Ex: l’article sur la mise à jour de owncloud redirige sur la page d’authentification.

    Merci

  2. Salut,
    j’ai bien aimé le concept, j’ai un raspberry w, j’ai installé les drivers et essayé le code de demonstration, mais je n’ai rien qui s’affiche… (j’ai presque le même afficheur ; le B). Tu aurais une idée ? (idem avec ton code).

  3. Je ne savais pas quoi faire de mon raspberry pi que j’avais acheté pour faire tourner quelques clés USB ASIC, le coup du ticker est une super idée 🙂 Je vais tester la config que tu montres sur ton article et voir si j’y arrive. Je suis un peu bricolo mais je connais pas le python, on verra si ça le fait quand même :p

    1. Salut Maxime,
      Le plus galère si t’es pas trop bricoleur, c’est la soudure des pins GPIO sur le PI (zéro dans mon cas).
      Après si tu as un Pi2 ou 3 tu n’auras pas cette galère.
      Hésite pas si tu as besoin d’aide, bye!

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.