foo
This commit is contained in:
parent
27fa6f7c63
commit
6c7d81ed49
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
# fork of https://github.com/SmartViking/MaTris by deinkoks
|
# fork of https://github.com/SmartViking/MaTris by deinkoks
|
||||||
# removed everythin but elemental gameplay, added multiplayer controlled via mqtt
|
# removed everythin but elemental gameplay, added multiplayer controlled via mqtt
|
||||||
# most ugly thing: a mqtt client for every player due to callback limitations
|
# most ugly thing: a mqtt client for every player due to callback limitations
|
||||||
@ -9,7 +9,7 @@ import os
|
|||||||
import paho.mqtt.client as mqtt
|
import paho.mqtt.client as mqtt
|
||||||
|
|
||||||
|
|
||||||
from tetrominoes import list_of_tetrominoes
|
from tetrominoes import list_of_tetrominoes, shape_str
|
||||||
from tetrominoes import rotate
|
from tetrominoes import rotate
|
||||||
|
|
||||||
from scores import load_score, write_score
|
from scores import load_score, write_score
|
||||||
@ -21,12 +21,16 @@ def get_sound(filename):
|
|||||||
return pygame.mixer.Sound(os.path.join(os.path.dirname(__file__), "resources", filename))
|
return pygame.mixer.Sound(os.path.join(os.path.dirname(__file__), "resources", filename))
|
||||||
|
|
||||||
ENABLE_STDIO = True #dump game on stdio, not sure if works as intended.
|
ENABLE_STDIO = True #dump game on stdio, not sure if works as intended.
|
||||||
|
ENABLE_MQTT = True # for debugging w/o a broker
|
||||||
|
ENABLE_SOUND = False
|
||||||
|
ENABLE_KEYBOARD_CONTROLS = False # working for player1. mostly
|
||||||
|
MQTT_TOPIC = "deckentetris/"
|
||||||
|
|
||||||
PLAYER = 10 # player count, 1 columns per player
|
PLAYER = 10 # player count, 1 columns per player
|
||||||
BGCOLOR = (15, 15, 20)
|
BGCOLOR = (15, 15, 20)
|
||||||
BORDERCOLOR = (140, 140, 140)
|
BORDERCOLOR = (140, 140, 140)
|
||||||
|
GAMEOVER_COLOR = (140, 100, 100)
|
||||||
BLOCKSIZE = 16 # set this to 1 if run on the pixeldecke
|
BLOCKSIZE = 1 # set this to 1 if run on the pixeldecke
|
||||||
BORDERWIDTH = 0
|
BORDERWIDTH = 0
|
||||||
|
|
||||||
MATRIS_OFFSET = 0
|
MATRIS_OFFSET = 0
|
||||||
@ -34,14 +38,14 @@ MATRIS_OFFSET = 0
|
|||||||
# we have 8pixel columns with a height of 5*8px for every player
|
# we have 8pixel columns with a height of 5*8px for every player
|
||||||
# lets use one for the next block, but 2 lines are hidden
|
# lets use one for the next block, but 2 lines are hidden
|
||||||
MATRIX_WIDTH = 8
|
MATRIX_WIDTH = 8
|
||||||
MATRIX_HEIGHT = (4+2)*8
|
MATRIX_HEIGHT = (4)*8
|
||||||
|
|
||||||
LEFT_MARGIN = 0
|
LEFT_MARGIN = 0
|
||||||
|
|
||||||
WIDTH = (MATRIX_WIDTH*BLOCKSIZE + MATRIS_OFFSET*2 + LEFT_MARGIN) * PLAYER
|
WIDTH = (MATRIX_WIDTH*BLOCKSIZE + MATRIS_OFFSET*2 + LEFT_MARGIN) * PLAYER
|
||||||
HEIGHT = (MATRIX_HEIGHT-2)*BLOCKSIZE + MATRIS_OFFSET*2
|
HEIGHT = (MATRIX_HEIGHT-2)*BLOCKSIZE + MATRIS_OFFSET*2
|
||||||
HEIGHT += BLOCKSIZE*8 # additional tile for preview above game
|
HEIGHT += BLOCKSIZE*8 # additional tile for preview above game
|
||||||
|
HEIGHT += 2 # height fix for reasons
|
||||||
TRICKY_CENTERX = WIDTH-(WIDTH-(MATRIS_OFFSET+BLOCKSIZE*MATRIX_WIDTH))/2
|
TRICKY_CENTERX = WIDTH-(WIDTH-(MATRIS_OFFSET+BLOCKSIZE*MATRIX_WIDTH))/2
|
||||||
|
|
||||||
VISIBLE_MATRIX_HEIGHT = MATRIX_HEIGHT - 2
|
VISIBLE_MATRIX_HEIGHT = MATRIX_HEIGHT - 2
|
||||||
@ -60,22 +64,18 @@ class Matris(object):
|
|||||||
self.request_movement('left')
|
self.request_movement('left')
|
||||||
elif payload == "right":
|
elif payload == "right":
|
||||||
self.request_movement('right')
|
self.request_movement('right')
|
||||||
else:
|
elif payload == "update":
|
||||||
pass #print the matrix
|
self.mqtt.publish(MQTT_TOPIC+str(offset)+"/current", payload=shape_str(self.current_tetromino.shape), qos=0, retain=False)
|
||||||
|
self.mqtt.publish(MQTT_TOPIC+str(offset)+"/next", payload=shape_str(self.next_tetromino.shape), qos=0, retain=False)
|
||||||
|
|
||||||
def __init__(self, offset):
|
def __init__(self, offset):
|
||||||
self.surface = screen.subsurface(Rect((MATRIX_WIDTH * BLOCKSIZE*offset, 8*BLOCKSIZE),
|
self.surface = screen.subsurface(Rect((MATRIX_WIDTH * BLOCKSIZE*offset, 8*BLOCKSIZE),
|
||||||
(MATRIX_WIDTH * BLOCKSIZE, (MATRIX_HEIGHT-2) * BLOCKSIZE)))
|
(MATRIX_WIDTH * BLOCKSIZE, (MATRIX_HEIGHT-2) * BLOCKSIZE)))
|
||||||
self.mqtt = mqtt.Client()
|
|
||||||
self.mqtt.connect("mqtt.chaospott.de", port=1883, keepalive=60, bind_address="")
|
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
self.matrix = dict()
|
self.matrix = dict()
|
||||||
for y in range(MATRIX_HEIGHT):
|
for y in range(MATRIX_HEIGHT):
|
||||||
for x in range(MATRIX_WIDTH):
|
for x in range(MATRIX_WIDTH):
|
||||||
self.matrix[(y,x)] = None
|
self.matrix[(y,x)] = None
|
||||||
self.mqtt.subscribe("deckentetris/"+str(offset)+"/action", 2)
|
|
||||||
self.mqtt.on_message = self.on_msg
|
|
||||||
self.mqtt.loop_start()
|
|
||||||
"""
|
"""
|
||||||
`self.matrix` is the current state of the tetris board, that is, it records which squares are
|
`self.matrix` is the current state of the tetris board, that is, it records which squares are
|
||||||
currently occupied. It does not include the falling tetromino. The information relating to the
|
currently occupied. It does not include the falling tetromino. The information relating to the
|
||||||
@ -109,6 +109,15 @@ class Matris(object):
|
|||||||
self.linescleared_sound = get_sound("linecleared.wav")
|
self.linescleared_sound = get_sound("linecleared.wav")
|
||||||
self.highscorebeaten_sound = get_sound("highscorebeaten.wav")
|
self.highscorebeaten_sound = get_sound("highscorebeaten.wav")
|
||||||
|
|
||||||
|
if ENABLE_MQTT:
|
||||||
|
self.mqtt = mqtt.Client()
|
||||||
|
self.mqtt.connect("mqtt.chaospott.de", port=1883, keepalive=60, bind_address="")
|
||||||
|
self.mqtt.subscribe(MQTT_TOPIC+str(offset)+"/action", 2)
|
||||||
|
self.mqtt.on_message = self.on_msg
|
||||||
|
self.mqtt.loop_start()
|
||||||
|
self.mqtt.publish(MQTT_TOPIC+str(offset)+"/current", payload=shape_str(self.current_tetromino.shape), qos=0, retain=False)
|
||||||
|
self.mqtt.publish(MQTT_TOPIC+str(offset)+"/next", payload=shape_str(self.next_tetromino.shape), qos=0, retain=False)
|
||||||
|
|
||||||
|
|
||||||
def set_tetrominoes(self):
|
def set_tetrominoes(self):
|
||||||
self.current_tetromino = self.next_tetromino
|
self.current_tetromino = self.next_tetromino
|
||||||
@ -132,9 +141,10 @@ class Matris(object):
|
|||||||
def update(self, timepassed):
|
def update(self, timepassed):
|
||||||
self.needs_redraw = False
|
self.needs_redraw = False
|
||||||
|
|
||||||
|
if ENABLE_KEYBOARD_CONTROLS:
|
||||||
pressed = lambda key: event.type == pygame.KEYDOWN and event.key == key
|
pressed = lambda key: event.type == pygame.KEYDOWN and event.key == key
|
||||||
unpressed = lambda key: event.type == pygame.KEYUP and event.key == key
|
unpressed = lambda key: event.type == pygame.KEYUP and event.key == key
|
||||||
#self.mqtt.loop()
|
|
||||||
events = pygame.event.get()
|
events = pygame.event.get()
|
||||||
|
|
||||||
for event in events:
|
for event in events:
|
||||||
@ -150,6 +160,7 @@ class Matris(object):
|
|||||||
if self.paused:
|
if self.paused:
|
||||||
return self.needs_redraw
|
return self.needs_redraw
|
||||||
|
|
||||||
|
if ENABLE_KEYBOARD_CONTROLS:
|
||||||
for event in events:
|
for event in events:
|
||||||
if pressed(pygame.K_SPACE):
|
if pressed(pygame.K_SPACE):
|
||||||
self.hard_drop()
|
self.hard_drop()
|
||||||
@ -176,8 +187,12 @@ class Matris(object):
|
|||||||
self.downwards_speed = self.base_downwards_speed ** (1 + self.level/10.)
|
self.downwards_speed = self.base_downwards_speed ** (1 + self.level/10.)
|
||||||
|
|
||||||
self.downwards_timer += timepassed
|
self.downwards_timer += timepassed
|
||||||
|
|
||||||
|
if ENABLE_KEYBOARD_CONTROLS:
|
||||||
downwards_speed = self.downwards_speed*0.10 if any([pygame.key.get_pressed()[pygame.K_DOWN],
|
downwards_speed = self.downwards_speed*0.10 if any([pygame.key.get_pressed()[pygame.K_DOWN],
|
||||||
pygame.key.get_pressed()[pygame.K_s]]) else self.downwards_speed
|
pygame.key.get_pressed()[pygame.K_s]]) else self.downwards_speed
|
||||||
|
else:
|
||||||
|
downwards_speed = self.downwards_speed
|
||||||
if self.downwards_timer > downwards_speed:
|
if self.downwards_timer > downwards_speed:
|
||||||
if not self.request_movement('down'):
|
if not self.request_movement('down'):
|
||||||
self.lock_tetromino()
|
self.lock_tetromino()
|
||||||
@ -185,6 +200,7 @@ class Matris(object):
|
|||||||
self.downwards_timer %= downwards_speed
|
self.downwards_timer %= downwards_speed
|
||||||
|
|
||||||
|
|
||||||
|
if ENABLE_KEYBOARD_CONTROLS:
|
||||||
if any(self.movement_keys.values()):
|
if any(self.movement_keys.values()):
|
||||||
self.movement_keys_timer += timepassed
|
self.movement_keys_timer += timepassed
|
||||||
if self.movement_keys_timer > self.movement_keys_speed:
|
if self.movement_keys_timer > self.movement_keys_speed:
|
||||||
@ -216,13 +232,15 @@ class Matris(object):
|
|||||||
is responsible for checking if it's game over.
|
is responsible for checking if it's game over.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
write_score(self.score)
|
#write_score(self.score)
|
||||||
|
|
||||||
if full_exit:
|
|
||||||
exit()
|
|
||||||
else:
|
|
||||||
raise GameOver("Sucker!")
|
|
||||||
|
|
||||||
|
#if full_exit:
|
||||||
|
# exit()
|
||||||
|
#else:
|
||||||
|
# raise GameOver("Sucker!")
|
||||||
|
self.paused = True
|
||||||
|
self.surface.fill(GAMEOVER_COLOR)
|
||||||
|
self.needs_redraw =True
|
||||||
def place_shadow(self):
|
def place_shadow(self):
|
||||||
posY, posX = self.tetromino_position
|
posY, posX = self.tetromino_position
|
||||||
while self.blend(position=(posY, posX)):
|
while self.blend(position=(posY, posX)):
|
||||||
@ -333,16 +351,17 @@ class Matris(object):
|
|||||||
self.lines += lines_cleared
|
self.lines += lines_cleared
|
||||||
|
|
||||||
if lines_cleared:
|
if lines_cleared:
|
||||||
if lines_cleared >= 4:
|
if lines_cleared >= 4 and ENABLE_SOUND:
|
||||||
self.linescleared_sound.play()
|
self.linescleared_sound.play()
|
||||||
self.score += 100 * (lines_cleared**2) * self.combo
|
self.score += 100 * (lines_cleared**2) * self.combo
|
||||||
|
|
||||||
if not self.played_highscorebeaten_sound and self.score > self.highscore:
|
if not self.played_highscorebeaten_sound and self.score > self.highscore:
|
||||||
if self.highscore != 0:
|
if self.highscore != 0 and ENABLE_SOUND:
|
||||||
self.highscorebeaten_sound.play()
|
self.highscorebeaten_sound.play()
|
||||||
self.played_highscorebeaten_sound = True
|
self.played_highscorebeaten_sound = True
|
||||||
|
|
||||||
if self.lines >= self.level*10:
|
if self.lines >= self.level*10:
|
||||||
|
if ENABLE_SOUND:
|
||||||
self.levelup_sound.play()
|
self.levelup_sound.play()
|
||||||
self.level += 1
|
self.level += 1
|
||||||
|
|
||||||
@ -351,6 +370,7 @@ class Matris(object):
|
|||||||
self.set_tetrominoes()
|
self.set_tetrominoes()
|
||||||
|
|
||||||
if not self.blend():
|
if not self.blend():
|
||||||
|
if ENABLE_SOUND:
|
||||||
self.gameover_sound.play()
|
self.gameover_sound.play()
|
||||||
self.gameover()
|
self.gameover()
|
||||||
|
|
||||||
@ -450,8 +470,9 @@ class Game(object):
|
|||||||
|
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
if ENABLE_STDIO:
|
if ENABLE_STDIO:
|
||||||
#print(screen.get_view('2'))
|
#print("-------------")
|
||||||
os.write(1, screen.get_view('2'))
|
#print(pygame.image.tostring(screen, "RGB", False))
|
||||||
|
os.write(1, pygame.image.tostring(screen, "RGB", False))
|
||||||
|
|
||||||
|
|
||||||
def blit_next_tetromino(self, tetromino_surf, offset):
|
def blit_next_tetromino(self, tetromino_surf, offset):
|
||||||
@ -498,9 +519,14 @@ def construct_nightmare(size):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
pygame.init()
|
pygame.init()
|
||||||
|
print("Width:", WIDTH, "Height:", HEIGHT, "Playercount:", PLAYER)
|
||||||
|
if ENABLE_MQTT or True:
|
||||||
|
print("MQTT enabled:")
|
||||||
|
print("TOPIC:", MQTT_TOPIC+"<playerid>/action", " PAYLOAD: left|right|rotate|drop|update")
|
||||||
|
print("TOPIC:", MQTT_TOPIC+"<playerid>/current", "Show the current tetromino. Updated by update @ /action.")
|
||||||
|
print("TOPIC:", MQTT_TOPIC+"<playerid>/next", "Show the current tetromino. Updated by update @ /action.")
|
||||||
screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
||||||
pygame.display.set_caption("MaTris")
|
pygame.display.set_caption("Deckentetris")
|
||||||
# Menu().main(screen)
|
# Menu().main(screen)
|
||||||
Game().main(screen)
|
Game().main(screen)
|
||||||
|
|
||||||
|
@ -17,9 +17,9 @@ uint32_t hash32(uint32_t d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// must be the next prime after NUM_TOTAL_LEDS
|
// must be the next prime after NUM_TOTAL_LEDS
|
||||||
#define IDLE_PRIME 1931
|
#define IDLE_PRIME 3203
|
||||||
// must be a primitive element of the prime residue field |N/IDLE_PRIM
|
// must be a primitive element of the prime residue field |N/IDLE_PRIM
|
||||||
#define IDLE_PRIM_ELEM 283
|
#define IDLE_PRIM_ELEM 777
|
||||||
|
|
||||||
int IDLE_rand(int *seed){
|
int IDLE_rand(int *seed){
|
||||||
return *seed = (*seed * IDLE_PRIM_ELEM ) % IDLE_PRIME;
|
return *seed = (*seed * IDLE_PRIM_ELEM ) % IDLE_PRIME;
|
||||||
|
20
apps/pong.py
20
apps/pong.py
@ -9,8 +9,8 @@ import random
|
|||||||
|
|
||||||
PADDLE_LEN = 6
|
PADDLE_LEN = 6
|
||||||
|
|
||||||
Nx = int(sys.argv[1])
|
Ny = int(sys.argv[1])
|
||||||
Ny = int(sys.argv[2])
|
Nx = int(sys.argv[2])
|
||||||
param = sys.argv[3]
|
param = sys.argv[3]
|
||||||
|
|
||||||
speed = 1.0
|
speed = 1.0
|
||||||
@ -21,8 +21,10 @@ except:
|
|||||||
|
|
||||||
pygame.init()
|
pygame.init()
|
||||||
pygame.joystick.init()
|
pygame.joystick.init()
|
||||||
j = pygame.joystick.Joystick(0)
|
j1 = pygame.joystick.Joystick(0)
|
||||||
j.init()
|
j2 = pygame.joystick.Joystick(1)
|
||||||
|
j1.init()
|
||||||
|
j2.init()
|
||||||
|
|
||||||
numbers = [
|
numbers = [
|
||||||
int("0b111101101101111", 2),
|
int("0b111101101101111", 2),
|
||||||
@ -69,14 +71,14 @@ while True:
|
|||||||
|
|
||||||
time.sleep(0.016)
|
time.sleep(0.016)
|
||||||
|
|
||||||
if j.get_axis(0) > 0 and player1+PADDLE_LEN < Nx:
|
if j1.get_axis(0) > 0.2 and player1+PADDLE_LEN < Nx:
|
||||||
player1 += 1
|
player1 += 1
|
||||||
if j.get_axis(0) < 0 and player1 > 0 :
|
if j1.get_axis(0) < -0.2 and player1 > 0 :
|
||||||
player1 -= 1
|
player1 -= 1
|
||||||
|
|
||||||
if j.get_axis(1) > 0 and player2+PADDLE_LEN < Nx:
|
if j2.get_axis(0) > 0.2 and player2+PADDLE_LEN < Nx:
|
||||||
player2 += 1
|
player2 += 1
|
||||||
if j.get_axis(1) < 0 and player2 > 0 :
|
if j2.get_axis(0) < -0.2 and player2 > 0 :
|
||||||
player2 -= 1
|
player2 -= 1
|
||||||
|
|
||||||
x += dx
|
x += dx
|
||||||
@ -114,7 +116,7 @@ while True:
|
|||||||
|
|
||||||
buffer = bytearray(b"\x00"*(3*Nx*Ny))
|
buffer = bytearray(b"\x00"*(3*Nx*Ny))
|
||||||
def SetPixel(x, y, r, g, b):
|
def SetPixel(x, y, r, g, b):
|
||||||
idx = 3*(x+Nx*y)
|
idx = 3*(y+Ny*x)
|
||||||
buffer[idx+0] = r
|
buffer[idx+0] = r
|
||||||
buffer[idx+1] = g
|
buffer[idx+1] = g
|
||||||
buffer[idx+2] = b
|
buffer[idx+2] = b
|
||||||
|
@ -1,2 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
|
export PATH="$PATH:/home/deckensteuerung/.config/bin"
|
||||||
youtube-dl --no-progress --output - ${3} | ffmpeg -f alsa default -re -i - -pix_fmt rgb24 -vf "scale=${1}x${2}" -sws_flags bicubic -sws_dither bayer -vcodec rawvideo -f image2pipe -
|
youtube-dl --no-progress --output - ${3} | ffmpeg -f alsa default -re -i - -pix_fmt rgb24 -vf "scale=${1}x${2}" -sws_flags bicubic -sws_dither bayer -vcodec rawvideo -f image2pipe -
|
||||||
|
#youtube-dl --no-progress --output - ${3} | ffmpeg -re -i - -pix_fmt rgb24 -vf "scale=${1}x${2}" -sws_flags bicubic -sws_dither bayer -vcodec rawvideo -f image2pipe -
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
21
config.py
21
config.py
@ -1,7 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
#width
|
#width
|
||||||
ScreenX = 48
|
ScreenX = 80
|
||||||
#height
|
#height
|
||||||
ScreenY = 40
|
ScreenY = 40
|
||||||
|
|
||||||
@ -13,19 +13,26 @@ NoDataTimeout = 40
|
|||||||
LogLevel = logging.DEBUG
|
LogLevel = logging.DEBUG
|
||||||
|
|
||||||
UseGui = True
|
UseGui = True
|
||||||
GuiScaleFactor = 20
|
GuiScaleFactor = 15
|
||||||
|
|
||||||
WebHost = "localhost"
|
WebHost = "0.0.0.0"
|
||||||
WebPort = 8000
|
WebPort = 8000
|
||||||
|
|
||||||
# first app is always running in IDLE
|
# first app is always running in IDLE
|
||||||
Apps = [
|
Apps = [
|
||||||
|
{"guiname": "Dual moodlight", "name": "bimood", "cmd": "apps/bimood", "persistent": False},
|
||||||
{"guiname": "IDLE", "name": "pixelflut", "cmd": "apps/idle.py", "persistent": False},
|
{"guiname": "IDLE", "name": "pixelflut", "cmd": "apps/idle.py", "persistent": False},
|
||||||
{"guiname": "IDLE2", "name": "idlec", "cmd": "apps/idle2"},
|
{"guiname": "IDLE2", "name": "idlec", "cmd": "apps/idle2"},
|
||||||
{"guiname": "YoutubeDL", "name": "youtubedl", "cmd": "apps/youtubedl.sh"},
|
{"guiname": "YoutubeDL", "name": "youtubedl", "cmd": "apps/youtubedl.sh", "persistent": False},
|
||||||
{"guiname": "Snake", "name": "snake", "cmd": "apps/snake.py"},
|
{"guiname": "Stream", "name": "stream", "cmd": "apps/stream.sh", "persistent": False},
|
||||||
{"guiname": "Tetris", "name": "tetris", "cmd": "apps/deckentetris/deckentetris.py"}
|
{"guiname": "Wget Video/Gif/Images", "name": "wget", "cmd": "apps/wget.sh", "persistent": False},
|
||||||
{"guiname": "Strobo", "name": "strobo", "cmd": "apps/strobo.py"},
|
{"guiname": "Tetris", "name": "tetris", "cmd": "apps/deckentetris/deckentetris.py", "persistent": False},
|
||||||
|
{"guiname": "SkyScrapper", "name": "sky", "cmd": "apps/weather/main.py"},
|
||||||
|
{"guiname": "Strobo", "name": "strobo", "cmd": "apps/strobo.py", "persistent": False},
|
||||||
|
{"guiname": "Snake", "name": "snake", "cmd": "apps/snake.py", "persistent": False},
|
||||||
{"name": "pong", "cmd": "apps/pong.py"},
|
{"name": "pong", "cmd": "apps/pong.py"},
|
||||||
{"name": "framebuffer", "cmd": ["apps/fbcp", "/dev/fb0"]},
|
{"name": "framebuffer", "cmd": ["apps/fbcp", "/dev/fb0"]},
|
||||||
|
{"name": "gif", "cmd": "apps/gif.sh"},
|
||||||
|
{"name": "colormap", "cmd": "apps/colormap.py"},
|
||||||
|
{"name": "fibonacci-clock", "cmd": "apps/fibonacci-clock.py"}
|
||||||
]
|
]
|
||||||
|
5
main.py
Normal file → Executable file
5
main.py
Normal file → Executable file
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
import config
|
import config
|
||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
@ -94,6 +95,7 @@ class SerialWriter(threading.Thread):
|
|||||||
data = self.datasource.getData()
|
data = self.datasource.getData()
|
||||||
ser.write(b"\01")
|
ser.write(b"\01")
|
||||||
ser.write(data)
|
ser.write(data)
|
||||||
|
ser.flush()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if ser != None:
|
if ser != None:
|
||||||
ser.close()
|
ser.close()
|
||||||
@ -138,8 +140,9 @@ class LogReader(threading.Thread):
|
|||||||
logging.info("LogReader started")
|
logging.info("LogReader started")
|
||||||
while running and self.running:
|
while running and self.running:
|
||||||
try:
|
try:
|
||||||
self.log += runner.app.stderr.read(1).decode("utf-8")
|
self.log += self.runner.app.stderr.read(1).decode("utf-8")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
logging.info("LogReader closed")
|
logging.info("LogReader closed")
|
||||||
def stop(self):
|
def stop(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user