Hi. I have tried to compile the kpc2 on a debian jessie os. Unfortunately the used KDE Libs (4/5) seems not to be compatible anymore.
Anybody successfully compiled it?
Hi. I have tried to compile the kpc2 on a debian jessie os. Unfortunately the used KDE Libs (4/5) seems not to be compatible anymore.
Anybody successfully compiled it?
Looks like this thread is long dead.
Anyone succeeded with this interface?
Hi Phill
could you be so kind and share what you find out. Messages between usp and Beoport.
Thanks Wolfgang
Location: Villach, Austria
I would like to realize this circuit with the ML I/O .
Has anyone already experience?
Hi there,
so, this is an old thread, but maybe the following will be useful to folks. You can use a MasterLink Gateway to monitor the full ML bus using an undocumented command _MLLOG from the CLI. Here is a python script that will dump the traffic on the bus, and it implements the best I know about the various fields in the protocol.
import getpass
import telnetlib
import datetime
def _hexbyte(byte):
resultstr = hex(byte)
if byte < 16:
resultstr = resultstr[:2] + "0" + resultstr[2]
return resultstr
def _hexword(byte1, byte2):
resultstr = _hexbyte(byte2)
resultstr = _hexbyte(byte1) + resultstr[2:]
return resultstr
ml_command_type_dict = dict([
(0x45, "GOTO_SOURCE"),
(0x6c, "DISTRIBUTION_REQUEST"),
(0x96, "PC_PRESENT"),
(0x10, "STANDBY"),
(0x11, "RELEASE"),
(0x3c, "TIMER"),
(0x0d, "BEO4_KEY"),
(0x04, "MASTER_PRESENT"),
(0x5c, "REQUEST_KEY"),
(0x30, "WHAT_AUDIO_SOURCE"),
(0x40, "CLOCK"),
(0x44, "TRACK_INFO"),
(0x82, "TRACK_INFO_LONG"),
(0x87, "STATUS_INFO"),
(0x94, "DVD_STATUS_INFO"),
(0x20, "MLGW REMOTE BEO4")
])
ml_state_dict = dict ([
(0x00,"UNKNOWN"),
(0x01,"STOP"),
(0x02,"PLAYING"),
(0x03,"FASTFORWARD"),
(0x04,"REWIND"),
(0x05,"RECORD_LOCK"),
(0x06,"STANDBY"),
(0x07,"LOAD"),
(0x08,"STIL_PICTURE"),
(0x14,"SCAN_FORWARD"),
(0x15,"SCAN_REVERSE"),
(0xff,"BLANK_STATUS")
])
pictureformatdict = dict( [
(0x00, "Not known"), (0x01, "Known by decoder"), (0x02, "4:3"), (0x03, "16:9"),
(0x04, "4:3 Letterbox middle"), (0x05, "4:3 Letterbox top"),
(0x06, "4:3 Letterbox bottom"), (0xff, "Blank picture")
] )
beo4_destselectordict = dict([
(0x00, "Video Source"), (0x01, "Audio Source"), (0x05, "V.TAPE/V.MEM"), (0x0f, "All Products"), (0x1b, "MLGW")
])
selectedsourcedict = dict( [
(0x00, "CAMERA"),
(0x0b, "TV"), (0x15, "V.Mem"), (0x16, "DVD_2"), (0x1f, "DTV"),
(0x29, "DVD"), (0x33, "V_AUX"), (0x3e, "V_AUX2"),
(0x47, "PC"), (0x6f, "Radio"), (0x79, "A.Mem"), (0x7a, "NMUSIC"), (0x8d, "CD"),
(0x97, "A_AUX"), (0xa1, "NRADIO"),
# Dummy for 'Listen for all sources'
(0xfe, "")
] )
def _dictsanitize( d , s ):
result = d.get( s )
if result == None:
result = "UNKNOWN (type=" + _hexbyte( s ) + ")"
return str(result)
beo4commanddict = dict([
# Source selection:
(0x0c, "Standby"), (0x47, "Sleep"), (0x80, "TV"), (0x81, "Radio"), (0x82, "DTV2"),
(0x83, "Aux_A"), (0x85, "V.Mem"), (0x86, "DVD"), (0x87, "Camera"), (0x88, "Text"),
(0x8a, "DTV"), (0x8b, "PC"), (0x0d, "Doorcam"), (0x91, "A.Mem"), (0x92, "CD"),
(0x93, "N.Radio"), (0x94, "N.Music"), (0x97, "CD2"), (0x96, "Spotify"),
(0xbf, "AV"),
# Digits:
(0x00, "Digit-0"), (0x01, "Digit-1"), (0x02, "Digit-2"), (0x03, "Digit-3"),
(0x04, "Digit-4"), (0x05, "Digit-5"), (0x06, "Digit-6"), (0x07, "Digit-7"),
(0x08, "Digit-8"), (0x09, "Digit-9"),
# Source control:
(0x1e, "STEP_UP"), (0x1f, "STEP_DW"), (0x32, "REWIND"), (0x33, "RETURN"),
(0x34, "WIND"), (0x35, "Go / Play"), (0x36, "Stop"), (0xd4, "Yellow"),
(0xd5, "Green"), (0xd8, "Blue"), (0xd9, "Red"),
# Sound and picture control
(0x0d, "Mute"), (0x1c, "P.Mute"), (0x2a, "Format"), (0x44, "Sound / Speaker"),
(0x5c, "Menu"), (0x60, "Volume UP"), (0x64, "Volume DOWN"), (0xda, "Cinema_On"),
(0xdb, "Cinema_Off"),
# Other controls:
(0x14, "BACK"), (0x7f, "Exit"),
# Continue functionality:
(0x70, "Rewind Repeat"),
(0x71, "Wind Repeat"),
(0x72, "Step_UP Repeat"),
(0x73, "Step_DW Repeat"),
(0x75, "Go Repeat"),
(0x76, "Green Repeat"),
(0x77, "Yellow Repeat"),
(0x78, "Blue Repeat"),
(0x79, "Red Repeat"),
(0x7e, "Key Release"),
# Functions:
(0x40, "Guide"), (0x43, "Info"),
# Cursor functions:
(0x13, "SELECT"), (0xca, "Cursor_Up"), (0xcb, "Cursor_Down"), (0xcc, "Cursor_Left"),
(0xcd, "Cursor_Right"),
#
(0x9b, "Light"), (0x9c, "Command"),
# Light Timeout
(0x58, "Light Timeout"),
# Dummy for 'Listen for all commands'
(0xff, "")
])
def decode_ml(telegram):
decoded = decode_device(telegram[1]) + " => " + decode_device(telegram[0]) + " TYPE: " + str(telegram[3]) + " SRC_DEST:" + _hexbyte(telegram[4]) + " ORIG_SRC:" + _hexbyte(telegram[5]) + " PL_Type: " + _dictsanitize(ml_command_type_dict,telegram[7]) + " Len: " + str(telegram😡)
# status info
if (telegram[7]==0x87): decoded = decoded + " Source: " + _dictsanitize(selectedsourcedict,telegram[10]) + " Ch/Track: " + str(telegram[19]) + " Activity: " + _dictsanitize(ml_state_dict, telegram[21]) + " Source Medium: " + str(_hexword(telegram[18],telegram[17])) + " Picture Identifier: " + _dictsanitize(pictureformatdict, telegram[23])
# beo4 command
if (telegram[7]==0x0d): decoded = decoded + " Source: " + _dictsanitize(selectedsourcedict,telegram[10]) + " Command: " + _dictsanitize(beo4commanddict,telegram[11])
# track info long
if (telegram[7]==0x82): decoded = decoded + " Source: " + _dictsanitize(selectedsourcedict,telegram[11]) + " Ch/Track: " + str(telegram[12]) + " Activity: " + _dictsanitize(ml_state_dict, telegram[13])
# track info
if (telegram[7]==0x44):
if (telegram[9]==0x07): decoded = decoded + " Switch Source. Old: " + _dictsanitize(selectedsourcedict,telegram[11]) + " New: " + _dictsanitize(selectedsourcedict,telegram[22])
elif (telegram[9]==0x05): decoded = decoded + " Current Source: " + _dictsanitize(selectedsourcedict,telegram[11])
else: decoded = decoded + " Undefined"
# goto source
if (telegram[7]==0x45): decoded = decoded + " Source: " + _dictsanitize(selectedsourcedict,telegram[11]) + " Ch/Track: " + str(telegram[12])
# remote request
if (telegram[7]==0x20): decoded = decoded + " Command: " + _dictsanitize(beo4commanddict,telegram[14]) + " Dest Selector: " + _dictsanitize(beo4_destselectordict, telegram[11])
# request_key
if (telegram[7]==0x5c):
if (telegram[9]==0x01): decoded = decoded + " Request Key"
elif (telegram[9]==0x02): decoded = decoded + " Transfter Key"
elif (telegram[9]==0x04): decoded = decoded + " Key Transfer Complete"
else: decoded = decoded + " Undefined"
# what audio source
if (telegram[7]==0x30):
if (telegram😡==0x0): decoded = decoded + " Request Audio Source"
elif (telegram😡==0x02): decoded = decoded + " Audio Source: " + _dictsanitize(selectedsourcedict,telegram[11])
else: decoded = decoded + " Undefined"
return decoded
def decode_device(d):
if (d==0xc0): return "VIDEO_MASTER"
if (d==0xc1): return "AUDIO_MASTER"
if (d==0xc2): return "SLAVE_DEVICE"
if (d==0x83): return "ALL_LINK_DEVICES"
if (d==0x80): return "ALL"
if (d==0xf0): return "MLGW"
else: return "MLN: " + hex(d)
HOST = "192.168.1.10"
# password = getpass.getpass()
password = "XXXX"
tn = telnetlib.Telnet(HOST)
tn.read_until(b"login: ")
tn.write(password.encode('ascii') + b"\n")
print(tn.read_until(b"MLGW >"))
tn.write(b"_MLLOG ONLINE\r\n")
try:
while True:
line = tn.read_until(b"\n").decode('ascii')
print("------------------")
print(line.strip("\n"))
items = line.split()
try:
date_time_obj = datetime.datetime.strptime(items[0], '%Y%m%d-%H:%M:%S:%f:')
telegram = bytearray()
checksum = 0
for x in range(1, len(items)):
telegram.append(items[x][:-1].decode('hex'))
checksum = checksum + telegram[len(telegram)-1]
# print ("len:"+ str(len(telegram)) + " checksum:" + str(checksum & 0xff ) + " timestamp:" + str(date_time_obj))
# print (''.join('{:02x}'.format(x) for x in telegram))
print (decode_ml(telegram))
except ValueError:
continue
except EOFError as error:
quit()
My B&O Icons:
hallo zusammen. Ich wäre auch mega an dieser Lösung interessiert.
Könnte man zB auch einfach den I2C einer Ouverture mithören und dann reagieren?
Würde gerne den Tuner Teil trennen und was eigenes einspeisen
Könnte man zB auch einfach den I2C einer Ouverture mithören und dann reagieren?
Würde gerne den Tuner Teil trennen und was eigenes einspeisen
I haven't tried this, but yes, it should be possible to emulate the tuner module with a bit of reverse engineering of the communication between the tuner + RDS modules and the main board.
The ouverture is pretty tolerant to working with many / most of its modules missing - I know this because I am using just the transformer, main board, uP, and masterlink modules inside a plastic project box, to connect a datalink capable beogram to an NL/ML converter, so that I can join it from a NL television and control it with the beoremote 1. Obviously this can be done with an intact ouverture, but I wanted something smaller that I could hide away along with the NL/ML converter, and I already had a spare ouverture that was in very bad cosmetic condition, with no doors and no CD mech that I could harvest these parts from.
Martin.
Location: Exeter, UK
ich Grunde genommen war die Idee folgendermaßen: Die NF-Zuleitung vom Tuner zum Mainboard trennen, Raspi anschliessen.
Dann den I2C abhören und bei einem bestimmten Signal auf dem I2C Zum Beispiel den Sender zu wechseln.
Kann man den I2C mit dem Raspi einfach Sniffen? Ich möchte die Kommunikation zum Tuner mithören und dann als Trigger für eine Reaktion auf dem Raspi nutzen.
Looking at the schematics within the ouverture service manual, it seems to i2c is not used by the tuner board (it simply loops through the tuner PCB and onwards to the RDS decoder PCB).
Instead, the lines you would be interested in would be those labelled PLL CE (chip enable), CLOCK, DATA, and DATA2 on the tuner schematics.
Given the tuner uses a Sanyo LC7218 frequency synthesizer, these lines will be using Sanyo CCB serial communication protocol. There are some useful links here about Sanyo CCB: https://forum.arduino.cc/t/ccb-data-reading/418509
It's likely all of the inter-IC communication in the ouverture will be at 5V logic levels, so you should not connect the raspberry PI GPIO lines directly as you will likely destroy your RPi. You will need to use some level converters.
Ideally you'd want to connect an oscilloscope to the CLOCK line, at least to see what kind of data rates you are working with.
I would probably be inclined to use an arduino or esp32 (again with the appropriate logic level converters) to handle the low level stuff and then communicate the results with the RPi.
Martin.
Location: Exeter, UK
ich versuchs mal. Vielen Dank für Deine Hilfe!!!
You must be logged in as a BeoWorld member to post replies to forum threads.
Register to access the forums, reference material, and exclusive member benefits — including our monthly prize draw.
Become a Member