Skip to content

Commit 9cd1d2e

Browse files
committed
Improved GUI
Fix volume computation
1 parent 063a971 commit 9cd1d2e

File tree

10 files changed

+180
-100
lines changed

10 files changed

+180
-100
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ venv
55
# PyInstaller
66
build
77
dist
8+
__pycache__

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ License: [GPLv3+](LICENSE)
77

88
Language: [Python](https://python.org) 3
99

10+
Dependencies:
11+
12+
- [Unicode Power Symbol](https://unicodepowersymbol.com/) Copyright (c) 2013 Joe Loughry licensed under MIT
13+
1014
### Features
1115

1216
#### Target hardware
@@ -74,12 +78,11 @@ Language: [Python](https://python.org) 3
7478

7579
##### Windows executable
7680

77-
- [ ] Find a way to make it resident in the task bar with a nice icon, like soundcard control panel
81+
- [x] Find a way to make it resident in the task bar with a nice icon, like soundcard control panel
7882
- [x] [RBTray](https://sourceforge.net/projects/rbtray/files/latest/download)
79-
- [x] [MinimizeToTray](https://github.com/sandwichdoge/MinimizeToTray/releases/latest)
8083
- [ ] The Pythonic Way
8184
- [ ] Handle shutdown to power off the device
82-
- [ ] PyInstaller
85+
- [y] PyInstaller
8386
- [ ] VST plugin? (Not required if MIDI input is implemented but would be neat to have in the monitoring section of a
8487
DAW)
8588
- [ ] See [PyVST](https://pypi.org/project/pyvst/)

Unicode_IEC_symbol.ttf

2.2 KB
Binary file not shown.

assets/DN-500AV.png

23.1 KB
Loading

config.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
from telnetlib import TELNET_PORT
22

3+
DEBUG = False
4+
5+
GUI = True
6+
7+
# TODO: override at build time
8+
BUILD_DATE = '<source>'
9+
310
RECEIVER_IP = '192.168.1.24'
411
RECEIVER_PORT = TELNET_PORT
5-
GUI = True
6-
DEBUG = True
712

813
VOL_PRESET_1 = '-30.0dB'
914
VOL_PRESET_2 = '-24.0dB'

denon/communication.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,24 @@ def lineReceived(self, line):
5252
state = False
5353
if receiver.parameter_code == 'ON':
5454
state = True
55-
self.factory.app.set_mute_button(state)
55+
self.factory.app.update_volume_mute(state)
5656

5757
# VOLUME
5858
if receiver.command_code == 'MV':
5959
if receiver.subcommand_code is None:
60-
self.factory.app.set_volume(receiver.parameter_label)
60+
self.factory.app.update_volume(receiver.parameter_label)
6161

6262
# POWER
6363
if receiver.command_code == 'PW':
6464
state = True
6565
if receiver.parameter_code == 'STANDBY':
6666
state = False
67-
self.factory.app.set_power_button(state)
67+
self.factory.app.update_power(state)
6868

6969
# SOURCE
7070
if receiver.command_code == 'SI':
7171
source = receiver.parameter_code
72-
self.factory.app.set_source(source)
72+
self.factory.app.update_source(source)
7373

7474
def connectionMade(self):
7575
if self.factory.gui:
@@ -100,7 +100,6 @@ def get_mute(self):
100100
self.sendLine('MU?'.encode('ASCII'))
101101

102102
def set_mute(self, state):
103-
self.logger.debug("Entering mute callback")
104103
if state:
105104
self.sendLine('MUON'.encode('ASCII'))
106105
else:

denon/dn500av.py

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,25 +78,48 @@ def srange(start, stop, step, length):
7878
MASTER_VOLUME_ZERODB_REF = 80
7979

8080

81-
def compute_master_volume_label(value):
81+
def compute_master_volume_label(value, zerodb_ref=MASTER_VOLUME_ZERODB_REF):
8282
"""Convert Master Volume ASCII value to dB"""
8383
# TODO: Handle absolute values
84-
label = ''
84+
label = '---.-dB'
8585
if int(value[:2]) < MASTER_VOLUME_MIN or int(value[:2]) > MASTER_VOLUME_MAX:
8686
logger.error("Master volume value %s out of bounds (%s-%s)", value, MASTER_VOLUME_MIN, MASTER_VOLUME_MAX)
8787
# Quirks
8888
if value == '99':
89-
label = "-∞dB"
89+
result = "-∞dB"
9090
elif value == '995':
91-
label = "-80.5dB"
92-
else:
91+
result = "-80.5dB"
92+
elif len(value) == 2:
9393
# General case
94+
result = str(float(value) - zerodb_ref)
95+
elif len(value) == 3:
96+
# Handle undocumented special case for half dB
97+
98+
# Hardcode values around 0 because of computing sign uncertainty
9499
# FIXME: test '985' which seems invalid
95-
if len(value) == 2:
96-
label = str(float(value) - MASTER_VOLUME_ZERODB_REF) + "dB"
97-
if len(value) == 3:
98-
# Handle undocumented special case for half dB
99-
label = str(int(value[:2]) - MASTER_VOLUME_ZERODB_REF) + ".5" + "dB"
100+
if value == str((zerodb_ref - 1)) + '5':
101+
result = "-0.5"
102+
elif value == str(zerodb_ref) + '5':
103+
result = "0.5"
104+
else:
105+
value = int(value[:2]) # Drop the third digit
106+
offset = 0
107+
if value < zerodb_ref:
108+
offset = 1
109+
logger.debug("Add offset %i to dB calculation with value %i5", offset, value)
110+
result = str(int(value + offset - zerodb_ref)) + ".5"
111+
else:
112+
raise ValueError
113+
114+
# Format label with fixed width like the actual display:
115+
# [ NEG SIGN or EMPTY ] [ DIGIT er EMPTY ] [ DIGIT ] [ DOT ] [ DIGIT ] [ d ] [ B ]
116+
label = "%s%s%s.%sdB" % (
117+
result[0] if result[0] == '-' else " ",
118+
" " if len(result) <= 3 or result[-4] == '-' else result[-4],
119+
result[-3],
120+
result[-1])
121+
122+
logger.debug(label)
100123
return label
101124

102125

@@ -734,7 +757,7 @@ def parse_response(self, status_command):
734757
self.logger.error("Command unknown: %s", status_command)
735758
return
736759
else:
737-
self.logger.info("Found command %s: %s", self.command_code, self.command_label)
760+
self.logger.info("Parsed command %s: %s", self.command_code, self.command_label)
738761

739762
# Trim command from status command stream
740763
status_command = status_command[len(self.command_code):]
@@ -757,7 +780,7 @@ def parse_response(self, status_command):
757780
self.logger.debug("Subcommand unknown. Probably a parameter: %s", status_command)
758781
self.subcommand_code = None
759782
else:
760-
self.logger.info("Found subcommand %s: %s", self.subcommand_code, self.subcommand_label)
783+
self.logger.info("Parsed subcommand %s: %s", self.subcommand_code, self.subcommand_label)
761784
# Trim subcommand from status command stream
762785
status_command = status_command[
763786
len(self.subcommand_code) + 1:] # Subcommands have a space before the parameter
@@ -778,7 +801,7 @@ def parse_response(self, status_command):
778801

779802
# Handle unexpected leftovers
780803
if status_command:
781-
self.logger.error("unexpected unparsed data found: %s", status_command)
804+
self.logger.error("Unexpected unparsed data found: %s", status_command)
782805

783806
if self.subcommand_label:
784807
self.response = "%s, %s: %s" % (self.command_label, self.subcommand_label, self.parameter_label)
@@ -793,7 +816,7 @@ class DN500AVFormat():
793816

794817
def __init__(self, logger=None):
795818
self.logger = logger
796-
self.mv_reverse_params = new_dict = dict([(value, key) for key, value in mv_params.items()])
819+
self.mv_reverse_params = dict([(value, key) for key, value in mv_params.items()])
797820

798821
def get_raw_volume_value_from_db_value(self, value):
799822
self.logger.debug('value: %s', value)

denonremote.spec

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ from kivy_deps import sdl2, glew
44

55
block_cipher = None
66

7+
added_files = [
8+
( 'Unicode_IEC_symbol.ttf', '.' ),
9+
('assets', 'assets')
10+
]
711

812
a = Analysis(['main.py'],
913
pathex=['G:\\raph\\Documents\\GitHub\\denonremote'],
1014
binaries=[],
11-
datas=[],
15+
datas=added_files,
1216
hiddenimports=[],
1317
hookspath=[],
1418
runtime_hooks=[],

0 commit comments

Comments
 (0)