This guide disables the red standby LED entirely via software. No hardware modification, no opening the TV, no soldering. The LED stays off through standby and power cycles.
Tested on: UA50JU6400WXXY, firmware T-HKMUABC 1550.0 (build 2019-11-28), Tizen 2.3.0. May work on other 2015 J-series Samsung TVs with the same firmware platform.
Prerequisites
- A computer on the same local network as the TV
- Python 3 installed on the computer
- The TV’s IP address (find it in TV Settings → Network → Network Status)
Step 1: Enable Developer Mode on the TV
- On the TV remote, press Smart Hub (or Home)
- Navigate to Apps
- In the Apps panel, press 1 2 3 4 5 on the remote (a settings dialog appears)
- Toggle Developer Mode to ON
- Enter your computer’s local IP address (e.g.
192.168.1.100) — find it withifconfig(Mac) oripconfig(Windows) - Press OK and accept the prompt
- Restart the TV (power off completely, then back on)
After restart, Developer Mode is active and the SDB (Samsung Debug Bridge) service listens on TCP port 26101.
Reference: https://developer.samsung.com/smarttv/develop/getting-started/using-sdk/tv-device.html
Step 2: Verify connectivity
From your computer’s terminal:
python3 -c "
import socket
try:
s = socket.create_connection(('TV_IP_HERE', 26101), timeout=5)
s.close()
print('OK - TV is reachable on SDB port')
except Exception as e:
print(f'FAIL - {e}')
"
Replace TV_IP_HERE with the TV’s actual IP. If it says “Connection refused” or “timed out”, check that:
- The TV is powered ON (not in standby)
- Developer Mode is enabled
- Your computer’s IP matches what you entered in the Developer Mode setup
Step 3: Run the LED disable script
Save the following as disable_led.py and run it with python3 disable_led.py:
"""
Permanently disable the standby LED on Samsung JU6400 (2015 J-series).
This script:
1. Uploads a LED-off Python script to the TV's persistent storage
2. Connects to systemd via the TV's private DBUS socket
3. Installs a systemd service that runs at every boot
4. Sends the LED-off MICOM commands immediately
The root filesystem is temporarily remounted read-write for the service
installation, then re-sealed read-only.
"""
import socket, struct, time, sys
# ============================================================
# CONFIGURATION — change this to your TV's IP address
# ============================================================
TV_IP = 'TV_IP_HERE'
TV_PORT = 26101
# ============================================================
MAX_PAYLOAD = 4096
def exact(sock, count):
buf = bytearray()
while len(buf) < count:
chunk = sock.recv(count - len(buf))
if not chunk:
raise EOFError('Connection closed')
buf.extend(chunk)
return bytes(buf)
def send_pkt(sock, cmd, a0, a1, payload=b''):
n = int.from_bytes(cmd, 'little')
sock.sendall(struct.pack('<6I', n, a0, a1, len(payload),
sum(payload), n ^ 0xffffffff) + payload)
def recv_pkt(sock, timeout=10):
sock.settimeout(timeout)
cmd, a0, a1, length, csum, magic = struct.unpack('<6I', exact(sock, 24))
if length > MAX_PAYLOAD or magic != cmd ^ 0xffffffff:
raise ValueError('Invalid packet')
payload = exact(sock, length) if length else b''
return cmd.to_bytes(4, 'little'), a0, a1, payload
def read_dbus_lines(sock, lid, rid, timeout=3):
buf = bytearray()
deadline = time.time() + timeout
while time.time() < deadline:
try:
c, _, _, p = recv_pkt(sock, max(0.5, deadline - time.time()))
if c == b'OKAY':
continue
if c == b'WRTE':
buf.extend(p)
send_pkt(sock, b'OKAY', lid, rid)
if c == b'CLSE':
break
except (socket.timeout, OSError):
break
return bytes(buf)
def read_dbus_binary(sock, lid, rid, timeout=10):
buf = bytearray()
deadline = time.time() + timeout
while time.time() < deadline:
try:
c, _, _, p = recv_pkt(sock, max(0.5, deadline - time.time()))
if c == b'OKAY':
continue
if c == b'WRTE':
buf.extend(p)
send_pkt(sock, b'OKAY', lid, rid)
if c == b'CLSE':
break
except (socket.timeout, OSError):
break
return bytes(buf)
class DBusWriter:
def __init__(self):
self.buf = bytearray()
def _pad(self, a):
r = len(self.buf) % a
if r:
self.buf += b'\0' * (a - r)
def write_boolean(self, v):
self._pad(4)
self.buf += struct.pack('<I', 1 if v else 0)
def write_string(self, s):
self._pad(4)
b = s.encode('utf-8')
self.buf += struct.pack('<I', len(b)) + b + b'\0'
def start_array(self, element_alignment):
self._pad(4)
length_pos = len(self.buf)
self.buf += b'\0\0\0\0'
self._pad(element_alignment)
content_start = len(self.buf)
return length_pos, content_start
def end_array(self, length_pos, content_start):
array_len = len(self.buf) - content_start
struct.pack_into('<I', self.buf, length_pos, array_len)
def data(self):
return bytes(self.buf)
def build_method_call(serial, path, member, interface=None, sig=None, body=b''):
fields = bytearray()
def add_field(code, type_sig, value_bytes):
pad = (8 - (len(fields) % 8)) % 8
fields.extend(b'\0' * pad)
fields.append(code)
fields.append(len(type_sig))
fields.extend(type_sig.encode('ascii'))
fields.append(0)
fields.extend(value_bytes)
def str_bytes(s):
b = s.encode('utf-8')
return struct.pack('<I', len(b)) + b + b'\0'
def sig_bytes(s):
b = s.encode('ascii')
return bytes([len(b)]) + b + b'\0'
add_field(1, 'o', str_bytes(path))
if interface:
add_field(2, 's', str_bytes(interface))
add_field(3, 's', str_bytes(member))
if sig:
add_field(8, 'g', sig_bytes(sig))
fields_bytes = bytes(fields)
hdr_pad = (8 - (len(fields_bytes) % 8)) % 8
header = struct.pack('<BBBBIII', ord('l'), 1, 0, 1,
len(body), serial, len(fields_bytes))
return header + fields_bytes + b'\0' * hdr_pad + body
def sdb_send_file(path, content, mode=0o644):
"""Upload a file to the TV via SDB SEND."""
sock = socket.create_connection((TV_IP, TV_PORT), timeout=10)
sock.settimeout(10)
send_pkt(sock, b'CNXN', 0x01000000, MAX_PAYLOAD, b'host::\0')
recv_pkt(sock)
send_pkt(sock, b'OPEN', 1, 0, b'sync:\0')
cmd, rid, _, _ = recv_pkt(sock)
if cmd != b'OKAY':
sock.close()
return False
buf = bytearray()
def _w(data):
for off in range(0, len(data), MAX_PAYLOAD):
send_pkt(sock, b'WRTE', 1, rid, data[off:off + MAX_PAYLOAD])
while True:
c, _, _, p = recv_pkt(sock)
if c == b'OKAY':
break
if c == b'WRTE':
buf.extend(p)
send_pkt(sock, b'OKAY', 1, rid)
if c == b'CLSE':
raise EOFError
def _r(n):
while len(buf) < n:
c, _, _, p = recv_pkt(sock)
if c == b'WRTE':
buf.extend(p)
send_pkt(sock, b'OKAY', 1, rid)
elif c == b'CLSE':
raise EOFError
r = bytes(buf[:n])
del buf[:n]
return r
ps = f'{path},{mode}'.encode()
_w(b'SEND' + struct.pack('<I', len(ps)) + ps)
cm = MAX_PAYLOAD - 64
for off in range(0, len(content), cm):
chunk = content[off:off + cm]
_w(b'DATA' + struct.pack('<I', len(chunk)) + chunk)
_w(b'DONE' + struct.pack('<I', int(time.time())))
tag = _r(4)
_r(4)
send_pkt(sock, b'CLSE', 1, rid)
sock.close()
return tag == b'OKAY'
def sdb_stat(path):
"""Check if a file exists on the TV via SDB STAT."""
sock = socket.create_connection((TV_IP, TV_PORT), timeout=10)
sock.settimeout(10)
send_pkt(sock, b'CNXN', 0x01000000, MAX_PAYLOAD, b'host::\0')
recv_pkt(sock)
send_pkt(sock, b'OPEN', 1, 0, b'sync:\0')
cmd, rid, _, _ = recv_pkt(sock)
if cmd != b'OKAY':
sock.close()
return 0, 0
buf = bytearray()
def _w(data):
for off in range(0, len(data), MAX_PAYLOAD):
send_pkt(sock, b'WRTE', 1, rid, data[off:off + MAX_PAYLOAD])
while True:
c, _, _, p = recv_pkt(sock)
if c == b'OKAY':
break
if c == b'WRTE':
buf.extend(p)
send_pkt(sock, b'OKAY', 1, rid)
if c == b'CLSE':
raise EOFError
def _r(n):
while len(buf) < n:
c, _, _, p = recv_pkt(sock)
if c == b'WRTE':
buf.extend(p)
send_pkt(sock, b'OKAY', 1, rid)
elif c == b'CLSE':
raise EOFError
r = bytes(buf[:n])
del buf[:n]
return r
name = path.encode()
_w(b'STAT' + struct.pack('<I', len(name)) + name)
tag = _r(4)
if tag == b'STAT':
m, s, t = struct.unpack_from('<3I', _r(12))
send_pkt(sock, b'CLSE', 1, rid)
sock.close()
return m, s
send_pkt(sock, b'CLSE', 1, rid)
sock.close()
return 0, 0
# ============================================================
# Files to install on the TV
# ============================================================
# This script runs at every boot via systemd — just sends LED-off commands
LED_OFF_RUN = b"""\
import os, array, fcntl
try:
fd = os.open('/dev/micom-msg', os.O_RDWR)
msg = array.array('B', [0xE5, 0xE5] + [0]*10)
fcntl.ioctl(fd, 0xC00CB301, msg, True)
os.close(fd)
except:
pass
try:
fd = os.open('/dev/micom-msg', os.O_RDWR)
msg2 = array.array('B', [0x2A, 0x3A] + [0]*10)
fcntl.ioctl(fd, 0xC00CB301, msg2, True)
os.close(fd)
except:
pass
"""
# One-time installer: remounts /, writes service file, creates symlink, LED off
INSTALLER = b"""\
import os, array, fcntl, errno
results = []
ret = os.system('mount -o remount,rw /')
results.append('remount_rw:' + str(ret))
if ret == 0:
svc = '[Unit]\\nDescription=LED Off\\nAfter=deviced-pre.service\\n\\n[Service]\\nType=oneshot\\nExecStart=/usr/bin/python /home/developer/led-off-run.py\\n\\n[Install]\\nWantedBy=multi-user.target\\n'
try:
f = open('/etc/systemd/system/led-off.service', 'w')
f.write(svc)
f.close()
results.append('svc:ok')
except Exception as e:
results.append('svc:' + str(e))
wdir = '/etc/systemd/system/multi-user.target.wants'
try:
os.makedirs(wdir)
except OSError:
pass
wlink = wdir + '/led-off.service'
try:
if os.path.exists(wlink):
os.unlink(wlink)
os.symlink('/etc/systemd/system/led-off.service', wlink)
results.append('link:ok')
except Exception as e:
results.append('link:' + str(e))
results.append('svc_exists:' + str(os.path.exists('/etc/systemd/system/led-off.service')))
results.append('link_exists:' + str(os.path.islink(wlink)))
ret2 = os.system('mount -o remount,ro /')
results.append('remount_ro:' + str(ret2))
try:
fd = os.open('/dev/micom-msg', os.O_RDWR)
msg = array.array('B', [0xE5, 0xE5] + [0]*10)
fcntl.ioctl(fd, 0xC00CB301, msg, True)
os.close(fd)
results.append('e5:ok')
except Exception as e:
results.append('e5:' + str(e))
try:
fd = os.open('/dev/micom-msg', os.O_RDWR)
msg2 = array.array('B', [0x2A, 0x3A] + [0]*10)
fcntl.ioctl(fd, 0xC00CB301, msg2, True)
os.close(fd)
results.append('2a:ok')
except Exception as e:
results.append('2a:' + str(e))
f = open('/tmp/led-install-result', 'w')
f.write('\\n'.join(results))
f.close()
"""
INSTALLER_SERVICE = b"""\
[Unit]
Description=LED Off Installer
[Service]
Type=oneshot
ExecStart=/usr/bin/python /tmp/led-installer.py
"""
# ============================================================
# Main script
# ============================================================
def main():
if TV_IP == 'TV_IP_HERE':
print('ERROR: Edit this script and set TV_IP to your TV\'s IP address.')
sys.exit(1)
print(f'Samsung JU6400 LED Disable')
print(f'TV: {TV_IP}:{TV_PORT}')
print()
# Step 1: Upload files
print('[1/4] Uploading files to TV...')
ok1 = sdb_send_file('/tmp/led-installer.py', INSTALLER)
print(f' Installer script: {"OK" if ok1 else "FAIL"}')
ok2 = sdb_send_file('/home/developer/led-off-run.py', LED_OFF_RUN)
print(f' Boot-time script: {"OK" if ok2 else "FAIL"}')
ok3 = sdb_send_file('/tmp/led-installer.service', INSTALLER_SERVICE)
print(f' Service file: {"OK" if ok3 else "FAIL"}')
if not (ok1 and ok2 and ok3):
print('\nUpload failed. Check TV connectivity and Developer Mode.')
sys.exit(1)
# Step 2: Connect to systemd via DBUS
print('\n[2/4] Connecting to systemd via DBUS...')
sock = socket.create_connection((TV_IP, TV_PORT), timeout=10)
sock.settimeout(10)
lid = 1
send_pkt(sock, b'CNXN', 0x01000000, MAX_PAYLOAD, b'host::\0')
recv_pkt(sock)
send_pkt(sock, b'OPEN', lid, 0, b'localfilesystem:/run/systemd/private\0')
cmd, rid, _, _ = recv_pkt(sock)
if cmd != b'OKAY':
print(' Failed to open systemd socket')
sys.exit(1)
print(' Socket opened')
send_pkt(sock, b'WRTE', lid, rid, b'\x00AUTH EXTERNAL 30\r\n')
resp = read_dbus_lines(sock, lid, rid, 3)
if b'DATA' in resp:
send_pkt(sock, b'WRTE', lid, rid, b'DATA\r\n')
read_dbus_lines(sock, lid, rid, 3)
send_pkt(sock, b'WRTE', lid, rid, b'BEGIN\r\n')
time.sleep(0.3)
print(' Authenticated')
# Step 3: Load, link, reload, start the installer service
print('\n[3/4] Running installer via systemd...')
serial = 1
# LoadUnit
w = DBusWriter()
w.write_string('led-installer.service')
msg = build_method_call(serial, '/org/freedesktop/systemd1', 'LoadUnit',
interface='org.freedesktop.systemd1.Manager',
sig='s', body=w.data())
serial += 1
send_pkt(sock, b'WRTE', lid, rid, msg)
resp = read_dbus_binary(sock, lid, rid, 5)
if resp and resp[1] == 4:
read_dbus_binary(sock, lid, rid, 3)
print(' LoadUnit: done')
# LinkUnitFiles
w = DBusWriter()
lp, cs = w.start_array(4)
w.write_string('/tmp/led-installer.service')
w.end_array(lp, cs)
w.write_boolean(True)
w.write_boolean(True)
msg = build_method_call(serial, '/org/freedesktop/systemd1', 'LinkUnitFiles',
interface='org.freedesktop.systemd1.Manager',
sig='asbb', body=w.data())
serial += 1
send_pkt(sock, b'WRTE', lid, rid, msg)
resp = read_dbus_binary(sock, lid, rid, 5)
if resp and resp[1] == 4:
read_dbus_binary(sock, lid, rid, 3)
print(' LinkUnitFiles: done')
# Reload
msg = build_method_call(serial, '/org/freedesktop/systemd1', 'Reload',
interface='org.freedesktop.systemd1.Manager')
serial += 1
send_pkt(sock, b'WRTE', lid, rid, msg)
resp = read_dbus_binary(sock, lid, rid, 10)
if resp and resp[1] == 4:
read_dbus_binary(sock, lid, rid, 5)
print(' Reload: done')
# StartUnit
w = DBusWriter()
w.write_string('led-installer.service')
w.write_string('replace')
msg = build_method_call(serial, '/org/freedesktop/systemd1', 'StartUnit',
interface='org.freedesktop.systemd1.Manager',
sig='ss', body=w.data())
serial += 1
send_pkt(sock, b'WRTE', lid, rid, msg)
resp = read_dbus_binary(sock, lid, rid, 10)
if resp and resp[1] == 4:
read_dbus_binary(sock, lid, rid, 5)
print(' StartUnit: done')
send_pkt(sock, b'CLSE', lid, rid)
sock.close()
# Step 4: Wait and verify
print('\n[4/4] Waiting for installer to complete...')
time.sleep(10)
svc_m, _ = sdb_stat('/etc/systemd/system/led-off.service')
want_m, _ = sdb_stat('/etc/systemd/system/multi-user.target.wants/led-off.service')
run_m, _ = sdb_stat('/home/developer/led-off-run.py')
result_m, result_sz = sdb_stat('/tmp/led-install-result')
print()
if svc_m and want_m and run_m:
print('SUCCESS! LED disable service installed permanently.')
print()
print(' Service: /etc/systemd/system/led-off.service')
print(' Symlink: /etc/systemd/system/multi-user.target.wants/led-off.service')
print(' Script: /home/developer/led-off-run.py')
print()
print('The LED should already be off. Power cycle the TV to confirm')
print('the LED stays off through standby and restarts.')
elif result_m:
print(f'Installer ran (result file: {result_sz} bytes) but service')
print('files not found. The remount may have failed.')
else:
print('Installer may not have executed. Check:')
print(' - TV is powered on (not standby)')
print(' - Developer Mode is enabled')
print(' - Your IP is registered in Developer Mode settings')
if __name__ == '__main__':
main()
How it works
The TV’s normal service menu LED setting (Option → Engineer Option → Standby led on/off = OFF) doesn’t actually suppress the LED on this model. The shutdown path re-reads the factory setting and sends a MICOM command regardless.
This script bypasses that by:
- Uploading files via SDB (Samsung Debug Bridge) file transfer
- Connecting to systemd’s private DBUS socket through SDB’s
localfilesystem:transport — this reaches systemd (PID 1), which runs as root with full privileges - Installing a systemd service that runs at every boot, before the normal TV UI starts
- The service executes a Python script that sends two MICOM ioctl commands:
0xE5, 0xE5— standby LED off0x2A, 0x3A— power LED off
The root filesystem (/etc/systemd/system/) is normally read-only, so the installer temporarily remounts it read-write, writes the service file and symlink, then remounts read-only.
Reversal
To re-enable the LED, run this script on the same computer with the TV on and Developer Mode active. Save as reenable_led.py:
"""Re-enable the standby LED by removing the LED-off service."""
# Copy all the helper functions from disable_led.py above, then:
UNDO_SCRIPT = b"""\
import os
os.system('mount -o remount,rw /')
try:
os.unlink('/etc/systemd/system/multi-user.target.wants/led-off.service')
except:
pass
try:
os.unlink('/etc/systemd/system/led-off.service')
except:
pass
os.system('mount -o remount,ro /')
open('/tmp/led-undo-result', 'w').write('done')
"""
# Upload and run via the same systemd DBUS method as the installer.
# After a reboot, the LED will return to its default behavior.
Troubleshooting
“Connection refused” on port 26101:
- TV must be powered ON, not in standby
- Developer Mode must be enabled (press 12345 in Apps)
- Your computer’s IP must match the one entered in Developer Mode settings
- Restart the TV after enabling Developer Mode
Installer runs but service files not created:
- The root filesystem remount may have failed. This is model/firmware dependent.
- Check that
/tmp/led-install-resultexists (the script ran) vs not (the script didn’t execute)
LED comes back on after firmware update:
- A firmware update may overwrite
/etc/systemd/system/. Re-run the installer after updating.
Works on power cycle but not on standby-wake:
- The E5/E5 command suppresses the standby LED. If it comes back during certain sleep/wake transitions, the boot-time command should re-suppress it on next full boot.
Technical details
- MICOM: The TV’s microcontroller that controls the LED and power management. Communication is via
/dev/micom-msg(mode 0666, SMACK label*) using ioctl0xC00CB301with a 12-byte message. - systemd version 43: Very old. No
StartTransientUnit(requires systemd 209+). UsesLoadUnit+LinkUnitFiles+Reload+StartUnitinstead. - UEP bypass: The TV’s Unified Enforcement Policy blocks execution from debug-launchpad child processes. systemd (PID 1) is not subject to UEP, which is why this approach works while others don’t.
- SDB protocol: Samsung Debug Bridge, similar to ADB. Version 0x01000000, max payload 4096. Uses
localfilesystem:transport to reach Unix domain sockets on the TV.
Leave a Reply