Läuft die Voice Acoustic VA-Remotecontrol (AllDSP AllControl) nativ unter Linux auf echtem wxGTK 3.0 — ohne Wine und ohne dekompilierten App-Code. Ausgeführt wird das unveränderte Python-2.7-Bytecode aus dem macOS-.app; C-Extensions (wxGTK/numpy/ scipy/PortAudio) kommen nativ aus Debian stretch. Enthält: va/ (Original-.pyc + pure-Python-Libs + Assets + launch.py mit den drei Linux-Fixes), Dockerfile/run.sh/entrypoint.sh, reference/ (dekompilierter Quellcode zum Debuggen) und README/STATUS. img.cache (378 MB, regenerierbar) ist per .gitignore ausgeschlossen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1605 lines
54 KiB
Python
1605 lines
54 KiB
Python
# uncompyle6 version 3.9.3
|
|
# Python bytecode version base 2.6 (62161)
|
|
# Decompiled from: Python 3.9.25 (main, Oct 31 2025, 23:16:49)
|
|
# [GCC 14.2.0]
|
|
# Embedded file name: protocol.pyc
|
|
# Compiled at: 2024-11-13 09:37:24
|
|
import socket, collections, mytime, threading, copy, struct, types, os.path, wx, codecs, string, sys, one_unit, main, data_model, traceback
|
|
from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EBADF, ECONNABORTED, EPIPE, errorcode
|
|
fBELL = 128
|
|
fNOTCH = 129
|
|
fAllpass = 130
|
|
fLowShelf = 131
|
|
fHighShelf = 132
|
|
fBandPass = 133
|
|
fHighPass = 134
|
|
fLowPass = 136
|
|
confInitRunning = 1
|
|
confMemoryTestFailed = 2
|
|
confStandby = 4
|
|
confCodecFailed = 8
|
|
confDSPNotSynced = 16
|
|
confProtect = 32
|
|
confDimDisplay = 64
|
|
confDisableDisplay = 128
|
|
confUserConfig = 256
|
|
confPresetChanged = 512
|
|
confAESBackup = 1024
|
|
confPrepareForFirmwareUpdate = 2048
|
|
confToneControlBass = 4096
|
|
confToneControlMid = 8192
|
|
confToneControlTreble = 16384
|
|
confTelnetEnabled = 32768
|
|
flagLockFrontPanelkeys = 524288
|
|
flagAvbEnabled = 1048576
|
|
flagAvbBound = 2097152
|
|
flagAvbLocked = 4194304
|
|
confNone = 0
|
|
confTwoWay = 4096
|
|
confAllModes = 61440
|
|
confBridge = 256
|
|
HARDWARE_STATUS_FLAGS_READ_ONLY_MASK = 4278190911L
|
|
cmdNone = 0
|
|
cmdLoadPreset = 1
|
|
cmdSavePreset = 2
|
|
cmdResetCommunication = 3
|
|
cmdGotoStandby = 4
|
|
cmdExitStandby = 5
|
|
cmdLocate = 6
|
|
cmdActivateNewNetworkSettings = 14
|
|
cmdMirrorFIR = 16
|
|
cmdChangeUnitType = 17
|
|
cmdWriteGlobal = 19
|
|
cmdLogin = 20
|
|
cmdPrepareForFirmwareUpdate = 23
|
|
cmdSaveLastPreset = 24
|
|
cmdLoadLastPreset = 25
|
|
cmdLoadEmptyPreset = 26
|
|
cmdClearUserPresets = 27
|
|
cmdClearFactoryPresets = 28
|
|
cmdLoadSpeakerFromLibrary = 30
|
|
cmdResetLog = 31
|
|
cmdStartTest = 32
|
|
cmdStoreFactoryDefaults = 33
|
|
uAllDSP = 0
|
|
uFactory = 1
|
|
uDeveloper = 2
|
|
uAdmin = 3
|
|
uUser = 4
|
|
uLocked = 5
|
|
USER_TEXT = {uAllDSP: 'AllDSP',
|
|
uFactory: 'Factory',
|
|
uDeveloper: 'Developer',
|
|
uAdmin: 'Admin',
|
|
uUser: 'User',
|
|
uLocked: 'Locked'}
|
|
USER_EXT = {uAllDSP: '_d',
|
|
uFactory: '_f',
|
|
uDeveloper: '_d',
|
|
uAdmin: '_a',
|
|
uUser: '_u',
|
|
uLocked: '_l'}
|
|
arInChannel = 1
|
|
arOutChannel = 2
|
|
arLoadPreset = 4
|
|
arSavePreset = 8
|
|
arFrontPanelEnabled = 16
|
|
arDisplayLock = 16384
|
|
arLanguage = 32768
|
|
arUserAccessRights = 65536
|
|
arLockedAccessRights = 131072
|
|
arUnitName = 262144
|
|
arAutoLock = 524288
|
|
arUnitConfiguration = 1048576
|
|
arLoadEmptyPreset = 2097152
|
|
arAdminAccessRights = 4194304
|
|
arDeveloperAccessRights = 8388608
|
|
arUpgradeFirmware = 16777216
|
|
arShowFullSkin = 33554432
|
|
arMasterVolumeControl = 67108864
|
|
arToneControl = 134217728
|
|
arAllAccessRights = 268419103
|
|
arAlwaysSettableForDeveloper = arShowFullSkin
|
|
ACCESS_RIGHTS_TEXT = {arInChannel: 'Access Input Channel',
|
|
arOutChannel: 'Access Output Channel',
|
|
arLoadPreset: 'Load Presets (Attention: Disabling leads to severe restrictions for the user!)',
|
|
arSavePreset: 'Save Presets',
|
|
arFrontPanelEnabled: 'Enable Front Panel Access',
|
|
arLanguage: 'Select Language',
|
|
arDisplayLock: 'Enable Lock Unit',
|
|
arLockedAccessRights: 'Change Access Rights for Locked level',
|
|
arUserAccessRights: 'Change Access Rights for User level',
|
|
arUnitName: 'Change Unit Name',
|
|
arAutoLock: 'Lock Automatically After Power Cycle',
|
|
arUnitConfiguration: 'Change Unit Configuration',
|
|
arAdminAccessRights: 'Change Access Rights for Administrator level',
|
|
arDeveloperAccessRights: 'Change Access Rights for Developer level',
|
|
arLoadEmptyPreset: 'Load an Empty Preset',
|
|
arUpgradeFirmware: 'Upgrade the unit firmware',
|
|
arShowFullSkin: 'Show Full Graphics',
|
|
arMasterVolumeControl: 'Master Volume Control',
|
|
arToneControl: 'Tone Control'}
|
|
PRESET_ACCESS_RIGHTS_TEXT = {1: 'Access Input Channel',
|
|
2: 'Access Output Channel'}
|
|
PRESET_ACCESS_RIGHTS_MASK = 3
|
|
OPCODE_DATA_END = 0
|
|
OPCODE_VU_DATA_IN = 1
|
|
OPCODE_VU_DATA_OUT = 2
|
|
OPCODE_GR_DATA_IN = 7
|
|
OPCODE_GR_DATA_OUT = 8
|
|
OPCODE_GET = 3
|
|
OPCODE_SET = 4
|
|
OPCODE_RSP = 5
|
|
OPCODE_ERR = 6
|
|
OPCODE_CHECKSUM = 9
|
|
OPCODE_FACTORY = 10
|
|
OPCODE_RAW_VU_IN = 11
|
|
OPCODE_VU_DATA_READING = 12
|
|
OPCODE_INCLINATION = 13
|
|
OPCODE_ORIENTATION = 14
|
|
OPCODE_ACTIVITY_LOG = 15
|
|
OPCODE_TEST_RESULT = 16
|
|
OPCODE_GPI = 17
|
|
OPCODE_ADC = 18
|
|
OPCODE_FOUND_HARDWARE = 19
|
|
OPCODE_LIST_SLAVES = 98
|
|
OPCODE_ID = 99
|
|
STRUCT_ID_VU = -1
|
|
STRUCT_ID_GR = -2
|
|
STRUCT_ID_RAW_VU = -3
|
|
STRUCT_ID_GAIN = 0
|
|
STRUCT_ID_MIXER = 1
|
|
STRUCT_ID_DELAY = 2
|
|
STRUCT_ID_LPF = 3
|
|
STRUCT_ID_HPF = 4
|
|
STRUCT_ID_PEQ = 5
|
|
STRUCT_ID_LIMITER = 6
|
|
STRUCT_ID_MUTE = 7
|
|
STRUCT_ID_INVERT = 8
|
|
STRUCT_ID_PRESET_GLOBAL = 9
|
|
STRUCT_ID_LINK = 10
|
|
STRUCT_ID_COMMAND = 11
|
|
STRUCT_ID_COMPRESSOR = 12
|
|
STRUCT_ID_GLOBAL = 13
|
|
STRUCT_ID_CHANNEL = 14
|
|
STRUCT_ID_FIR = 15
|
|
STRUCT_ID_FIR_BLOCK = 16
|
|
STRUCT_ID_PROTECT = 17
|
|
STRUCT_ID_AVB_CONTROL = 18
|
|
STRUCT_ID_UI_CONTROL = 32
|
|
STRUCT_ID_ADC_READING = 254
|
|
STRUCT_ID_INTERNAL = 255
|
|
MEMBER_ID_GAIN = 0
|
|
MEMBER_ID_FREQ = 1
|
|
MEMBER_ID_Q = 2
|
|
MEMBER_ID_TYPE = 3
|
|
MEMBER_ID_THRESHOLD = 4
|
|
MEMBER_ID_ATTACK = 5
|
|
MEMBER_ID_RELEASE = 6
|
|
MEMBER_ID_HOLD = 7
|
|
MEMBER_ID_DELAY = 8
|
|
MEMBER_ID_STATUS = 9
|
|
MEMBER_ID_VU_IN = 10
|
|
MEMBER_ID_VU_OUT = 11
|
|
MEMBER_ID_GR_IN = 12
|
|
MEMBER_ID_GR_OUT = 13
|
|
MEMBER_ID_MUTE = 14
|
|
MEMBER_ID_INVERT = 15
|
|
MEMBER_ID_SHORT_NAME = 16
|
|
MEMBER_ID_LONG_NAME = 17
|
|
MEMBER_ID_PRESET_NUMBER = 18
|
|
MEMBER_ID_PRESET_VERSION = 19
|
|
MEMBER_ID_NUMBER_OF_GROUPS = 20
|
|
MEMBER_ID_NUMBER_OF_WAYS = 21
|
|
MEMBER_ID_GROUND_LIFT = 22
|
|
MEMBER_ID_LANGUAGE = 23
|
|
MEMBER_ID_ON = 24
|
|
MEMBER_ID_LINK = 25
|
|
MEMBER_ID_COMMAND = 26
|
|
MEMBER_ID_RATIO = 27
|
|
MEMBER_ID_SET_PASSWORD = 28
|
|
MEMBER_ID_CHECK_PASSWORD = 29
|
|
MEMBER_ID_ACCESS_RIGHTS = 30
|
|
MEMBER_ID_USER_ACCESS_RIGHTS = 31
|
|
MEMBER_ID_SW_VERSION = 33
|
|
MEMBER_ID_STANDBY_DELAY = 34
|
|
MEMBER_ID_HARDWARE_STATUS_FLAGS = 35
|
|
MEMBER_ID_CONFIGURATION = 36
|
|
MEMBER_ID_AMP_READINGS = 37
|
|
MEMBER_ID_CURRENT_USER = 38
|
|
MEMBER_ID_AMP_READINGS_2 = 39
|
|
MEMBER_ID_SUBNET_MASK = 40
|
|
MEMBER_ID_STARTUP_PRESET = 43
|
|
MEMBER_ID_INPUT_SELECT = 44
|
|
MEMBER_ID_AES_FS = 45
|
|
MEMBER_ID_CONNECTOR_NAME = 46
|
|
MEMBER_ID_RAW_VU_IN = 47
|
|
MEMBER_ID_MODEL_NUMBER = 48
|
|
MEMBER_ID_MODEL_FIRMWARE = 49
|
|
MEMBER_ID_MODEL_NAME = 50
|
|
MEMBER_ID_PIN = 51
|
|
MEMBER_ID_CHECK_PIN = 52
|
|
MEMBER_ID_BUILD_NUMBER = 53
|
|
MEMBER_ID_VOLTAGE_READING = 54
|
|
MEMBER_ID_CURRENT_READING = 55
|
|
MEMBER_ID_POWER_READING = 56
|
|
MEMBER_ID_IMPEDANCE_READING = 57
|
|
MEMBER_ID_LINK_TO_FIR = 58
|
|
MEMBER_ID_ACTIVITY_LOG = 59
|
|
MEMBER_ID_TEST_RESULT = 60
|
|
MEMBER_ID_KNEE = 61
|
|
MEMBER_ID_THRESHOLD_LIMIT = 62
|
|
MEMBER_ID_GAIN_ADJUSTMENT = 63
|
|
MEMBER_ID_UI_CONTROL = 64
|
|
MEMBER_ID_PROTECT = 65
|
|
MEMBER_ID_IP = 87
|
|
MEMBER_ID_FIR = 128
|
|
MEMBER_ID_Q_BW = 1000
|
|
MEMBER_ID_FACTORY_UNITS_LIST = 1001
|
|
MEMBER_ID_ADC_READING = 1002
|
|
MEMBER_ID_VD_READING = 1003
|
|
MEMBER_ID_VCC_READING = 1004
|
|
MEMBER_ID_VSS_READING = 1005
|
|
MEMBER_ID_TEMPERATURE = 1006
|
|
MEMBER_ID_UI_MODEL_NAME = 1007
|
|
unit_global_items = (
|
|
MEMBER_ID_SET_PASSWORD,
|
|
MEMBER_ID_CHECK_PASSWORD,
|
|
MEMBER_ID_SW_VERSION,
|
|
MEMBER_ID_CURRENT_USER,
|
|
MEMBER_ID_IP,
|
|
MEMBER_ID_SUBNET_MASK,
|
|
MEMBER_ID_STARTUP_PRESET,
|
|
MEMBER_ID_MODEL_NUMBER,
|
|
MEMBER_ID_MODEL_FIRMWARE,
|
|
MEMBER_ID_MODEL_NAME,
|
|
MEMBER_ID_BUILD_NUMBER)
|
|
STRUCT_ID_TEXT = (
|
|
'Gain',
|
|
'Mixer',
|
|
'Delay',
|
|
'LPF',
|
|
'HPF',
|
|
'PEQ',
|
|
'Limiter',
|
|
'Mute',
|
|
'Invert',
|
|
'Preset Global',
|
|
'Link',
|
|
'Command',
|
|
'Compressor',
|
|
'Global',
|
|
'Channel',
|
|
'FIR',
|
|
'FIR Block',
|
|
'Protect',
|
|
'AVB Control',
|
|
'',
|
|
'',
|
|
'',
|
|
'',
|
|
'',
|
|
'',
|
|
'',
|
|
'',
|
|
'',
|
|
'',
|
|
'',
|
|
'',
|
|
'',
|
|
'UI Control')
|
|
MEMB_ID_TEXT = {MEMBER_ID_VU_IN: 'VU in',
|
|
MEMBER_ID_VU_OUT: 'VU out',
|
|
MEMBER_ID_GR_IN: 'GR in',
|
|
MEMBER_ID_GR_OUT: 'GR out',
|
|
MEMBER_ID_GAIN: 'Gain',
|
|
MEMBER_ID_FREQ: 'Frequency',
|
|
MEMBER_ID_Q: 'Q',
|
|
MEMBER_ID_TYPE: 'Type',
|
|
MEMBER_ID_THRESHOLD: 'Threshold',
|
|
MEMBER_ID_ATTACK: 'Attack',
|
|
MEMBER_ID_RELEASE: 'Release',
|
|
MEMBER_ID_HOLD: 'Hold',
|
|
MEMBER_ID_RATIO: 'Ratio',
|
|
MEMBER_ID_DELAY: 'Delay',
|
|
MEMBER_ID_PRESET_NUMBER: 'Number',
|
|
MEMBER_ID_SHORT_NAME: 'Name',
|
|
MEMBER_ID_LONG_NAME: 'Long Name',
|
|
MEMBER_ID_STATUS: 'Status',
|
|
MEMBER_ID_MUTE: 'Mute',
|
|
MEMBER_ID_COMMAND: 'Command',
|
|
MEMBER_ID_INVERT: 'Invert',
|
|
MEMBER_ID_ON: 'Enable',
|
|
MEMBER_ID_LINK: 'Link',
|
|
MEMBER_ID_Q_BW: 'Q_BW',
|
|
MEMBER_ID_SET_PASSWORD: 'Set Password',
|
|
MEMBER_ID_CHECK_PASSWORD: 'Password',
|
|
MEMBER_ID_ACCESS_RIGHTS: 'Access Rights',
|
|
MEMBER_ID_USER_ACCESS_RIGHTS: 'User Access Rights',
|
|
MEMBER_ID_SW_VERSION: 'Software Version',
|
|
MEMBER_ID_STANDBY_DELAY: 'Standby Delay',
|
|
MEMBER_ID_HARDWARE_STATUS_FLAGS: 'Hardware Settings',
|
|
MEMBER_ID_CONFIGURATION: 'Configuration',
|
|
MEMBER_ID_AMP_READINGS: 'Amplifier Readings',
|
|
MEMBER_ID_AMP_READINGS_2: 'Amplifier Readings 2',
|
|
MEMBER_ID_CURRENT_USER: 'Current user',
|
|
MEMBER_ID_IP: 'IP',
|
|
MEMBER_ID_SUBNET_MASK: 'Subnet Mask',
|
|
MEMBER_ID_STARTUP_PRESET: 'Startup Preset',
|
|
MEMBER_ID_INPUT_SELECT: 'Input Select',
|
|
MEMBER_ID_AES_FS: 'AES Sample rate',
|
|
MEMBER_ID_RAW_VU_IN: 'Raw input VU',
|
|
MEMBER_ID_FIR: 'FIR',
|
|
MEMBER_ID_CONNECTOR_NAME: 'Connector Name',
|
|
MEMBER_ID_MODEL_NUMBER: 'Model Number',
|
|
MEMBER_ID_MODEL_FIRMWARE: 'Model Firmware',
|
|
MEMBER_ID_MODEL_NAME: 'Model Name',
|
|
MEMBER_ID_PIN: 'Set PIN',
|
|
MEMBER_ID_CHECK_PIN: 'PIN',
|
|
MEMBER_ID_BUILD_NUMBER: 'Build Number',
|
|
MEMBER_ID_LINK_TO_FIR: 'FIR',
|
|
MEMBER_ID_UI_CONTROL: 'UI Control',
|
|
MEMBER_ID_PROTECT: 'Protect',
|
|
MEMBER_ID_KNEE: 'Knee',
|
|
MEMBER_ID_THRESHOLD_LIMIT: 'Output Threshold Limit',
|
|
MEMBER_ID_GAIN_ADJUSTMENT: 'Output Gain Adjustment'}
|
|
MEMBER_FORMATS = {MEMBER_ID_VU_IN: 'b',
|
|
MEMBER_ID_VU_OUT: 'b',
|
|
MEMBER_ID_GR_IN: 'b',
|
|
MEMBER_ID_GR_OUT: 'b',
|
|
MEMBER_ID_GAIN: '>h',
|
|
MEMBER_ID_FREQ: '>H',
|
|
MEMBER_ID_Q: '>H',
|
|
MEMBER_ID_TYPE: 'B',
|
|
MEMBER_ID_THRESHOLD: '>h',
|
|
MEMBER_ID_ATTACK: '>h',
|
|
MEMBER_ID_RELEASE: '>h',
|
|
MEMBER_ID_HOLD: '>h',
|
|
MEMBER_ID_RATIO: '>h',
|
|
MEMBER_ID_DELAY: '>L',
|
|
MEMBER_ID_PRESET_NUMBER: '>L',
|
|
MEMBER_ID_SHORT_NAME: '16s',
|
|
MEMBER_ID_LONG_NAME: '64s',
|
|
MEMBER_ID_STATUS: 'B',
|
|
MEMBER_ID_MUTE: 'B',
|
|
MEMBER_ID_COMMAND: 'B',
|
|
MEMBER_ID_INVERT: 'B',
|
|
MEMBER_ID_ON: 'B',
|
|
MEMBER_ID_LINK: 'B',
|
|
MEMBER_ID_SHORT_NAME: '16s',
|
|
MEMBER_ID_Q_BW: 'B',
|
|
MEMBER_ID_SET_PASSWORD: '8s',
|
|
MEMBER_ID_CHECK_PASSWORD: '8s',
|
|
MEMBER_ID_ACCESS_RIGHTS: '>L',
|
|
MEMBER_ID_USER_ACCESS_RIGHTS: '>L',
|
|
MEMBER_ID_SW_VERSION: '>L',
|
|
MEMBER_ID_STANDBY_DELAY: '>L',
|
|
MEMBER_ID_HARDWARE_STATUS_FLAGS: '>L',
|
|
MEMBER_ID_CONFIGURATION: '>L',
|
|
MEMBER_ID_AMP_READINGS: '>L',
|
|
MEMBER_ID_AMP_READINGS_2: '>L',
|
|
MEMBER_ID_CURRENT_USER: '>L',
|
|
MEMBER_ID_IP: '>L',
|
|
MEMBER_ID_SUBNET_MASK: '>L',
|
|
MEMBER_ID_STARTUP_PRESET: '>L',
|
|
MEMBER_ID_INPUT_SELECT: '>L',
|
|
MEMBER_ID_AES_FS: '>L',
|
|
MEMBER_ID_RAW_VU_IN: 'b',
|
|
MEMBER_ID_FIR: '>l',
|
|
MEMBER_ID_CONNECTOR_NAME: '16s',
|
|
MEMBER_ID_MODEL_NUMBER: '>L',
|
|
MEMBER_ID_MODEL_FIRMWARE: '>L',
|
|
MEMBER_ID_MODEL_NAME: '16s',
|
|
MEMBER_ID_PIN: '>L',
|
|
MEMBER_ID_CHECK_PIN: '>L',
|
|
MEMBER_ID_BUILD_NUMBER: '>L',
|
|
MEMBER_ID_LINK_TO_FIR: 'B',
|
|
MEMBER_ID_UI_CONTROL: '8s',
|
|
MEMBER_ID_KNEE: '>h',
|
|
MEMBER_ID_THRESHOLD_LIMIT: '>h',
|
|
MEMBER_ID_GAIN_ADJUSTMENT: '>h'}
|
|
MEMBER_DATA_TYPES = {MEMBER_ID_GAIN: 'gain',
|
|
MEMBER_ID_FREQ: 'freq',
|
|
MEMBER_ID_Q: 'Q',
|
|
MEMBER_ID_TYPE: 'type',
|
|
MEMBER_ID_THRESHOLD: 'gain',
|
|
MEMBER_ID_ATTACK: 'attack',
|
|
MEMBER_ID_RELEASE: 'attack',
|
|
MEMBER_ID_HOLD: 'attack',
|
|
MEMBER_ID_RATIO: 'ratio',
|
|
MEMBER_ID_KNEE: 'knee',
|
|
MEMBER_ID_DELAY: 'delay',
|
|
MEMBER_ID_SHORT_NAME: '16s',
|
|
MEMBER_ID_MUTE: 'bool',
|
|
MEMBER_ID_INVERT: 'bool',
|
|
MEMBER_ID_ON: 'bool',
|
|
MEMBER_ID_LINK: 'bool',
|
|
MEMBER_ID_INPUT_SELECT: 'inputSelect'}
|
|
MEMBER_SCALE = {MEMBER_ID_GAIN: 100.0,
|
|
MEMBER_ID_Q: 10.0,
|
|
MEMBER_ID_THRESHOLD: 100.0,
|
|
MEMBER_ID_RATIO: 10.0,
|
|
MEMBER_ID_DELAY: 1000.0,
|
|
MEMBER_ID_STANDBY_DELAY: 60000.0,
|
|
MEMBER_ID_AES_FS: 100.0}
|
|
|
|
def get_user_text(user):
|
|
if user in USER_TEXT:
|
|
return USER_TEXT[user]
|
|
else:
|
|
return 'None'
|
|
return
|
|
|
|
|
|
def get_member_format(member_id):
|
|
if member_id not in MEMBER_FORMATS:
|
|
return '>l'
|
|
else:
|
|
return MEMBER_FORMATS[member_id]
|
|
return
|
|
|
|
|
|
def get_member_data_type(member_id):
|
|
if member_id not in MEMBER_DATA_TYPES:
|
|
return
|
|
else:
|
|
return MEMBER_DATA_TYPES[member_id]
|
|
return
|
|
|
|
|
|
def get_member_scale(member_id):
|
|
if member_id in one_unit.app.custom_scale:
|
|
return one_unit.app.custom_scale[member_id]
|
|
else:
|
|
if member_id not in MEMBER_SCALE:
|
|
return 1.0
|
|
return MEMBER_SCALE[member_id]
|
|
return
|
|
|
|
|
|
def get_member_text(member_id):
|
|
if member_id not in MEMB_ID_TEXT:
|
|
return str(member_id)
|
|
else:
|
|
return MEMB_ID_TEXT[member_id]
|
|
return
|
|
|
|
|
|
def get_membid_by_text(text):
|
|
for memb_id in MEMB_ID_TEXT:
|
|
if MEMB_ID_TEXT[memb_id] == text:
|
|
return memb_id
|
|
|
|
return
|
|
|
|
|
|
def get_strid_text(struct_id):
|
|
try:
|
|
return STRUCT_ID_TEXT[struct_id]
|
|
except:
|
|
return str(struct_id)
|
|
|
|
return
|
|
|
|
|
|
def get_strid_by_text(text):
|
|
for struct_id in range(len(STRUCT_ID_TEXT)):
|
|
if STRUCT_ID_TEXT[struct_id] == text:
|
|
return struct_id
|
|
|
|
return
|
|
|
|
|
|
def csvString(key):
|
|
return str(key.struct_id) + '|' + str(key.member_id) + '|' + str(key.channel) + '|' + str(key.num)
|
|
|
|
|
|
def readable(key):
|
|
return get_strid_text(key.struct_id) + ' ' + get_member_text(key.member_id) + ' ' + str(key.channel) + ' ' + str(key.num)
|
|
|
|
|
|
def get_access_text(ar):
|
|
if ar in ACCESS_RIGHTS_TEXT.keys():
|
|
return ACCESS_RIGHTS_TEXT[ar]
|
|
else:
|
|
return 'p.gat.Unknown key: ' + hex(ar)
|
|
return
|
|
|
|
|
|
mac_names = 'posix'
|
|
Key = collections.namedtuple('Key', 'struct_id, member_id, channel, num')
|
|
local_link_retry = 0
|
|
local_link_stopping = False
|
|
|
|
class Unit_var():
|
|
"""The state of an interface variable in a hardware unit"""
|
|
|
|
def __init__(self):
|
|
"""Constructor"""
|
|
self.read_val = None
|
|
self.read_ts = None
|
|
self.change_ts = 0
|
|
self.write_val = None
|
|
self.write_ts = 0
|
|
self.SetCount = 0
|
|
self.set_ts = 0
|
|
return
|
|
|
|
|
|
class UnitLink():
|
|
|
|
def __init__(self, parent):
|
|
self.Connected = False
|
|
self.ResetValues = False
|
|
self.last_key = None
|
|
self.parent = parent
|
|
self.lock = threading.Lock()
|
|
self.errortext = ''
|
|
self.reset()
|
|
self.stopping = False
|
|
self.broadcasted_skin = ''
|
|
self.keepalive = True
|
|
self.last_hw_packet_id = 0
|
|
self.invalid_packet_counter = 0
|
|
self.DisconnectTime = mytime.clock()
|
|
self.Uptime = 0
|
|
self.synced = False
|
|
self.stopped = False
|
|
self.s = None
|
|
self.last_vu = 0
|
|
self.avg_vu_delay = 0
|
|
self.Connected = False
|
|
self.LinkStatus = False
|
|
self.SyncIndicateActive = False
|
|
self.last_rx = 0
|
|
self.hardware_synced = False
|
|
self.vu_list = {}
|
|
self.direct_link = None
|
|
decoding_map = codecs.make_identity_dict(range(128))
|
|
self.encoding_map = codecs.make_encoding_map(decoding_map)
|
|
self.thread = threading.Thread(name='AllDSP Local Client', target=self.process)
|
|
self.thread.daemon = True
|
|
self.parent = parent
|
|
self.buffer = ''
|
|
self.active_mac = 'DEMO'
|
|
self.start()
|
|
return
|
|
|
|
def reset(self):
|
|
self.Connected = False
|
|
self.received_data = None
|
|
self.LinkStatus = False
|
|
if self.parent.MAC[:4] != 'GRP_':
|
|
self.ResetValues = True
|
|
self.SyncIndicateActive = False
|
|
self.last_peq_key = None
|
|
self.last_xover_key = None
|
|
self.values = {}
|
|
self.last_requested = 0
|
|
self.next_command = None
|
|
self.next_command_params = []
|
|
self.NO_GET_LIST = []
|
|
for i in range(8):
|
|
if i > 0:
|
|
key = Key(STRUCT_ID_PRESET_GLOBAL, MEMBER_ID_CONFIGURATION, i, 0)
|
|
self.NO_GET_LIST.append(key)
|
|
key = Key(STRUCT_ID_PRESET_GLOBAL, MEMBER_ID_CONFIGURATION, i + 128, 0)
|
|
self.NO_GET_LIST.append(key)
|
|
self.NO_GET_LIST.append(Key(13, 37, i, 0))
|
|
self.NO_GET_LIST.append(Key(13, 37, i + 128, 0))
|
|
self.NO_GET_LIST.append(Key(13, 39, i, 0))
|
|
self.NO_GET_LIST.append(Key(13, 39, i + 128, 0))
|
|
|
|
self.NO_GET_LIST.append(Key(STRUCT_ID_GLOBAL, MEMBER_ID_SET_PASSWORD, 0, 0))
|
|
self.NO_GET_LIST.append(Key(STRUCT_ID_GLOBAL, MEMBER_ID_CHECK_PASSWORD, 0, 0))
|
|
self.NO_GET_LIST.append(Key(13, 47, 0, 0))
|
|
self.NO_GET_LIST.append(Key(13, 48, 0, 0))
|
|
self.NO_GET_LIST.append(Key(13, 49, 0, 0))
|
|
self.NO_GET_LIST.append(Key(13, 50, 0, 0))
|
|
self.NO_GET_LIST.append(Key(9, 28, 0, 0))
|
|
self.NO_GET_LIST.append(Key(9, 31, 0, 1))
|
|
self.NO_GET_LIST.append(Key(9, 31, 0, 0))
|
|
self.NO_GET_LIST.append(Key(13, 31, 0, 1))
|
|
self.NO_GET_LIST.append(Key(13, 31, 0, 0))
|
|
return
|
|
|
|
def PowerSingleUnit(self, mac, mute):
|
|
self.next_command = 'power_single_unit'
|
|
self.next_command_params = (mac, mute)
|
|
return
|
|
|
|
def PowerGroup(self, group, mute):
|
|
self.next_command = 'power_group'
|
|
self.next_command_params = (group, mute)
|
|
return
|
|
|
|
def MuteSingleUnit(self, mac, mute):
|
|
self.next_command = 'mute_single_unit'
|
|
self.next_command_params = (mac, mute)
|
|
self.parent.peers.units[mac].Muted = str(mute)
|
|
return
|
|
|
|
def MuteGroup(self, group, mute):
|
|
self.next_command = 'mute_group'
|
|
self.next_command_params = (group, mute)
|
|
try:
|
|
if group == 'all_units':
|
|
maclist = self.parent.peers.units.keys()
|
|
else:
|
|
maclist = one_unit.app.groups[group].keys()
|
|
except:
|
|
print mytime.displayTime() + ' Unknown Group', group
|
|
traceback.print_exc(file=sys.stdout)
|
|
return
|
|
else:
|
|
for mac in maclist:
|
|
if mac not in one_unit.app.pin_verified:
|
|
continue
|
|
if one_unit.app.pin_verified[mac] == False:
|
|
continue
|
|
self.parent.peers.units[mac].Muted = str(mute)
|
|
|
|
return
|
|
|
|
def MakeImage(self, mac):
|
|
one_unit.updateBootloaderDial(mac, 'Preparing Flash Image')
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.2)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.2)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.2)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.2)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.2)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.2)
|
|
one_unit.tryYield()
|
|
self.next_command = 'make_image'
|
|
self.next_command_params = mac
|
|
return
|
|
|
|
def UpdateDisplay(self, mac):
|
|
one_unit.updateBootloaderDial(mac, 'Starting Display Update')
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.2)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.2)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.2)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.2)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.2)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.2)
|
|
one_unit.tryYield()
|
|
self.next_command = 'update_display'
|
|
self.next_command_params = mac
|
|
return
|
|
|
|
def LocateUnit(self, mac):
|
|
self.next_command = 'locate_unit'
|
|
self.next_command_params = mac
|
|
return
|
|
|
|
def StartMainUpdate(self, mac, ignore_version=False):
|
|
print mytime.displayTime(), 'p.smu.Starting update of', mac, ignore_version
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.02)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.02)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.02)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.02)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.02)
|
|
one_unit.tryYield()
|
|
mytime.sleep(0.02)
|
|
one_unit.tryYield()
|
|
self.next_command = 'start_main_update'
|
|
self.next_command_params = (mac, ignore_version)
|
|
return
|
|
|
|
def ClearDataBuffer(self):
|
|
self.next_command = 'clear_data_buffer'
|
|
self.next_command_params = ()
|
|
return
|
|
|
|
def clear_data_buffer(self, MAC=None):
|
|
if self.parent.MAC[:4] in ('DEMO', 'GRPdeactivated'):
|
|
self.next_command = None
|
|
return
|
|
else:
|
|
if MAC == None:
|
|
MAC = self.parent.MAC
|
|
if MAC.count(':') != 5:
|
|
print mytime.displayTime(), 'p.cdb.No valid MAC found, aborting. MAC:', MAC
|
|
self.next_command = None
|
|
return
|
|
if self.send('clear_data_buffer' + MAC) == False:
|
|
print mytime.displayTime(), 'p.cdb.Failed!!', MAC
|
|
self.next_command = None
|
|
return
|
|
retry = 100
|
|
while retry > 0 and not self.stopping and one_unit.app.application_stopping == False:
|
|
retry -= 1
|
|
pkt = self.recv()
|
|
if pkt == None:
|
|
mytime.sleep(0.01)
|
|
continue
|
|
elif pkt == 'clear_data_buffer_ok':
|
|
self.next_command = None
|
|
self.values = {}
|
|
return
|
|
|
|
return
|
|
|
|
def process(self):
|
|
pkt = None
|
|
last_pkt = None
|
|
self.start_server()
|
|
timestamp = 0
|
|
try:
|
|
while self.parent.active_unit == None and self.stopping == False and one_unit.app.application_stopping == False:
|
|
if mytime.clock() - timestamp > 1:
|
|
timestamp = mytime.clock()
|
|
self.get_unit_list(s)
|
|
else:
|
|
mytime.sleep(0.05)
|
|
|
|
except:
|
|
return
|
|
else:
|
|
loopcounter = 0
|
|
list_delay = 0.5
|
|
self.MAC = self.parent.MAC
|
|
while self.parent and not self.stopping and one_unit.app.application_stopping == False:
|
|
if mytime.clock() > 15:
|
|
list_delay = 1
|
|
if self.next_command != None:
|
|
if self.next_command == 'clear_data_buffer':
|
|
self.clear_data_buffer()
|
|
if self.next_command == 'start_main_update':
|
|
self.start_main_update(self.next_command_params)
|
|
if self.next_command == 'mute_single_unit':
|
|
self.mute_single_unit(self.next_command_params)
|
|
if self.next_command == 'make_image':
|
|
self.make_image(self.next_command_params)
|
|
if self.next_command == 'update_display':
|
|
self.update_display(self.next_command_params)
|
|
if self.next_command == 'mute_group':
|
|
self.mute_group(self.next_command_params)
|
|
if self.next_command == 'power_single_unit':
|
|
self.power_single_unit(self.next_command_params)
|
|
if self.next_command == 'power_group':
|
|
self.power_group(self.next_command_params)
|
|
if self.next_command == 'locate_unit':
|
|
self.locate_unit(self.next_command_params)
|
|
if mytime.clock() - timestamp > list_delay:
|
|
loopcounter += 1
|
|
timestamp = mytime.clock()
|
|
self.get_unit_list()
|
|
mytime.sleep(0.01)
|
|
if one_unit.app.application_stopping == True or self.stopping == True:
|
|
break
|
|
if one_unit.app.application_stopping == True or self.stopping == True:
|
|
break
|
|
self.update_group_index()
|
|
if one_unit.app.application_stopping == True or self.stopping == True:
|
|
break
|
|
if self.parent and self.parent.master_network_window == True and self.parent.is_child_window == False:
|
|
mytime.sleep(0.1)
|
|
if one_unit.app.application_stopping == True or self.stopping == True:
|
|
break
|
|
self.get_vu_data()
|
|
continue
|
|
if self.direct_link != None:
|
|
counter = 10
|
|
while counter > 0 and self.next_command == None:
|
|
mytime.sleep(0.02)
|
|
counter -= 1
|
|
|
|
continue
|
|
self.lock.acquire()
|
|
keys = self.choose_var_to_update(1)
|
|
vars = {}
|
|
if keys is not None:
|
|
for key in keys:
|
|
var = self.values[key]
|
|
vars[key] = var.write_val
|
|
|
|
self.lock.release()
|
|
if self.parent and self.parent.MAC[:4] not in ('DEMO', 'GRPdeactivated'):
|
|
self.active_mac = self.parent.MAC
|
|
cmd = build_command(self.active_mac, vars, self.parent.loading_factory_presets)
|
|
retry_counter = 10
|
|
self.send(cmd)
|
|
pkt = self.recv()
|
|
if pkt != None:
|
|
if len(pkt) > 0:
|
|
self.process_data_pkt(parse_data_pkt(pkt))
|
|
mytime.sleep(0.01)
|
|
one_unit.tryYield()
|
|
|
|
if self.s != None:
|
|
self.s.close()
|
|
self.stopped = True
|
|
try:
|
|
print mytime.displayTime() + ' Local Comm Process for', self.MAC, 'Exit'
|
|
except:
|
|
pass
|
|
|
|
return
|
|
|
|
def get_vu_data(self):
|
|
if one_unit.app.application_stopping == True:
|
|
return
|
|
else:
|
|
if self.send('vudata') == False:
|
|
print mytime.displayTime() + ' p.gvd.send failed'
|
|
return
|
|
pkt = self.recv()
|
|
if pkt == None:
|
|
return
|
|
pos = 0
|
|
size = 0
|
|
no_of_units = 0
|
|
if len(pkt) < 8:
|
|
return
|
|
check = pkt[:8]
|
|
if check != 'vu_list:':
|
|
return
|
|
pkt = pkt[8:]
|
|
while pos < len(pkt) - 5:
|
|
if len(pkt) < pos + 19:
|
|
print mytime.displayTime() + ' protocol.invalid data (4)! length: ', len(pkt), ', packet discarded'
|
|
return
|
|
mac = pkt[pos:pos + 17]
|
|
in_vu = struct.unpack('b', pkt[pos + 17])[0]
|
|
out_vu = struct.unpack('b', pkt[pos + 18])[0]
|
|
pos += 19
|
|
self.vu_list[mac] = (in_vu, out_vu)
|
|
|
|
return
|
|
|
|
def locate_unit(self, mac):
|
|
string = 'locate_unit' + chr(len(mac)) + mac
|
|
if self.send(string) == False:
|
|
print mytime.displayTime() + ' send locate command failed'
|
|
return
|
|
else:
|
|
self.next_command = None
|
|
return
|
|
|
|
def start_main_update(self, params):
|
|
mac = params[0]
|
|
ignore_version = params[1]
|
|
if ignore_version == True:
|
|
ignore_version = 'i'
|
|
else:
|
|
ignore_version = 'n'
|
|
string = 'start_main_update' + chr(len(mac)) + mac + ignore_version
|
|
if self.send(string) == False:
|
|
print mytime.displayTime() + ' send update command failed'
|
|
return
|
|
self.next_command = 'clear_data_buffer'
|
|
self.next_command_params = ()
|
|
return
|
|
|
|
def mute_group(self, params):
|
|
group = params[0]
|
|
mute = params[1]
|
|
string = 'mute_group' + chr(len(group)) + group + chr(mute)
|
|
if self.send(string) == False:
|
|
print mytime.displayTime() + ' send mute group command failed'
|
|
return
|
|
else:
|
|
self.next_command = None
|
|
return
|
|
|
|
def mute_single_unit(self, params):
|
|
mac = params[0]
|
|
mute = params[1]
|
|
string = 'mute_single_unit' + chr(len(mac)) + mac + chr(mute)
|
|
if self.send(string) == False:
|
|
print mytime.displayTime() + ' send mute single unit command failed'
|
|
return
|
|
else:
|
|
self.next_command = None
|
|
return
|
|
|
|
def make_image(self, mac):
|
|
string = 'make_image' + chr(len(mac)) + mac
|
|
if self.send(string) == False:
|
|
print mytime.displayTime() + ' make image command failed'
|
|
return
|
|
else:
|
|
self.next_command = None
|
|
return
|
|
|
|
def update_display(self, mac):
|
|
string = 'update_display' + chr(len(mac)) + mac
|
|
if self.send(string) == False:
|
|
print mytime.displayTime() + ' update_display command failed'
|
|
return
|
|
else:
|
|
self.next_command = None
|
|
return
|
|
|
|
def power_group(self, params):
|
|
group = params[0]
|
|
state = params[1]
|
|
string = 'power_group' + chr(len(group)) + group + chr(state)
|
|
if self.send(string) == False:
|
|
print mytime.displayTime() + ' send power group command failed'
|
|
return
|
|
else:
|
|
self.next_command = None
|
|
return
|
|
|
|
def power_single_unit(self, params):
|
|
mac = params[0]
|
|
mute = params[1]
|
|
string = 'power_single_unit' + chr(len(mac)) + mac + chr(mute)
|
|
if self.send(string) == False:
|
|
print mytime.displayTime() + ' send power single unit command failed'
|
|
return
|
|
else:
|
|
self.next_command = None
|
|
return
|
|
|
|
def update_group_index(self):
|
|
if self.send('update_groups' + chr(len(self.parent.MAC.strip())) + self.parent.MAC.strip()) == False:
|
|
return
|
|
return
|
|
|
|
def get_unit_list(self):
|
|
if self.send('list\n') == False:
|
|
return
|
|
else:
|
|
pkt = self.recv()
|
|
if pkt == None:
|
|
return
|
|
if len(pkt) < 10:
|
|
return
|
|
check = pkt[:10]
|
|
if check != 'unit_list:':
|
|
return
|
|
self.lock.acquire()
|
|
pkt = pkt[10:]
|
|
no_of_units = 0
|
|
while len(pkt) > 4:
|
|
try:
|
|
pos = 0
|
|
size = 1
|
|
if pkt[:4] != 'unit':
|
|
break
|
|
pkt = pkt[4:]
|
|
unit = one_unit.RemoteUnit()
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 2:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 1', size, len(pkt)
|
|
break
|
|
unit.MAC = pkt[pos + 1:pos + size + 1]
|
|
pos += size + 1
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 2:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 2', size, len(pkt)
|
|
break
|
|
name = pkt[pos + 1:pos + size + 1]
|
|
try:
|
|
name = unicode(name)
|
|
except:
|
|
print mytime.displayTime() + ' p.gul.Unit Name: unicode error'
|
|
name = 'Unicode Decode Error'
|
|
|
|
unit.name = name
|
|
pos += size + 1
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 2:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 3', size, len(pkt)
|
|
break
|
|
unit.type = pkt[pos + 1:pos + size + 1]
|
|
pos += size + 1
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 2:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 4', size, len(pkt)
|
|
break
|
|
unit.link_type = pkt[pos + 1:pos + size + 1]
|
|
pos += size + 1
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 1:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 5', size, len(pkt)
|
|
break
|
|
unit.link_status = pkt[pos + 1:pos + size + 1]
|
|
pos += size + 1
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 1:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 6', size, len(pkt)
|
|
break
|
|
unit.IP = pkt[pos + 1:pos + size + 1]
|
|
pos += size + 1
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 1:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 7', size, len(pkt)
|
|
break
|
|
unit.Serial = pkt[pos + 1:pos + size + 1]
|
|
pos += size + 1
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 1:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 8', size, len(pkt)
|
|
break
|
|
unit.HWVersion = pkt[pos + 1:pos + size + 1]
|
|
pos += size + 1
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 1:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 9', size, len(pkt)
|
|
break
|
|
unit.FWVersion = pkt[pos + 1:pos + size + 1]
|
|
pos += size + 1
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 1:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 10', size, len(pkt)
|
|
break
|
|
unit.PICVersion = pkt[pos + 1:pos + size + 1]
|
|
pos += size + 1
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 1:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 10b', size, len(pkt)
|
|
break
|
|
unit.originalSwID = pkt[pos + 1:pos + size + 1]
|
|
pos += size + 1
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 1:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 11', size, len(pkt)
|
|
break
|
|
unit.ProductionDate = pkt[pos + 1:pos + size + 1]
|
|
pos += size + 1
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 1:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 12', size, len(pkt)
|
|
break
|
|
unit.Muted = pkt[pos + 1:pos + size + 1]
|
|
pos += size + 1
|
|
size = ord(pkt[pos])
|
|
if size < 1 or len(pkt) < pos + size + 1:
|
|
print mytime.displayTime() + ' p.gul.fragment size fail 13', size, len(pkt)
|
|
break
|
|
unit.BuildNumber = int(pkt[pos + 1:pos + size + 1])
|
|
pos += size + 1
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
continue
|
|
|
|
self.parent.peers.add(unit)
|
|
if self.parent.active_unit != None:
|
|
if unit.MAC == self.parent.MAC:
|
|
if unit.link_status == 'available':
|
|
if self.Connected == False:
|
|
self.Connected = True
|
|
self.SyncIndicateActive = True
|
|
self.ConnectedTime = mytime.clock()
|
|
self.ResetValues = False
|
|
self.parent.active_unit.last_rx = mytime.clock()
|
|
self.Uptime = mytime.clock() - self.ConnectedTime
|
|
else:
|
|
self.Uptime = 0
|
|
if self.Connected == True:
|
|
self.Connected = False
|
|
if mytime.clock() - self.parent.active_unit.last_rx > 5 and self.ResetValues == False:
|
|
self.ResetValues = True
|
|
self.SyncIndicateActive = False
|
|
self.parent.model.reset()
|
|
pkt = pkt[pos:]
|
|
|
|
self.lock.release()
|
|
return
|
|
|
|
def start(self):
|
|
self.thread.start()
|
|
return
|
|
|
|
def choose_var_to_update(self, limit):
|
|
keys = [_[1] for k in self.values.keys() if k[0] >= 0 if k[0] < 255]
|
|
res = []
|
|
no_added = 0
|
|
no_of_new_values = 0
|
|
nitems = len(keys)
|
|
if nitems == 0:
|
|
return
|
|
else:
|
|
if self.last_requested >= nitems:
|
|
self.last_requested = 0
|
|
self.next_requested = self.last_requested
|
|
while no_added < limit and one_unit.app.application_stopping == False:
|
|
key = keys[self.next_requested]
|
|
var = self.values[key]
|
|
if var.write_val is not None:
|
|
no_of_new_values += 1
|
|
if mytime.clock() - var.set_ts > 0.2:
|
|
if var.SetCount < 100:
|
|
var.SetCount = var.SetCount + 1
|
|
var.write_ts = mytime.clock()
|
|
var.set_ts = mytime.clock()
|
|
self.synced = False
|
|
res.append(key)
|
|
no_added += 1
|
|
else:
|
|
channel = key.channel + 1
|
|
if channel > 128:
|
|
channel -= 128
|
|
inout = ', Output '
|
|
else:
|
|
inout = ', Input '
|
|
print mytime.displayTime() + ' protocol.SET Aborted!!!', STRUCT_ID_TEXT[key.struct_id], get_member_text(key.member_id), 'channel', key.channel, 'no. ', key.num, 'tried ', var.write_val
|
|
self.errortext = ('').join(('Setting ', STRUCT_ID_TEXT[key.struct_id], ': ', get_member_text(key.member_id), inout, str(channel), ' no. ', str(key.num + 1), ' is not accepted by the unit!'))
|
|
var.write_val = None
|
|
var.SetCount = 0
|
|
self.next_requested = (self.next_requested + 1) % nitems
|
|
if self.next_requested == self.last_requested:
|
|
break
|
|
|
|
self.last_requested = self.next_requested
|
|
if no_of_new_values == 0:
|
|
self.synced = True
|
|
for key in keys:
|
|
var = self.values[key]
|
|
if var.write_val != None:
|
|
self.synced = False
|
|
break
|
|
|
|
if len(res) == 0:
|
|
return
|
|
return res
|
|
|
|
def build_key(self, struct_id, member_id, channel=0, num=0):
|
|
return Key(struct_id, member_id, channel, num)
|
|
|
|
def get(self, struct_id, member_id, channel=0, num=0):
|
|
struct_id = int(struct_id)
|
|
member_id = int(member_id)
|
|
key = self.build_key(struct_id, member_id, channel, num)
|
|
return self.get_by_key(key)
|
|
|
|
def get_by_key(self, key):
|
|
if key.channel == None or key.channel < 0:
|
|
print mytime.displayTime() + ' protocol.get_by_key.invalid key!', key
|
|
self.lock.acquire()
|
|
try:
|
|
var = self.values[key]
|
|
except KeyError:
|
|
self.values[key] = Unit_var()
|
|
var = self.values[key]
|
|
except:
|
|
self.lock.release()
|
|
raise
|
|
|
|
try:
|
|
self.lock.release()
|
|
except:
|
|
pass
|
|
|
|
return copy.deepcopy(var)
|
|
|
|
def set(self, val, struct_id, member_id, channel=0, num=0):
|
|
key = self.build_key(struct_id, member_id, channel, num)
|
|
return self.set_by_key(key, val)
|
|
|
|
def set_get_key(self, key):
|
|
if key in self.NO_GET_LIST:
|
|
return
|
|
try:
|
|
if self.parent.MAC[:4] in ('DEMO', 'GRPdeactivated'):
|
|
return
|
|
else:
|
|
try:
|
|
del self.values[key]
|
|
except:
|
|
pass
|
|
|
|
self.direct_link.set_get_key(key, self.parent.MAC)
|
|
return
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
return
|
|
|
|
def set_last_key(self, key):
|
|
if key.struct_id == STRUCT_ID_PEQ:
|
|
self.last_peq_key = key
|
|
if key.struct_id == STRUCT_ID_HPF or key.struct_id == STRUCT_ID_LPF:
|
|
self.last_xover_key = key
|
|
return
|
|
|
|
def set_by_key(self, key, val):
|
|
if self.parent.active_unit.link_status != 'available' and self.parent.MAC[:4] != 'GRP_':
|
|
return
|
|
else:
|
|
self.lock.acquire()
|
|
try:
|
|
var = self.values[key]
|
|
except KeyError:
|
|
self.values[key] = Unit_var()
|
|
var = self.values[key]
|
|
except:
|
|
self.lock.release()
|
|
raise
|
|
|
|
if get_member_format(key.member_id)[-1:] == 's':
|
|
if key.member_id != MEMBER_ID_UI_CONTROL:
|
|
if isinstance(val, unicode):
|
|
text = val
|
|
else:
|
|
try:
|
|
text = str(val)
|
|
except:
|
|
text = 'Encode Error'
|
|
|
|
try:
|
|
encoded = codecs.charmap_encode(text, 'replace', self.encoding_map)
|
|
except UnicodeEncodeError, err:
|
|
encoded = str(err)
|
|
else:
|
|
val = encoded[0]
|
|
try:
|
|
val = str(val)
|
|
except:
|
|
val = ''
|
|
else:
|
|
val = val + ' '
|
|
val = val[:int(get_member_format(key.member_id)[:-1])]
|
|
elif key not in one_unit.app.member_scale:
|
|
if key.struct_id == STRUCT_ID_PRESET_GLOBAL and key.member_id == MEMBER_ID_DELAY:
|
|
one_unit.app.member_scale[key] = 1
|
|
one_unit.app.member_offset[key] = 0.0
|
|
else:
|
|
one_unit.app.member_scale[key] = get_member_scale(key.member_id)
|
|
one_unit.app.member_offset[key] = 0.0
|
|
try:
|
|
val = val * one_unit.app.member_scale[key]
|
|
val = val + one_unit.app.member_offset[key]
|
|
val = int(round(val))
|
|
except:
|
|
pass
|
|
|
|
try:
|
|
self.lock.release()
|
|
self.direct_link.set_direct_value(key, val, self.parent.MAC, self.parent.loading_factory_presets, self.parent.group)
|
|
return
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
var.write_val = val
|
|
var.write_ts = mytime.clock()
|
|
self.synced = False
|
|
var.read_val = None
|
|
var.read_ts = None
|
|
var.change_ts = None
|
|
var.SetCount = 0
|
|
try:
|
|
self.lock.release()
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
return copy.deepcopy(val)
|
|
|
|
def percent_vars_to_update(self):
|
|
keys = [_[1] for k in self.values.keys() if k[0] >= 0]
|
|
nitems = len(keys)
|
|
percent = 0.01
|
|
if nitems == 0:
|
|
return 100
|
|
else:
|
|
for key in keys:
|
|
var = self.values[key]
|
|
if var.write_val is None:
|
|
percent += 1
|
|
|
|
return percent / nitems * 99
|
|
|
|
def process_data_pkt(self, pkt):
|
|
for (opcode, fragment, MAC, correct_vars, hardware_synced) in pkt.fragments:
|
|
if one_unit.app.application_stopping == True or self.stopping == True:
|
|
break
|
|
self.parent.active_unit.correct_vars = correct_vars
|
|
self.hardware_synced = hardware_synced
|
|
if MAC != self.parent.MAC and self.parent.MAC[:4] not in ('DEMO', 'GRPdeactivated'):
|
|
return
|
|
if len(fragment) < 5:
|
|
print mytime.displayTime() + ' protocol.process.too small fragment! len=', len(fragment), ', packet discarded'
|
|
return
|
|
struct_id = struct.unpack('b', fragment[0])[0]
|
|
member_id = struct.unpack('B', fragment[1])[0]
|
|
channel = struct.unpack('B', fragment[2])[0]
|
|
index = struct.unpack('B', fragment[3])[0]
|
|
data_len = len(fragment) - 4
|
|
val = ''
|
|
try:
|
|
val = struct.unpack(get_member_format(member_id), fragment[4:])[0]
|
|
except:
|
|
continue
|
|
|
|
key = Key(struct_id, member_id, channel, index)
|
|
self.set_read_val(key, val)
|
|
|
|
self.invalid_packet_counter = 0
|
|
return
|
|
|
|
def set_read_val(self, key, val):
|
|
now = mytime.clock()
|
|
self.lock.acquire()
|
|
try:
|
|
var = self.values[key]
|
|
except KeyError:
|
|
if self.parent.model.get(key) == None and key.member_id not in (
|
|
MEMBER_ID_CURRENT_USER,
|
|
MEMBER_ID_CONFIGURATION,
|
|
MEMBER_ID_AMP_READINGS,
|
|
MEMBER_ID_HARDWARE_STATUS_FLAGS,
|
|
MEMBER_ID_ACCESS_RIGHTS,
|
|
MEMBER_ID_USER_ACCESS_RIGHTS,
|
|
MEMBER_ID_SET_PASSWORD,
|
|
MEMBER_ID_SW_VERSION,
|
|
MEMBER_ID_IP,
|
|
MEMBER_ID_SUBNET_MASK,
|
|
MEMBER_ID_STARTUP_PRESET):
|
|
self.lock.release()
|
|
return
|
|
self.values[key] = Unit_var()
|
|
var = self.values[key]
|
|
var.read_val = val
|
|
var.read_ts = now
|
|
except:
|
|
self.lock.release()
|
|
raise
|
|
|
|
if self.Connected == True and self.LinkStatus == False:
|
|
self.LinkStatus = True
|
|
self.SyncIndicateActive = True
|
|
if var.write_val is not None:
|
|
if var.write_val == val:
|
|
var.write_val = None
|
|
var.write_ts = now
|
|
var.SetCount = 0
|
|
self.lock.release()
|
|
return
|
|
else:
|
|
if var.read_val != val:
|
|
var.change_ts = now
|
|
if key.struct_id == STRUCT_ID_COMMAND:
|
|
timeout = 2
|
|
else:
|
|
timeout = 10
|
|
if now - var.write_ts > timeout:
|
|
var.read_val = val
|
|
var.read_ts = now
|
|
if key not in one_unit.app.member_scale:
|
|
one_unit.app.member_scale[key] = get_member_scale(key.member_id)
|
|
one_unit.app.member_offset[key] = 0.0
|
|
try:
|
|
val = val - one_unit.app.member_offset[key]
|
|
val = val / one_unit.app.member_scale[key]
|
|
except:
|
|
pass
|
|
else:
|
|
self.parent.model.set_from_unit(key, val)
|
|
self.lock.release()
|
|
return
|
|
|
|
def recv_direct(self, data):
|
|
self.lock.acquire()
|
|
self.received_data = data
|
|
self.lock.release()
|
|
return
|
|
|
|
def recv(self):
|
|
if self.direct_link != None:
|
|
counter = 100
|
|
while counter > 0:
|
|
self.lock.acquire()
|
|
if self.received_data != None:
|
|
pkt = self.received_data
|
|
self.received_data = None
|
|
self.lock.release()
|
|
return pkt
|
|
self.lock.release()
|
|
counter -= 1
|
|
mytime.sleep(0.05)
|
|
|
|
return
|
|
else:
|
|
try:
|
|
pkt = self.s.recv(4096)
|
|
return pkt
|
|
except socket.error, why:
|
|
if why.args[0] in (EWOULDBLOCK, 'timed out'):
|
|
return
|
|
if why.args[0] in (ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED, EPIPE, EBADF):
|
|
self.s.close()
|
|
print mytime.displayTime() + ' recv.closed socket'
|
|
self.start_server()
|
|
return
|
|
print mytime.displayTime() + ' protocol.recv error: ', why.args[0]
|
|
return
|
|
except:
|
|
self.s.close()
|
|
print mytime.displayTime() + ' Resetting server link (recv)'
|
|
self.start_server()
|
|
return
|
|
|
|
return
|
|
|
|
def send(self, data):
|
|
if self.direct_link != None:
|
|
self.direct_link.collect_incoming_data(data)
|
|
return True
|
|
else:
|
|
try:
|
|
self.s.send(data)
|
|
return True
|
|
except:
|
|
self.s.close()
|
|
print mytime.displayTime() + ' Resetting server link (send)'
|
|
self.start_server()
|
|
return False
|
|
|
|
return
|
|
|
|
def start_server(self):
|
|
if self.parent.server != None:
|
|
self.direct_link = self.parent.server.local_listener.start_direct_link(self)
|
|
one_unit.app.link_ok = True
|
|
try:
|
|
self.parent.active_unit.correct_vars = self.parent.server.peers.units[self.parent.MAC].process.conn.correct_vars
|
|
self.hardware_synced = self.parent.server.peers.units[self.parent.MAC].process.conn.synced
|
|
except:
|
|
pass
|
|
|
|
self.synced = True
|
|
return
|
|
else:
|
|
retry_conn = 0
|
|
one_unit.app.link_ok = False
|
|
while retry_conn < 100 and one_unit.app.application_stopping == False:
|
|
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
self.s.settimeout(0.1)
|
|
try:
|
|
self.s.connect(('127.0.0.1', 50684))
|
|
self.s.settimeout(0.1)
|
|
try:
|
|
self.s.send('list\n')
|
|
except:
|
|
print mytime.displayTime() + ' Could not send list request'
|
|
return
|
|
else:
|
|
retry = 10
|
|
while retry > 0 and one_unit.app.application_stopping == False:
|
|
retry -= 1
|
|
pkt = self.s.recv(4096)
|
|
if pkt == None:
|
|
try:
|
|
self.s.send('list\n')
|
|
except:
|
|
print mytime.displayTime() + ' Could not send list request'
|
|
return
|
|
else:
|
|
continue
|
|
elif len(pkt) < 10:
|
|
break
|
|
if pkt[:10] != 'unit_list:':
|
|
break
|
|
one_unit.app.link_ok = True
|
|
return
|
|
|
|
print mytime.displayTime() + ' Server Timeout!'
|
|
one_unit.app.application_stopping = True
|
|
return
|
|
except:
|
|
try:
|
|
self.s.close()
|
|
except:
|
|
pass
|
|
else:
|
|
retry_conn += 1
|
|
mytime.sleep(1)
|
|
print mytime.displayTime() + ' Connection Retry'
|
|
continue
|
|
|
|
print mytime.displayTime() + ' Server Failed!'
|
|
traceback.print_exc(file=sys.stdout)
|
|
one_unit.app.application_stopping = True
|
|
return
|
|
|
|
return
|
|
|
|
|
|
def build_command(MAC, vars, factory):
|
|
cmd = 'DDL' + chr(len(MAC)) + MAC
|
|
opcode = 187
|
|
if factory == True:
|
|
opcode = 234
|
|
for (k, v) in vars.items():
|
|
(struct_id, member_id, channel, index) = k
|
|
new_val = struct.pack(get_member_format(member_id), v)
|
|
cmd += ('').join([_[1] for i in (opcode, 6 + len(new_val),
|
|
struct_id, member_id, channel, index)]) + new_val
|
|
|
|
return cmd
|
|
|
|
|
|
class Data_packet():
|
|
"""The announcement broadcast by hardware units over USB"""
|
|
|
|
def __init__(self):
|
|
"""Constructor"""
|
|
self.fragments = []
|
|
self.PC_PacketId = None
|
|
self.HW_PacketId = None
|
|
self.invalid_packet_counter = 0
|
|
return
|
|
|
|
def __str__(self):
|
|
return 'Data_packet(opcode=%s, id=%s)' % (self.opcode,
|
|
self.HW_PacketId)
|
|
|
|
|
|
def parse_data_pkt(data):
|
|
res = Data_packet()
|
|
if len(data) < 5:
|
|
res.fragments = []
|
|
res.invalid_packet_counter = res.invalid_packet_counter + 1
|
|
return res
|
|
DDR = data[:3]
|
|
if DDR != 'DDR':
|
|
res.fragments = []
|
|
res.invalid_packet_counter = res.invalid_packet_counter + 1
|
|
return res
|
|
pos = ord(data[3]) + 4
|
|
if len(data) < pos - 1:
|
|
res.fragments = []
|
|
res.invalid_packet_counter = res.invalid_packet_counter + 1
|
|
return res
|
|
MAC = data[4:pos]
|
|
correct_vars = struct.unpack('I', data[pos:pos + 4])[0]
|
|
pos += 4
|
|
hardware_synced = ord(data[pos])
|
|
if hardware_synced == 0:
|
|
hardware_synced = False
|
|
else:
|
|
hardware_synced = True
|
|
pos += 1
|
|
no_of_fragments = 0
|
|
if len(data) <= pos:
|
|
return res
|
|
while pos + 6 < len(data):
|
|
opcode = ord(data[pos])
|
|
if opcode != 123:
|
|
res.fragments = []
|
|
res.invalid_packet_counter = res.invalid_packet_counter + 1
|
|
return res
|
|
pos += 1
|
|
size = ord(data[pos])
|
|
pos += 1
|
|
size -= 2
|
|
if size < 2:
|
|
print mytime.displayTime() + ' protocol.too small fragment! opcode: ', opcode, ' size:', size + 2, ', packet discarded'
|
|
res.fragments = []
|
|
res.invalid_packet_counter = res.invalid_packet_counter + 1
|
|
return res
|
|
if pos + size > len(data):
|
|
res.invalid_packet_counter = res.invalid_packet_counter + 1
|
|
res.fragments = []
|
|
return res
|
|
res.fragments.append((opcode, data[pos:pos + size], MAC, correct_vars, hardware_synced))
|
|
pos += size
|
|
no_of_fragments += 1
|
|
|
|
return res
|
|
|
|
|
|
|
|
# okay decompiling pycode/protocol.pyc
|