Lunar – macOS utility to set brightness and volume on external monitors
lunar.fyi
lunar.fyi
AFAIK there is no events for brightness change so this is why polling for main monitor brightness?
What are you using for analytics at "https://log.lunar.fyi?
I have been using [1] before, your app seems much more slick
Yes, there are no brightness change events, but reading the brightness is very fast so polling adds very little overhead.
For analytics I've just been using a plain nginx route that logs the request body to a static file, and I parse that using loki for further visualization in Grafana. I haven't found much value in that info though so I've decommissioned it after I migrated from nginx to Caddy. I'll remove the analytics request in the next update.
Before learning these things I was feeling excited about Apple's re-committing to the Mac around that time, but man these things made it feel like such "commitment" was just surface level - such low-hanging fruit not being handled is a shame. But, this is a rant for another day.
Anyway, I built my own very simple utility to poll the internal display for its brightness and write that same brightness to the LG via DDC, but never had the time/energy to make it more robust for publishing to the web. I have yet to try Lunar but I definitely will; much appreciated.
Can you elaborate on why you think that is? I’ve owned that monitor, and it seemed equally easy on both.
Hope that made sense! Thanks for the software!!! :)
So what does this do:
Lunar allows you to change the hardware brightness and contrast of the monitor (the one that can be controlled with the hardware buttons on the monitor)
If you simply want to turn down the brightness from time to time, you can set Lunar in Manual mode and use the brightness keys on your keyboard to adjust the monitor brightness.
Where Lunar shines is with a MacBook or iMac where there is an ambient light sensor integrated in the device that adapts the builtin display brightness. In Sync mode Lunar can sync that already adapted brightness to your external monitor so you don't have to worry about the brightness throughout the day.
There's also a Location mode if you want the brightness to adjust automatically based on the sun position in your location.
All this can be controlled through hotkeys which are visible in both the menu bar icon menu and the Hotkeys configuration page reachable by pressing the left arrow key 2 times in the Lunar UI.
I will disable the request completely in the next update, but if you want to know what's sent or even disable it completely you can take a look at the source code of the sendAnalytics function in AppDelegate.swift: https://github.com/alin23/Lunar
Thanks for making this! Having keys to adjust the brightness is such a blessing for my workflow.
Your app has been a godsend for my multimonitor setup, Macbook in clamshell mode. I tried a bunch of tools, but eventually gave up frustrated after crashes.
Love Lunar since I discovered it, it’s been working smooth from day one.
I use it with 2 disparate non-thunderbolt monitors, one connected into its built-in dock, and the other to a dock dongle. Works perfectly fine!
Worrying about this is the main reason we don't ship DDC/CI with f.lux. (I know that some more modern monitors use NAND and don't have limitations like this.) Anyone know if these fears are overblown?
BTW, assuming I change brightness 20 times per day, that would still give me 5000 days ≈ 13,5 years of service. By that time I definitely hope to use a different monitor than today
So every time you write to three same byte you're writing the same cell. 100.000 cycles is actually much more than current flash generations.
Early EEPROM could only be wiped entirely (but as this was done electrically, it was still an improvement over UV-erased EPROM), while EEPROM at the time of Flash's creation could often be byte-erased (as is the case now).
Nowadays "EEPROM" mostly refers to small, slow, rarely written config storage for microcontrollers. As thus, they are also usually accompanied by low write/erase endurance despite their byte-erase granularity.
Flash was meant as a higher capacity/performance version indeed sporting full block erasure as a downside, but nowadays it has supplanted EEPROM in all categories but small micro-controller usages. Plus, as capacity is now cheap, high write loads can easily be supported with write levelling (that is, writing to new locations instead of erasing/writing the same block over an over.)
100,000 is a typical eeprom guaranteed write count. It will likely last much longer. The eeprom is probably much bigger than they need for such an application so they could actually handle the wear case by moving to alternate locations when write failures occur.
This is not an option when using DDC/CI, where each brightness change is an isolated command. Plus, the OS is likely to emulate a smooth transition by sending even more commands than the end-user dictated.
Sure, the firmware could defer storing to EEPROM until a timeout from last command, but I would not credit the average display firmware as being that thoughtful.
> 100,000 is a typical eeprom guaranteed write count.
No, it's usually an estimated write endurance at a certain voltage and at 25°C, with the number based on calculated risk of failure being lower than a non-zero threshold. Higher temperature and voltage leads to higher failure rates.
I have dealt with several EEPROMs dying after just thousands of writes, including ones in products manufactured at a previous employer (where the EEPROMs were replaced with modern flash). Reserve EEPROMs for when writes are the exception.
Use DDC/CI, and they'll stop. Even NAND is wrong if brightness is actually dynamically controlled, it should just be RAM.
Such monitor recommendations could only be based on people tearing down things, which is outside the scope of Lunar and f.lux.
There is never a guarantee that you don't get stuck with a dud monitor, in any aspect. However, companies making products with bad reliability is going to face high support/warranty fulfillment costs and get a bad reputation. And if it fails within warranty/consumer protection periods, you lose nothing.
So, write away, and flood bad manufacturers in complaints. It's all you can do as a consumer - the alternative boing to get AMD, nVidia or Intel (or Displayport/HDMI interest forums) to be interested in making requirements against display manufacturers on the matter.
Seems like the kind of thing you could easily test if so inclined and properly insured?
For things like setting brightness or toggling devices that ought to be dead simple, stuff like DDC/CI and HDMI-CEC being broken on so many levels never fails to make me spectacularly sad.
Edit: updated the title
It's nice for mute/unmute though
alias verydull="~/Software/ddcctl/ddcctl -d 1 -b 3 -c 15"
alias dull="~/Software/ddcctl/ddcctl -d 1 -b 6 -c 35"
alias decent="~/Software/ddcctl/ddcctl -d 1 -b 10 -c 40"
alias medium="~/Software/ddcctl/ddcctl -d 1 -b 25 -c 50"
alias bright="~/Software/ddcctl/ddcctl -d 1 -b 30 -c 50"
alias morebright="~/Software/ddcctl/ddcctl -d 1 -b 35 -c 60"
alias superbright="~/Software/ddcctl/ddcctl -d 1 -b 100 -c 80"I wrote a GUI slider that wraps around the command line, so I don't have to type the numbers each time.
Pretty much all monitor settings are exposed.
I set it up in a cron job and that has been running for years now. (the external monitor brightness is not very linear though, so you need to fiddle a big to find the proper/acceptable matching)
It didn't occur to me that the Touch Bar control might be specific to this display, since the display predates the TouchBar by many years. But maybe it is, since you and other commenters don't seem to see it.
My previous laptop was a 2012 Macbook Air, and I used an Apple Bluetooth keyboard at my desk in part for this reason. The laptop keyboard adjusted the laptop screen brightness, and the BT keyboard adjusted the external screen brightness.
https://www.nesveda.com/projects/ExternalDisplayBrightness/
With my LG 32UL950-W, I've found that whether it responds depends on the cable choice. I had to give up on Thunderbolt because the monitor itself kept resetting; HDMI delivers a picture but doesn't look as good, and doesn't respond to ExternalDisplayBrightness. I'm now using a 10' USB-C to DisplayPort cable (too long for Thunderbolt) and everything works, including ExternalDisplayBrightness.
I'm curious to see if switching to Lunar would gain me anything.
But as I was gathering feedback from users, I wanted to make Lunar usable in as many monitor setups as possible. And very good ideas came out of that (Sync mode being one of them) but it also cluttered the UI with a bit too many configurable values. Those are still needed by some users even though they might not seem useful for you, so I don't want to remove configurability.
I think by adding all these knobs, Lunar achieved the goal of being flexible enough to conform to most types of monitor usage. Now I just have to figure out how to simplify all this without losing flexibility.
The preferences screen is very difficult to use - it's a mix of labels and buttons with no indication that things are adjustable. You can adjust the brightness by hovering over the brightness amount and scrolling vertically. There are multiple preference panes, but they're only findable with horizontal scrolling. None of this is easily discoverable.
I use the software... but pretty much only the shortcut keys (^F2, ^F1). The other features which seem like they could be useful, would probably see a lot higher adoption if the application followed some UX best practices.
On my iPhone 11 late at night, turning the brightness down to 20% makes black text on white readable, but if I switch to a dark mode app, it's not comfortable, so I have to turn the brightness up again. To me, that implies the brightness just linearly applies to the whole colour spectrum, when it'd be better to weight the brightness logarithmically: Colours close to the dark should stay the same at both 20% and 100% brightness.
I'm not sure if this is even possible on an iPhone. I don't have the same problem on my external Dell screen with my Mac, not sure why.
I haven't messed with the brightness in years because the OSD is so bad.
I would honestly base my next monitor purchase based on compatibility with this utility!
I think they would complement each other. Anyone tried both? (Lunar and f.lux)
* [1] https://justgetflux.com/
I've been using Lunar with Night Shift ever since it was released in macOS and they complement each other very well at night.
Up/down arrow keys can also be used to adjust values in the UI while the cursor is on a value.
I mostly use scrolling for rough adjustments and arrow keys for fine tuning. It feels faster than simply editing a text field. Although I'm planning to make the fields editable in the future as a lot of users have requested that.
The only issue was with the "Read external monitor brightness periodically" preference, which froze the system. But there is a fair warning.
If you feel like supporting the author, here is his Patreon:
https://vesa.org/displayport-developer/certified-components/
Also that VESA page is golden, now I know where to point people when they ask me for advice on what peripherals to buy.
Will have to try this out when I get it hooked up to my Macbook!
I plan to implement just the first switch along with a brightness/contrast reset to some default values so you can easily switch the monitor to another input.
But there are cases like yours where the response time is so slow that the kernel panics in the first DDC message and freezes the whole system. There's no way to detect or recover from that in software.
You could open a feature request on GitHub, best way to let author know.
https://github.com/alin23/Lunar/issues/new?assignees=alin23&...
I already have a lot of users telling me that the UI is too complex.
Looked wonderful though!
I have that information in the troubleshooting section on Github but I'll have to update the official website to also include that.