mirror of
https://github.com/LukeSpad/BeoGateway.git
synced 2024-12-23 21:51:51 +00:00
Add files via upload
This commit is contained in:
parent
41430a76c3
commit
566ebbeeda
7 changed files with 110 additions and 65 deletions
|
@ -1,5 +1,8 @@
|
|||
#!/usr/bin/python
|
||||
import indigo
|
||||
try:
|
||||
import indigo
|
||||
except ImportError:
|
||||
pass
|
||||
import logging
|
||||
import os
|
||||
import unicodedata
|
||||
|
@ -30,7 +33,6 @@ class MusicController(object):
|
|||
def __init__(self):
|
||||
self.app = SBApplication.applicationWithBundleIdentifier_("com.apple.Music")
|
||||
|
||||
|
||||
# ########################################################################################
|
||||
# Player information
|
||||
def get_current_track_info(self):
|
||||
|
@ -134,9 +136,11 @@ class MusicController(object):
|
|||
self.app.currentTrack().setValue_forKey_('true', 'loved')
|
||||
self.app.currentTrack().setValue_forKey_('true', 'enabled')
|
||||
elif int(rate) == 0:
|
||||
# If rated 0% then set to disliked and disable the track so it will not be played in shuffle
|
||||
# If rated 0% then set to disliked and disable the track, so it will not be played in shuffle
|
||||
self.app.currentTrack().setValue_forKey_('true', 'disliked')
|
||||
self.app.currentTrack().setValue_forKey_('false', 'enabled')
|
||||
# It's obviously a stinker, so let's skip to the next track
|
||||
self.app.nextTrack()
|
||||
else:
|
||||
# else remove disliked/loved flags and check the track is enabled for playback
|
||||
self.app.currentTrack().setValue_forKey_('false', 'disliked')
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import indigo
|
||||
try:
|
||||
import indigo
|
||||
except ImportError:
|
||||
pass
|
||||
import asynchat
|
||||
import socket
|
||||
import time
|
||||
|
@ -48,10 +51,11 @@ class BLHIPClient(asynchat.async_chat):
|
|||
# ##### Client functions
|
||||
def collect_incoming_data(self, data):
|
||||
self.is_connected = True
|
||||
self._received_data += data
|
||||
self._received_data += str(data)
|
||||
|
||||
def found_terminator(self):
|
||||
# indigo.server.log("Raw Data: " + self._received_data)
|
||||
if self.debug:
|
||||
indigo.server.log("Raw Data: " + self._received_data)
|
||||
self.last_received = self._received_data
|
||||
self.last_received_at = time.time()
|
||||
|
||||
|
@ -62,7 +66,7 @@ class BLHIPClient(asynchat.async_chat):
|
|||
indigo.server.log('\tAuthentication Successful!', level=logging.DEBUG)
|
||||
self.query(dev_type="AV renderer")
|
||||
|
||||
self._received_data = urllib.unquote(self._received_data)
|
||||
self._received_data = urllib.parse.unquote(self._received_data)
|
||||
telegram = self._received_data.replace("%201", "")
|
||||
telegram = telegram.split('/')
|
||||
header = telegram[0:4]
|
||||
|
@ -73,24 +77,20 @@ class BLHIPClient(asynchat.async_chat):
|
|||
e_string = str(header[0])
|
||||
if e_string[0] == 'e':
|
||||
if e_string[2:4] == 'OK' and self.debug:
|
||||
indigo.server.log('Command Successfully Processed: ' + str(urllib.unquote(self._received_data)),
|
||||
level=logging.DEBUG)
|
||||
indigo.server.log('Command Successfully Processed: ' + str(self._received_data), level=logging.DEBUG)
|
||||
|
||||
elif e_string[2:5] == 'CMD':
|
||||
indigo.server.log('Wrong or Unrecognised Command: ' + str(urllib.unquote(self._received_data)),
|
||||
level=logging.WARNING)
|
||||
indigo.server.log('Wrong or Unrecognised Command: ' + str(self._received_data), level=logging.WARNING)
|
||||
|
||||
elif e_string[2:5] == 'SYN':
|
||||
indigo.server.log('Bad Syntax, or Wrong Character Encoding: ' +
|
||||
str(urllib.unquote(self._received_data)), level=logging.WARNING)
|
||||
indigo.server.log('Bad Syntax, or Wrong Character Encoding: ' + str(self._received_data),
|
||||
level=logging.WARNING)
|
||||
|
||||
elif e_string[2:5] == 'ACC':
|
||||
indigo.server.log('Zone Access Violation: ' + str(urllib.unquote(self._received_data)),
|
||||
level=logging.WARNING)
|
||||
indigo.server.log('Zone Access Violation: ' + str(self._received_data), level=logging.WARNING)
|
||||
|
||||
elif e_string[2:5] == 'LEN':
|
||||
indigo.server.log('Received Message Too Long: ' + str(urllib.unquote(self._received_data)),
|
||||
level=logging.WARNING)
|
||||
indigo.server.log('Received Message Too Long: ' + str(self._received_data), level=logging.WARNING)
|
||||
|
||||
self._received_data = ""
|
||||
return
|
||||
|
@ -190,9 +190,16 @@ class BLHIPClient(asynchat.async_chat):
|
|||
self.is_connected = False
|
||||
self.close()
|
||||
|
||||
def send_cmd(self, telegram):
|
||||
def send_cmd(self, payload):
|
||||
payload = payload + "\r\n"
|
||||
payload = payload.encode('UTF8')
|
||||
telegram = bytearray()
|
||||
# append payload
|
||||
for p in payload:
|
||||
telegram.append(p)
|
||||
|
||||
try:
|
||||
self.push(str(telegram + "\r\n"))
|
||||
self.push(telegram)
|
||||
except socket.timeout as e:
|
||||
indigo.server.log("\tSocket connection timed out: " + str(e), level=logging.ERROR)
|
||||
self.handle_close()
|
||||
|
@ -204,9 +211,9 @@ class BLHIPClient(asynchat.async_chat):
|
|||
self.last_sent_at = time.time()
|
||||
if telegram == 'q Main/global/SYSTEM/BeoLink':
|
||||
if self.debug:
|
||||
indigo.server.log(self.name + " >>-SENT--> : " + telegram, level=logging.DEBUG)
|
||||
indigo.server.log(self.name + " >>-SENT--> : " + payload.decode('UTF8'), level=logging.DEBUG)
|
||||
else:
|
||||
indigo.server.log(self.name + " >>-SENT--> : " + telegram, level=logging.INFO)
|
||||
indigo.server.log(self.name + " >>-SENT--> : " + payload.decode('UTF8'), level=logging.INFO)
|
||||
time.sleep(0.2)
|
||||
|
||||
def query(self, zone='*', room='*', dev_type='*', device='*'):
|
||||
|
|
|
@ -485,7 +485,7 @@ ml_command_type_dict = dict(
|
|||
#########################################################
|
||||
# On power up all devices send out a request key telegram. If
|
||||
# no lock manager is allocated the devices send out a key_lost telegram. The Video Master (or Power
|
||||
# Master in older implementations) then asserts a NEW_LOCKmANAGER telegram and assumes responsibility
|
||||
# Master in older implementations) then asserts a NEW_LOCKMANAGER telegram and assumes responsibility
|
||||
# for LOCKMANAGER_COMMAND telegrams until a key transfer occurs.
|
||||
# reference: https://tidsskrift.dk/daimipb/article/download/7043/6004/0
|
||||
(0x12, "KEY_LOST"), # ?
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import indigo
|
||||
try:
|
||||
import indigo
|
||||
except ImportError:
|
||||
pass
|
||||
import asynchat
|
||||
import socket
|
||||
import time
|
||||
|
@ -26,7 +29,7 @@ class MLCLIClient(asynchat.async_chat):
|
|||
|
||||
self._i = 0
|
||||
self._header_lines = 6
|
||||
self._received_data = ""
|
||||
self._received_data = ''
|
||||
self.last_sent = ''
|
||||
self.last_sent_at = time.time()
|
||||
self.last_received = ''
|
||||
|
@ -48,7 +51,7 @@ class MLCLIClient(asynchat.async_chat):
|
|||
# ########################################################################################
|
||||
# ##### Client functions
|
||||
def collect_incoming_data(self, data):
|
||||
self._received_data += data
|
||||
self._received_data += str(data)
|
||||
|
||||
def found_terminator(self):
|
||||
self.last_received = self._received_data
|
||||
|
@ -61,8 +64,10 @@ class MLCLIClient(asynchat.async_chat):
|
|||
if self._i <= self._header_lines:
|
||||
self._i += 1
|
||||
if self._i == self._header_lines - 1:
|
||||
indigo.server.log("\tAuthenticated! Gateway type is " + telegram[0:4] + "\n", level=logging.DEBUG)
|
||||
if telegram[0:4] != "MLGW":
|
||||
if "MLGW" in telegram:
|
||||
indigo.server.log("\tAuthenticated! Gateway type is MLGW\n", level=logging.DEBUG)
|
||||
else:
|
||||
indigo.server.log("\tAuthenticated! Gateway type is BLGW\n", level=logging.DEBUG)
|
||||
self.isBLGW = True
|
||||
|
||||
# Process telegrams and return json data in human readable format
|
||||
|
@ -79,10 +84,15 @@ class MLCLIClient(asynchat.async_chat):
|
|||
# ML protocol message detected
|
||||
items = telegram.split()[1:]
|
||||
if len(items):
|
||||
telegram = bytearray()
|
||||
telegram = []
|
||||
for item in items:
|
||||
if len(item) == 3:
|
||||
item = '0x' + item[:-1]
|
||||
elif len(item) == 4:
|
||||
item = '0x' + item[:-2]
|
||||
|
||||
try:
|
||||
telegram.append(int(item[:-1], base=16))
|
||||
telegram.append(int(item, base=16))
|
||||
except (ValueError, TypeError):
|
||||
# abort if invalid character found
|
||||
if self.debug:
|
||||
|
@ -90,9 +100,8 @@ class MLCLIClient(asynchat.async_chat):
|
|||
''.join(items) + '\nAborting!', level=logging.ERROR)
|
||||
break
|
||||
|
||||
# Decode any telegram with a valid 9 byte header, excluding typy 0x14 (regular clock sync pings)
|
||||
if len(telegram) >= 9:
|
||||
# Header: To_Device/From_Device/1/Type/To_Source/From_Source/0/Payload_Type/Length
|
||||
# Decode any telegram with a valid 9 byte header, excluding type 0x14 (regular clock sync pings)
|
||||
if len(telegram) > 9:
|
||||
header = telegram[:9]
|
||||
payload = telegram[9:]
|
||||
message = self._decode(telegram)
|
||||
|
@ -133,9 +142,16 @@ class MLCLIClient(asynchat.async_chat):
|
|||
self.is_connected = False
|
||||
self.close()
|
||||
|
||||
def send_cmd(self, telegram):
|
||||
def send_cmd(self, payload):
|
||||
payload = payload + "\r\n"
|
||||
payload = payload.encode('UTF8')
|
||||
telegram = bytearray()
|
||||
# append payload
|
||||
for p in payload:
|
||||
telegram.append(p)
|
||||
|
||||
try:
|
||||
self.push(str(telegram + "\r\n"))
|
||||
self.push(telegram)
|
||||
except socket.timeout as e:
|
||||
indigo.server.log("\tSocket connection timed out: " + str(e), level=logging.ERROR)
|
||||
self.handle_close()
|
||||
|
@ -145,7 +161,7 @@ class MLCLIClient(asynchat.async_chat):
|
|||
else:
|
||||
self.last_sent = telegram
|
||||
self.last_sent_at = time.time()
|
||||
indigo.server.log(self.name + " >>-SENT--> : " + telegram, level=logging.INFO)
|
||||
indigo.server.log(self.name + " >>-SENT--> : " + payload.decode('UTF8'), level=logging.INFO)
|
||||
time.sleep(0.2)
|
||||
|
||||
def _report(self, header, payload, message):
|
||||
|
@ -156,7 +172,7 @@ class MLCLIClient(asynchat.async_chat):
|
|||
def ping(self):
|
||||
if self.debug:
|
||||
indigo.server.log(self.name + " >>-SENT--> : Ping", level=logging.DEBUG)
|
||||
self.push('\n')
|
||||
self.push(b'\n')
|
||||
|
||||
# ########################################################################################
|
||||
# ##### Utility functions
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import indigo
|
||||
try:
|
||||
import indigo
|
||||
except ImportError:
|
||||
pass
|
||||
import asyncore
|
||||
import json
|
||||
import requests
|
||||
|
@ -22,6 +25,8 @@ class MLConfig:
|
|||
|
||||
def _download_data(self):
|
||||
try:
|
||||
indigo.debugger()
|
||||
|
||||
indigo.server.log('Downloading configuration data from Gateway...', level=logging.WARNING)
|
||||
url = 'http://' + str(self._host) + '/mlgwpservices.json'
|
||||
# try Basic Auth next (this is needed for the BLGW)
|
||||
|
@ -239,7 +244,7 @@ class MLConfig:
|
|||
CONST.rooms.append(room)
|
||||
|
||||
# Report details of the configuration
|
||||
n_devices = indigo.devices.len(filter="uk.co.lukes_plugins.BeoGateway.plugin.AVrenderer") - 1
|
||||
n_devices = indigo.devices.len(filter="uk.co.lukes_plugins.BeoGateway.plugin.AVrenderer")
|
||||
indigo.server.log('Found ' + str(n_devices) + ' AV Renderers!', level=logging.DEBUG)
|
||||
for node in indigo.devices.iter('uk.co.lukes_plugins.BeoGateway.plugin.AVrenderer'):
|
||||
indigo.server.log('\tMLN ' + str(node.address) + ': ' + str(node.name), level=logging.INFO)
|
||||
|
@ -282,7 +287,6 @@ class MLConfig:
|
|||
test = False
|
||||
except KeyError:
|
||||
asyncore.loop(count=1, timeout=0.2)
|
||||
|
||||
else:
|
||||
# If this is a NetLink product then it has a serial number and no ML_ID
|
||||
indigo.server.log("\tNetworkLink ID of product " + node.name + " is " +
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import indigo
|
||||
try:
|
||||
import indigo
|
||||
except ImportError:
|
||||
pass
|
||||
import asynchat
|
||||
import socket
|
||||
import time
|
||||
|
@ -20,15 +23,15 @@ class MLGWClient(asynchat.async_chat):
|
|||
|
||||
self._host = host_address
|
||||
self._port = int(port)
|
||||
self._user = user
|
||||
self._pwd = pwd
|
||||
self._user = user.encode('UTF8')
|
||||
self._pwd = pwd.encode('UTF8')
|
||||
self.name = name
|
||||
self.is_connected = False
|
||||
|
||||
self._received_data = bytearray()
|
||||
self.last_sent = ''
|
||||
self.last_sent = bytearray()
|
||||
self.last_sent_at = time.time()
|
||||
self.last_received = ''
|
||||
self.last_received = bytearray()
|
||||
self.last_received_at = time.time()
|
||||
self.last_message = {}
|
||||
|
||||
|
@ -72,11 +75,11 @@ class MLGWClient(asynchat.async_chat):
|
|||
self._received_data = ""
|
||||
|
||||
def found_terminator(self, msg_type, payload):
|
||||
self.last_received = str(list(self._received_data))
|
||||
self.last_received = self._received_data
|
||||
self.last_received_at = time.time()
|
||||
|
||||
header = self._received_data[0:4]
|
||||
self._received_data = ""
|
||||
self._received_data = bytearray()
|
||||
self._decode(msg_type, header, payload)
|
||||
|
||||
def _decode(self, msg_type, header, payload):
|
||||
|
@ -184,6 +187,8 @@ class MLGWClient(asynchat.async_chat):
|
|||
self._report(header, payload, message)
|
||||
|
||||
def client_connect(self):
|
||||
indigo.debugger()
|
||||
|
||||
indigo.server.log('Connecting to host at ' + self._host + ', port ' + str(self._port), level=logging.WARNING)
|
||||
self.set_terminator(b'\r\n')
|
||||
# Create the socket
|
||||
|
@ -209,7 +214,7 @@ class MLGWClient(asynchat.async_chat):
|
|||
indigo.server.log("\tConnected to B&O Gateway", level=logging.DEBUG)
|
||||
|
||||
def handle_connect(self):
|
||||
login = []
|
||||
login = bytearray()
|
||||
for c in self._user:
|
||||
login.append(c)
|
||||
login.append(0x00)
|
||||
|
@ -217,6 +222,7 @@ class MLGWClient(asynchat.async_chat):
|
|||
login.append(c)
|
||||
|
||||
indigo.server.log("\tAttempting to Authenticate...", level=logging.WARNING)
|
||||
indigo.server.log("\tLogin: " + str(login), level=logging.DEBUG)
|
||||
self._send_cmd(CONST.MLGW_PL.get("LOGIN REQUEST"), login)
|
||||
|
||||
def handle_close(self):
|
||||
|
@ -235,21 +241,19 @@ class MLGWClient(asynchat.async_chat):
|
|||
# send_cmd command to mlgw
|
||||
def _send_cmd(self, msg_type, payload):
|
||||
# Construct header
|
||||
telegram = [1, msg_type, len(payload), 0]
|
||||
telegram = bytearray()
|
||||
telegram.append(1)
|
||||
telegram.append(msg_type)
|
||||
telegram.append(len(payload))
|
||||
telegram.append(0)
|
||||
indigo.debugger()
|
||||
|
||||
# append payload
|
||||
for p in payload:
|
||||
telegram.append(p)
|
||||
|
||||
# Convert telegram to byte string
|
||||
# b_telegram = b''
|
||||
# for t in telegram:
|
||||
# if type(t) == int:
|
||||
# b_telegram += (t).to_bytes(1, byteorder='little')
|
||||
# else:
|
||||
# b_telegram += bytes(t, 'ascii')
|
||||
|
||||
try:
|
||||
self.push(str(bytearray(telegram)))
|
||||
self.push(telegram)
|
||||
except socket.timeout as e:
|
||||
indigo.server.log("\tSocket connection to timed out: " + str(e), level=logging.ERROR)
|
||||
self.handle_close()
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import indigo
|
||||
try:
|
||||
import indigo
|
||||
except ImportError:
|
||||
pass
|
||||
import asynchat
|
||||
import socket
|
||||
import time
|
||||
|
@ -47,7 +50,7 @@ class MLtnClient(asynchat.async_chat):
|
|||
# ########################################################################################
|
||||
# ##### Client functions
|
||||
def collect_incoming_data(self, data):
|
||||
self._received_data += data
|
||||
self._received_data += str(data)
|
||||
|
||||
def found_terminator(self):
|
||||
self.last_received = self._received_data
|
||||
|
@ -300,17 +303,24 @@ class MLtnClient(asynchat.async_chat):
|
|||
|
||||
def handle_connect(self):
|
||||
indigo.server.log("\tAttempting to Authenticate...", level=logging.WARNING)
|
||||
self._send_cmd(self._pwd)
|
||||
self._send_cmd("MONITOR")
|
||||
self.send_cmd(self._pwd)
|
||||
self.send_cmd("MONITOR")
|
||||
|
||||
def handle_close(self):
|
||||
indigo.server.log(self.name + ": Closing socket", level=logging.ERROR)
|
||||
self.is_connected = False
|
||||
self.close()
|
||||
|
||||
def _send_cmd(self, telegram):
|
||||
def send_cmd(self, payload):
|
||||
payload = payload + "\r\n"
|
||||
payload = payload.encode('UTF8')
|
||||
telegram = bytearray()
|
||||
# append payload
|
||||
for p in payload:
|
||||
telegram.append(p)
|
||||
|
||||
try:
|
||||
self.push(str(telegram + "\r\n"))
|
||||
self.push(telegram)
|
||||
except socket.timeout as e:
|
||||
indigo.server.log("\tSocket connection timed out: " + str(e), level=logging.ERROR)
|
||||
self.handle_close()
|
||||
|
@ -320,7 +330,7 @@ class MLtnClient(asynchat.async_chat):
|
|||
else:
|
||||
self.last_sent = telegram
|
||||
self.last_sent_at = time.time()
|
||||
indigo.server.log(self.name + " >>-SENT--> : " + telegram, level=logging.INFO)
|
||||
indigo.server.log(self.name + " >>-SENT--> : " + payload.decode('UTF8'), level=logging.INFO)
|
||||
time.sleep(0.2)
|
||||
|
||||
def toggle_events(self):
|
||||
|
@ -345,7 +355,7 @@ class MLtnClient(asynchat.async_chat):
|
|||
self.handle_close()
|
||||
|
||||
def ping(self):
|
||||
self._send_cmd('')
|
||||
self.send_cmd('')
|
||||
|
||||
# ########################################################################################
|
||||
# ##### Utility functions
|
||||
|
|
Loading…
Reference in a new issue