Skip to content

Commit 10dce51

Browse files
committed
configured periodic restart to workaround 'keyboard' not handling kbd disconnects
1 parent 1961397 commit 10dce51

File tree

2 files changed

+78
-42
lines changed

2 files changed

+78
-42
lines changed

mediakey-remote.py

+76-40
Original file line numberDiff line numberDiff line change
@@ -23,73 +23,109 @@
2323
# - spotify
2424
# - ...
2525

26-
26+
import importlib
2727
import time
2828
from threading import Thread
2929
import keyboard
3030
import soco
3131
import toml
3232

3333

34-
# load config
34+
# global vars
3535
config_path="/home/kbouck/dev/mediakey-remote/mediakey-remote-config.toml"
36-
config = {}
37-
with open(config_path, 'r') as f:
38-
config = toml.load(f)
39-
print("Loaded config from " + config_path)
36+
config = {}
37+
state = ""
38+
39+
# load config
40+
def load_config():
41+
global config_path
42+
global config
43+
with open(config_path, 'r') as f:
44+
config = toml.load(f)
45+
print("Loaded config from " + config_path)
4046

4147

4248
# discover sonos devices on network
4349
# - todo: error handling
4450
# - todo: make reconnection loop
45-
46-
#sonos_speakers = soco.discover()
47-
#if (len(sonos_speakers) > 0):
48-
# print("Discovered sonos speakers:")
49-
# for speaker in sonos_speakers:
50-
# print(speaker.name)
51-
#else:
52-
# # todo - need reconnection loop
53-
# system.exit("No sonos speakers discovered")
54-
#sonos = sonos_speakers.pop()
55-
56-
57-
sonos = soco.discovery.any_soco()
58-
print("Connected to '" + str(sonos.player_name) + "'")
59-
60-
state = ""
61-
volume = 0
62-
volume_step = config['sonos']['vol_step']
63-
vol_init_max = config['sonos']['vol_init_max']
51+
def connect():
52+
global sonos
53+
global state
54+
global volume
55+
global volume_step
56+
global vol_init_max
57+
58+
#sonos_speakers = soco.discover()
59+
#if (len(sonos_speakers) > 0):
60+
# print("Discovered sonos speakers:")
61+
# for speaker in sonos_speakers:
62+
# print(speaker.name)
63+
#else:
64+
# # todo - need reconnection loop
65+
# system.exit("No sonos speakers discovered")
66+
#sonos = sonos_speakers.pop()
67+
68+
sonos = soco.discovery.any_soco()
69+
print("Connected to '" + str(sonos.player_name) + "'")
70+
state = ""
71+
volume = 0
72+
volume_step = config['sonos']['vol_step']
73+
vol_init_max = config['sonos']['vol_init_max']
6474

6575
def play_pause():
76+
global sonos
6677
global state
6778
sonos.pause() if (state == "PLAYING") else sonos.play()
6879
transport_info = sonos.get_current_transport_info()
6980
state = transport_info['current_transport_state']
7081

7182
def poll_state():
7283
global state
84+
global volume
7385
while True:
7486
volume = sonos.volume
7587
transport_info = sonos.get_current_transport_info()
7688
state = transport_info['current_transport_state']
7789
time.sleep(10)
78-
7990

80-
# map keys to api calls
81-
keyboard.add_hotkey(config['keys']['volume_down'], lambda: sonos.set_relative_volume(volume_step*-1), trigger_on_release=False)
82-
keyboard.add_hotkey(config['keys']['volume_up'], lambda: sonos.set_relative_volume(volume_step), trigger_on_release=False)
83-
keyboard.add_hotkey(config['keys']['next'], lambda: sonos.next(), trigger_on_release=False)
84-
keyboard.add_hotkey(config['keys']['previous'], lambda: sonos.previous(), trigger_on_release=False)
85-
keyboard.add_hotkey(config['keys']['play_pause'], lambda: play_pause(), trigger_on_release=False)
86-
# todo: mute/seek?
87-
88-
# start state polling thread
89-
poller = Thread(target=poll_state)
90-
poller.start()
91-
92-
# block app to wait for keyboard events
93-
keyboard.wait()
9491

92+
# map keys to api calls
93+
def map_hotkeys():
94+
global config
95+
global sonos
96+
keyboard.add_hotkey(config['keys']['volume_down'], lambda: sonos.set_relative_volume(volume_step*-1), trigger_on_release=False)
97+
keyboard.add_hotkey(config['keys']['volume_up'], lambda: sonos.set_relative_volume(volume_step), trigger_on_release=False)
98+
keyboard.add_hotkey(config['keys']['next'], lambda: sonos.next(), trigger_on_release=False)
99+
keyboard.add_hotkey(config['keys']['previous'], lambda: sonos.previous(), trigger_on_release=False)
100+
keyboard.add_hotkey(config['keys']['play_pause'], lambda: play_pause(), trigger_on_release=False)
101+
# todo: mute/seek?
102+
103+
104+
105+
load_config()
106+
107+
# main
108+
while True:
109+
try:
110+
# connect, or reconnect after exception
111+
connect()
112+
map_hotkeys()
113+
114+
# start state-polling thread
115+
poller = Thread(name="Polling Thread", target=poll_state)
116+
poller.start()
117+
118+
# block app to wait for keyboard events
119+
keyboard.wait()
120+
121+
except Exception as e:
122+
print("Exception from main:")
123+
print(e)
124+
125+
except Error as e:
126+
print("Error from main:")
127+
print(e)
128+
129+
# sleep a bit to avoid a fast loop during a persistent error situation
130+
time.sleep(1)
95131

mediakey-remote.service

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ StartLimitIntervalSec=0
55

66
[Service]
77
Type=simple
8-
Restart=always
9-
RestartSec=1
108
ExecStart=/home/kbouck/dev/mediakey-remote/dist/mediakey-remote
9+
Restart=always
10+
RuntimeMaxSec=10min
1111

1212
[Install]
1313
WantedBy=multi-user.target

0 commit comments

Comments
 (0)