CoinMarketCap - Scrolling Kurs - Kombination von scrolling Text/refresh with LED Matrix 2812B

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
chris_pi_1234
User
Beiträge: 1
Registriert: Samstag 6. November 2021, 13:17

Hallo,

Ich will den aktuellen Börsenkurs einer Cryptowährung über ein 8x32 LED Matrix Display anzeigen lassen.

Ich hab dazu schon 3 threads erstellt - (CMC)Data json.load, (REFRESH)image refresh & (MATRIX)scrolling text.
Die 3 threads laufen schon parallel.

Aber wie kann ich jetzt die Daten von (CMC) immer aktualisiert am Display anzeigen lassen?
Ich bekomme die Variable text nicht von einem thread zum anderen.

Vielen lieben Dank
mfg
Christian


#!/usr/bin/env python3

from requests import Request, Session
from requests.exceptions import ConnectionError, Timeout, TooManyRedirects
import threading
import json
import time
import sys
import board
import neopixel
from colorsys import hsv_to_rgb
from PIL import Image, ImageDraw, ImageFont

text = "### FTM $ 2.624 | 1h -0.705 % | 24h -8.476 % | 7d -6.670 % ### TOTAL T$ 2.665E+12 | -2.431 % ###"
pixel_pin = board.D18
num_pixels = 256
display_width = 32
display_height = 8
matrixbrightness = 0.1
scrollSpeed = 0.2 #adjust the scrolling speed here-> smaller number=faster scroll
TextColor = (55,55,255) #set the color of your text here in RGB, default is white

ORDER = neopixel.GRB
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=matrixbrightness, auto_write=False, pixel_order=ORDER)
rotation = 0

#load your font
#font = ImageFont.truetype("LiberationMono-Regular.ttf", 8)
#5x7.ttf font is easier to read and available for download for personal use from the Internet
font = ImageFont.truetype("5x7.ttf", 8)


def CMC():
global text
while True :
####TOTAL
url1 = 'https://pro-api.coinmarketcap.com/v1/gl ... tes/latest'
parameters1 = {'convert':'USD',}
####FTM
url2 = 'https://pro-api.coinmarketcap.com/v1/cr ... tes/latest'
parameters2 = {'convert':'USD', 'id': '3513',}
####CODE
# headers = {'Accepts': 'application/json', 'X-CMC_PRO_API_KEY': '', }
session = Session()
session.headers.update(headers)

try:
x = session.get(url1, params=parameters1)
data1 = json.loads(x.text)
y = session.get(url2, params=parameters2)
data2 = json.loads(y.text)
####FTM
print('###',data2["data"]["3513"]["symbol"],end=' $ ')
print("%5.3f" % (data2["data"]["3513"]["quote"]["USD"]["price"]),end=' ')
print('| 1h ' "%5.3f" % (data2["data"]["3513"]["quote"]["USD"]["percent_change_1h"]),end=' % ')
print('| 24h ' "%5.3f" % (data2["data"]["3513"]["quote"]["USD"]["percent_change_24h"]),end=' % ')
print('| 7d ' "%5.3f" % (data2["data"]["3513"]["quote"]["USD"]["percent_change_7d"]),'% ###', end=' ')
####TOTAL
print('TOTAL T$',"%1.3E"% data1["data"]["quote"]["USD"]["total_market_cap"],end=' | ')
print("%5.3f" % data1["data"]["quote"]["USD"]["total_market_cap_yesterday_percentage_change"],'% ###')

# a = ('TOTAL T$',"%1.3E"% data1["data"]["quote"]["USD"]["total_market_cap"])
# text = a
# return text

time.sleep(200)

except (ConnectionError, Timeout, TooManyRedirects) as e:
print(e)


#for the Adafruit NeoMatrix grid
def getIndex(x, y):
x = display_width-x-1
return (x*8)+y

#use for the flex grid
def getIndex2(x, y):
x = display_width-x-1
if x % 2 != 0:
return (x*8)+y
else:
return (x*8)+(7-y)

if len(sys.argv) > 1:
try:
rotation = int(sys.argv[1])
except ValueError:
print("Usage: {} <rotation>".format(sys.argv[0]))
sys.exit(1)

def REFRESH():
global image
# Measure the size of our text
text_width, text_height = font.getsize(text)

# Create a new PIL image big enough to fit the text
image = Image.new('P', (text_width + display_width + display_width, display_height), 0)
draw = ImageDraw.Draw(image)

# Draw the text into the image
draw.text((display_width, -1), text, font=font, fill=255)
image.save("img.png", "PNG")
offset_x = 0


#andere schleife parallel gleich aufgebaut
def MATRIX(offset_x = 0):
global image
image =Image.open(r"img.png")
while True :
for x in range(display_width):
for y in range(display_height):
if image.getpixel((x + offset_x, y)) == 255:
pixels[getIndex2(x,y)] = TextColor

