Skip to content

A small Windows tray app to control the brightness of Samsung Smart Monitors / TVs (tested idea: Odyssey G95SC-class devices) over your local network, written in Python + PyQt6.

License

Notifications You must be signed in to change notification settings

mrzt721010/Samsung-Smart-Monitor-TV-Brightness-Control

Repository files navigation

Samsung Smart Monitor/TV Brightness Control 🖥️✨

A small Windows tray app to control the brightness of Samsung Smart Monitors / TVs (tested idea: Odyssey G95SC-class devices) over your local network, written in Python + PyQt6.

It lives in the system tray, and when you click it, you get a clean brightness slider pop‑up. Under the hood it talks to the monitor using Samsung SmartThings TV WebSocket API via samsungtvws.

⚠️ This project is not an official Samsung app.


Features ✅

🧩 System tray app

  • Runs in the background (no main window).
  • Tray icon menu: Restart / Exit.

🎚️ Brightness slider pop-up

  • Small popup window with a horizontal slider (0 → 50).
  • Remembers last brightness value and restores it on next run.

📡 Network control via samsungtvws

  • Sends remote-control key presses (MENU / arrows / ENTER / RETURN) to reach the brightness menu and adjust it.

🔐 Token / “Allow” handling

  • First setup requests permission on the monitor (you’ll see Allow / Deny prompt on the screen).
  • Token gets saved to disk so next runs are seamless.

🧠 First-run setup dialog

  • Collects Monitor Name + Monitor IP.
  • Saves config to %APPDATA%\MonitorControl\app_config.json.

♻️ Auto reconnect

  • If connection drops while sending a key, the app retries by reconnecting.

🧰 Logging

  • Logs to stdout (when available) and to: %APPDATA%\MonitorControl\app.log

How it works (simple explanation) 🧠

Samsung monitors/TVs expose a remote-control style interface over the network.

This app does NOT set brightness directly by a numeric API call. Instead, it:

  1. Opens the monitor’s on-screen menu.
  2. Navigates to the brightness section.
  3. Sends LEFT/RIGHT key presses to change the value.

That’s why you may see the on-screen menu briefly when using the slider.


Screenshots 📸

  • Installer:

- Finish:

- First run setup:

- TV Allow prompt:

- Tray icon:

- Slider popup:


Install (for users) 🧑‍💻

Option A) Installer (recommended)

  1. Download the latest installer from GitHub Releases.
  2. Run it.
  3. At the end, the installer starts the app in setup mode.

First run

  • The app will ask for:
    • Monitor Name (any label you want)
    • Monitor IP (local IP of the monitor)
  • Then you’ll see a permission prompt on the monitor: ✅ Choose Allow

After that, the tray icon should appear. Click the tray icon to open the slider.

Autostart

If your installer creates an autostart shortcut, it will run on Windows boot.


Build from source (developers) 🧑‍🔧

Requirements:

  • Windows 11
  • Python 3.13.x
  • VS Code (optional)

1) Create venv & install deps

Open PowerShell in the project folder:

py -3.13 -m venv .venv
.\.venv\Scripts\activate
pip install -U pip
pip install -r requirements.txt

2) Run in dev mode

python Monitorcontrol.py

3) Build with PyInstaller (onedir)

Your project uses onedir mode and no console.

Typical command style (adjust if you use a .spec): pyinstaller --noconsole --onedir --icon icon.ico Monitorcontrol.py

If you use a spec file, build with: pyinstaller Monitorcontrol.spec

Important notes:

  • samsungtvws may require websockets and PyInstaller might not detect it automatically.
  • If you hit: ModuleNotFoundError: No module named 'websockets' add hiddenimports for websockets (or install it explicitly and ensure it is included).

4) Create installer (Inno Setup)

  • Use your installer.iss to package the whole onedir folder.
  • Recommended behavior:
    • Copy the entire onedir output folder to Program Files
    • Create Start Menu shortcut
    • Create Startup shortcut (optional)
    • Run app once after install with --setup

Configuration & files 📁

This app stores everything in:

%APPDATA%\MonitorControl\

Files:

  • app_config.json
    • contains: name, ip, and first_run flag (first-run config flow)
  • brightness.json
    • stores last slider brightness value
  • tv_token.json
    • Samsung TVWS token file (created after Allow)
  • app.log
    • logs

Usage 🕹️

Tray icon

  • Left click: open/close brightness slider popup
  • Right click: context menu

Slider behavior

  • Range: 0 → 50
  • When you release the slider, the app calculates the delta and sends:
    • KEY_RIGHT for increasing brightness
    • KEY_LEFT for decreasing brightness

Because it uses key presses, moving the slider from 0 → 50 will send many keys.

Tip:

  • Don’t drag like crazy. Slide, release, let it apply.

Troubleshooting 🧯

1) Tray icon not visible (but process exists)

Things to check:

  • Windows hides inactive tray icons sometimes:
    • Click the “^” arrow near the tray and see if it’s hidden there.
  • Confirm the app is really creating the tray:
    • Check %APPDATA%\MonitorControl\app.log

If the tray icon shows in dev but not after PyInstaller:

  • Make sure icon.ico is included in the build.
  • Avoid relying on working directory paths.
  • Your code uses resource_path() and _MEIPASS which is correct for PyInstaller.

2) “Allow/Deny” prompt never appears

  • Ensure monitor + PC are on the same network.
  • Ensure the IP is correct.
  • Some TVs require being turned on/unlocked.
  • Try running:
    • installed app with --setup

3) ModuleNotFoundError: websockets

This means PyInstaller missed it. Fix by:

  • Installing it explicitly and rebuilding: pip install websockets
  • Adding it to hiddenimports in the spec (if needed).

4) Brightness menu navigation is off

Samsung menu layouts can differ by model/firmware. This app navigates with a fixed sequence:

  • MENU → RIGHT → DOWN x4 → ENTER → ENTER If your model differs, tweak:
  • open_brightness_menu()
  • open_brightness_menu_first_time()

Security notes 🔒

  • The app talks to your monitor over LAN.
  • tv_token.json is a local token used for authentication after you press Allow.
  • Do not upload your personal token file to GitHub.
  • Do not expose your monitor IP publicly (it’s a LAN IP anyway, but still).

Roadmap ideas 💡

  • Multi-monitor support (profiles list)
  • Better UI polish (animation / modern styling)
  • Direct brightness API if Samsung exposes one (avoid menu navigation)
  • Optional hotkeys

License 📄

Copyright 2026 MRZT721010

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Credits 🙏

  • PyQt6
  • samsungtvws

About

A small Windows tray app to control the brightness of Samsung Smart Monitors / TVs (tested idea: Odyssey G95SC-class devices) over your local network, written in Python + PyQt6.

Resources

License

Stars

Watchers

Forks

Packages

No packages published