ARCHIVED FORUM -- March 2012 to February 2022READ ONLY FORUM
This is the second Archived Forum which was active between 1st March 2012 and 23rd February 2022
Hi there.
I have a Raspberry PI connected to a MLGW via the MLGW protocol (login on Ethernet from the RPi to the MLGW). Sending commands from the RPi to MLGW works fine, as well as the RPi receives "configuration change" messages, so the actual connection and protocol seems to be working.
However, it seems like the MLGW does not forward the Light commands from my NL units to the protocol connection.
I see the light command from my Network Link unit show up in the MLGW "Monitor" log (so the MLGW receives the light command), but the RPi never receives the command on the protocol connection.
How do I make the MLGW forward the light commands to the RPi?
I tried with macros, but there seems to be no way for a macro to send messages through the MLGW protocol connection.
Thanks!
Giovanni
I’m getting Light packages into a raspberry (I’m connecting via port 9000) from a Beosystem 4, so something else must be happening here - if it is hitting the monitor, then the NL device is set up to forward MLGW messages correctly.
What is the NL device you are using?
what is the code you are using to connect?
Interesting.
The device is a Beovision 55. They show up in the monitor, but not forwarded to the RPI over the 9000 port. Same thing for my Masterlink devices. Light commands show up in MLGW monitor but not forwarded.
I'm using a Hass.io python script to connect.
firmware of MLGW is 2.24. Wondering if there is some secret setting.
I worked around it by creating macros on the MLGW, activated by the light commands, but that push REST commands to the RPi to activate scenes. Works fine but it's not what I wanted!
this is the code: https://github.com/simonkamronn/mlgw/blob/master/bangolufsen/media_player.py
Here's my code - which works with the Light command -
https://rapidgator.net/file/f97262f9dfabca44aae57c59c829ca1d/mlgw_client.py.html
Hi Frog
I would like to study your program in python but the link you posted is no longer working. Could you share it again? Could the program be adapted to work with home assistant?
There is code to run the bang Olufsen MLGW from Home Assistant here, which is maintained: https://github.com/simonkamronn/mlgw
That's odd. It works fine with my home assistant. I'm on the latest version of HA. did you configure it correctly?
what is the error(s) you get?
Ciao,
I'd rather continue in English since it may be useful to others :-)
Masterlink devices unfortunately don't report when they are turned off to MLGW, so I haven't been able to make the return path work to update the status. I have the same issue with my Beosound 3000. Beosound only reports when some sources are activated (e.g. CD or RADIO are activated).
You should not need to install any plugin in Lovelace.
You only need to install __init__.py, manifest.json and media_player.py in the custom_components/bangolufsen directory, and a config entry in configuration.yaml, this is mine:
media_player:
- platform: bangolufsen
host: 192.168.1.10
username: xxx
password: xxx
default_source: A.MEM
available_sources:
- A.MEM
- CD
- RADIO
devices:
- Living Room
- Kitchen
- Patio
- Studio
- TV Room
- Bedroom
- Bathroom
Then Lovelace should pick up the media player using the normal media_player UI element.
I use mini_media player as a UI element which is nicer.
https://github.com/kalkih/mini-media-player/blob/master/README.md
1) I get that error too but it does not affect operation. Not all entities need a unique Id. you only need it if you want to persist settings which in this case we don't
2) it's a device thing. Some devices like don't implement the full protocol, ie they don't send a status change when they are turned off. the code actually is designed to handle the turn off packet if the device sends it. you can see exactly what is sent by devices by turning on "INFO" logging for your plugin and looking at the Home assistant logs.
3) you don't need beo-control.js, it's old code and doesn't work. You can just use the normal media player UI from Lovelace.
frog's code
#!/usr/bin/python # This is mlgw_client.py file
#
# It connects to a Bang & Olufsen Masterlink Gateway and interprets the LIGHT button pressed on a remote control
# It then connects via JSON to a Domoticz home automation server to switch on/off/dim a particular light
import socket # Import socket module
import time # Import Time module for delays & time
import datetime # Import time of day module
import json # Import JSON to connect to Domoticz
import urllib
import urllib2
import os # Import OS calls library
import __main__
import sys
__author__ = 'Nigel Smith'
__version__ = '0.1'
#Debug Flag
debug = True
sniff = True # Sniff MLGW packets and display
# Setup B&O datagrams
serno = '01390000'.decode('hex')
#BV10Standby ='0101030012004700'.decode('hex')
#BV10AppleTV ='0101030012008500'.decode('hex')
#BV10Sky = '0101030012008A00'.decode('hex')
#BV10off= '0101030012000C00'.decode('hex')
#mlgw address
hostname = ("192.168.0.22") # Masterlink Gateway hostname
#Rooms
Lounge = 1
Office = 2
Bedroom = 7
Dining = 4
Bathroom =5
Garden = 6
#Lights
RoomLight = 12
LoungeLight = 78
OfficeLight = [[12,False],[ 12, False], [15, False], [16, False]]
BlindLight = 194
VerandaLight = 17
BathroomLight = 45
GardenLight = 322
BedroomLight = 20
#Buttons
BOLightON = 155
BOLightOFF = 54
BOLightUP = 30
BOLightDN = 31
BOTV = 138
KeyRelease = 126
PanelOFF = 88
Exit = 127
Menu = 92
BOLightLeft = 50
BOLightRight = 52
BOGO = 53
BOSelect = 19
ButtonDict = {1:'One', 2:'Two', 3:'Three', 4:'Four', 5:'Five', 6:'Six', 7:'Seven', 8:'Eight', 9:'Nine', 0:'Zero',\
30:'B&O Light UP', 31:'B&O Light Down', 50:'Left Arrow', 52:'Right Arrow', 54:'B&O Light OFF', \
88:'Panel OFF', 92:'Menu', 126:'Key Release', 127:'Exit', 155:'B&O Light ON', 19:'Select'}
RoomDict = {1:'Lounge', 2:'Office', 8:'Bedroom', 4:'En-Suite Bathroom', 5:'Family Bathroom', 6:'Garden'}
#Times
on_time = datetime.time(17,30)
off_time = datetime.time(5,00)
grouplight = False
class switch(object):
value = None
def __new__(class_, value):
class_.value = value
return True
def case(*args):
return any((arg == switch.value for arg in args))
def ByteToHex(byteStr):
hex =[]
for aChar in byteStr:
hex.append("%02X " % ord(aChar))
return ''.join(hex).strip()
def SetLight(Lmp, opt, dimlvl,groups):
if (opt == 'dim'):
LightCMD="http://192.168.0.52:8080/json.htm?type=command¶m=switchlight&idx="+str(Lmp)+"&switchcmd=Set%20Level&level="+dimlvl
else:
if groups:
LightCMD="http://192.168.0.52:8080/json.htm?type=command¶m=switchscene&idx="+str(Lmp)+"&switchcmd="+opt+"&level=0"
LightCMD="http://192.168.0.52:8080/json.htm?type=command¶m=switchlight&idx="+str(Lmp)+"&switchcmd="+opt+"&level=0"
if debug:
print LightCMD
return LightCMD
def GetMLGWStatus():
MStatus =ByteToHex(s.recv(255))
if debug or sniff:
print time.strftime("%c"), '____', MStatus
return MStatus
def isLightCommand(Mstatus):
if (int(Mstatus[3:5],16) == 4):
return False
def getRoom(Mstatus):
return int(Mstatus[12:14],16)
def getLightButton(Mstatus):
if int(Mstatus[3:5]) <> 5:
buttonkey = int(Mstatus[18:20],16)
if ButtonDict.has_key(buttonkey):
print current_time,Mstatus, '--','The button',ButtonDict[buttonkey],'was pressed in the',RoomDict[getRoom(Mstatus)]
print Mstatus, '--''Unknown Key', buttonkey
return int(Mstatus[18:20],16)
return 0
# First check to see if program is running - if so - exit
try:
if len( os.popen( "ps -aef | grep -i "+sys.argv[0]+" | grep -v 'grep' | awk '{ print $3 }'" ).read().strip().split( '\n' ) ) > 1:
print sys.argv[0],"already running"
raise SystemExit(0)
except Exception, e:
raise e
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Create a socket object
host = socket.gethostbyname(hostname) # Connect to Mlgw.local
port = 9000 # Connect to MLGW Port
print "Connecting to: ",host, port
except socket.gaierror,err:
print "cannot resolve hostname: ",hostname,err
s.connect((hostname, port))
s.send(serno)
print ' '
print 'MLGW to Domoticz gateway'
print 'V1.0 - Nigel Smith, 26 Mar 2014'
print 'MLGW Serial Number: ____',s.recv(255)
print 'Waiting for MLGW'
FirstTime = True
while True:
MLGWStat = GetMLGWStatus()
current_time = datetime.datetime.now().time()
ButtonPressed = getLightButton(MLGWStat)
if (ButtonPressed >0):
print current_time
if (isLightCommand(MLGWStat) & ButtonDict.has_key(int(MLGWStat[18:20],16))):
while switch (getRoom(MLGWStat)):
if case(Lounge):
Room = 'Lounge'
RoomLight = LoungeLight
break
if case(Office):
Room = 'Office'
RoomLight = OfficeLight[0][0]
if case(Bedroom):
RoomLight = BedroomLight
Room = 'Bedroom'
grouplight = True
if case(Garden):
Room = 'Garden'
RoomLight = GardenLight
if case(Bathroom):
Room = 'Bathroom'
RoomLight = BathroomLight
print 'Button', ButtonPressed, 'Room', Room, RoomLight
while switch (ButtonPressed):
if case(BOLightON, BOGO, BOSelect):
if FirstTime == True:
FirstTime = False
Button = 'First'
Button = 'ON'
if Room == 'Office':
OfficeLight[1][1] = True
if Room == 'Bedroom' or Room == 'Garden':
urllib2.urlopen(SetLight(RoomLight,'On','32', grouplight)) #Switch (relay)
urllib2.urlopen(SetLight(RoomLight,'dim','32', grouplight)) #Max brightness
if case(BOLightOFF):
Button = 'OFF'
if case(BOLightOFF) and Room == 'Office':
urllib2.urlopen('http://192.168.0.52:8080/json.htm?type=command¶m=switchscene&idx=6&switchcmd=Off')
for n in range(len(OfficeLight)):
OfficeLight[1] = False
if case(BOLightOFF) and (Room == 'Bathroom' or Room == 'Garden' or Room == 'Lounge' or Room == 'Bedroom'):
urllib2.urlopen(SetLight(RoomLight, 'Off',0, grouplight))
if case(1,2,3) and Room == 'Office':
RoomLight = OfficeLight[ButtonPressed][0]
OfficeLight[ButtonPressed][1] = True
if case(4) and Room == 'Office':
urllib2.urlopen('http://192.168.0.52:8080/json.htm?type=command¶m=switchscene&idx=6&switchcmd=On')
OfficeLight[1] = True
if case(5,6,7,8,9,0) and Room == 'Office':
if case(50,52,92):
if case(1,2,3,4,5,6,7,8,9, 0) and Room == 'Lounge':
Button = str(int(round((9 - getLightButton(MLGWStat)+1) *3.2))) #change value from 0-9 to 32 to 1 - Bright to dim
urllib2.urlopen(SetLight(RoomLight,'dim',Button, grouplight))
if case(BOLightUP) and Room == 'Lounge':
urllib2.urlopen(SetLight(VerandaLight,'On',0, grouplight))
if case(BOLightDN) and Room == 'Lounge':
urllib2.urlopen(SetLight(VerandaLight,'Off',0, grouplight))
if case(BOLightUP) and Room == 'Office':
urllib2.urlopen(SetLight(BlindLight,'Off',0, grouplight)) #Toggle Blinds
if case(BOLightDN) and Room == 'Office':
urllib2.urlopen(SetLight(BlindLight,'On',0, grouplight)) #Toggle Blinds
if case(KeyRelease):
Button = 'Key Release'
if case(PanelOFF):
Button = 'PANEL OFF'
if case(Exit):
Button = 'Exit'
Looping = False
print '>>>', Button, 'pressed in ', Room
print ''
s.close # Close the socket when done
One reply here for posterity
I finally managed to get LIGHT commands forwarded. Not sure how it happened, but I did make 2 changes:
set a real password (not admin/admin)
created a separate room for each MLN device on the MLGW. I think this is actually what made the difference.