else:
pixels[getIndex2(x,y)] = (0, 0, 0)

offset_x += 1
if offset_x + display_width > image.size[0]:
offset_x = 0

pixels.show()
time.sleep(scrollSpeed) #scrolling text speed



thread1 = threading.Thread(target=CMC)
thread1.start()

thread2 = threading.Thread(target=REFRESH)
thread2.start()

thread3 = threading.Thread(target=MATRIX)
thread3.start()
Sirius3
User
Beiträge: 17825
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie immer wenn jemand mit Threads anfängt, sind das zwei bis drei Threads zuviel. Threads führen eine Komplexität ein, die man vermeiden möchte, wenn es nicht wirklich nötig ist.
Variablennamen und Funktionen schreibt man komplett kein, nur Konstanten werden GROSS geschrieben.
`global` benutzt man nicht, erst recht nicht in Zusammenhang mit Threads.
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, und nicht mal 4 und mal 2.

Will man eine Laufschrift synchronisieren, darf man nicht den Fehler machen, einen fixen Wert bei sleep anzugeben, sondern man muß die Zeit für's Update mit berücksichtigen.

Wie vermutet, kommt man mit 0 Threads aus:

Code: Alles auswählen

#!/usr/bin/env python3
import time
import board
import neopixel
from PIL import Image, ImageDraw, ImageFont
from requests import Session

API_KEY = ""
URL1 = 'https://pro-api.coinmarketcap.com/v1/global-metrics/quotes/latest'
URL2 = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest'
SOME_ID = '3513'

PIXEL_PIN = board.D18
NUM_PIXELS = 256
MATRIX_BRIGHTNESS = 0.1
PIXEL_ORDER = neopixel.GRB

DISPLAY_WIDTH = 32
DISPLAY_HEIGHT = 8
TEXT_COLOR = (55, 55, 255) #set the color of your text here in RGB, default is white
BACKGROUND = (0, 0, 0)
SCROLL_SPEED = 0.2 #adjust the scrolling speed here-> smaller number=faster scroll

def read_coin_info():
    session = Session()
    session.headers['X-CMC_PRO_API_KEY'] = API_KEY
    response = session.get(URL1, params={'convert': 'USD'})
    response.raise_for_status()
    data1 = response.json()
    response = session.get(URL2, params={'convert': 'USD', 'id': SOME_ID})
    response.raise_for_status()
    data2 = response.json()["data"][SOME_ID]
    quote = data2["quote"]["USD"]
    total_quote = data1["data"]["quote"]["USD"]
    return (
        f"### {data2['symbol']} $ {quote['price']:5.3f} "
        f"| 1h {quote['percent_change_1h']:5.3f} % "
        f"| 24h {quote['percent_change_24h']:5.3f} % "
        f"| 7d {quote['percent_change_7d']:5.3f} % "
        f"### TOTAL T$ {total_quote['total_market_cap']:1.3E} "
        f"| {total_quote['total_market_cap_yesterday_percentage_change']} % ###"
    )

def refresh_info(font, text):
    # Measure the size of our text
    text_width, text_height = font.getsize(text)

    # Create a new PIL image big enough to fit the text
    image = Image.new('P', (text_width + 2 * DISPLAY_WIDTH, DISPLAY_HEIGHT), 0)
    draw = ImageDraw.Draw(image)
    draw.text((DISPLAY_WIDTH, -1), text, font=font, fill=255)
    return image

def get_index(x, y):
    x = DISPLAY_WIDTH - x - 1
    if x % 2 == 0:
        y = 7 - y
    return x * 8 + y

def display_image(pixels, image, offset):
    for x in range(DISPLAY_WIDTH):
        for y in range(DISPLAY_HEIGHT):         
            color = TEXT_COLOR if image.getpixel((x + offset, y)) == 255 else BACKGROUND
            pixels[get_index(x,y)] = color
    pixels.show()

def main():
    font = ImageFont.truetype("5x7.ttf", 8)
    pixels = neopixel.NeoPixel(PIXEL_PIN, NUM_PIXELS,
        brightness=MATRIX_BRIGHTNESS,
        auto_write=False, pixel_order=PIXEL_ORDER)

    last_update_time = 0
    while True:
        current_time = time.time()
        if current_time - last_update_time > 200:
            text = read_coin_info()
            image = refresh_info(font, text)
            offset = 0
        display_image(pixels, image, offset)
        offset += 1
        if offset + DISPLAY_WIDTH > image.size[0]:
            offset = 0
        time.sleep(-(current_time % -0.2))

if __name__ == "__main__":
    main()
Antworten