NetLine is a Hammerspoon Spoon that displays a colored status line at the top of your screen(s) indicating network reachability status. It provides visual feedback on your network connectivity without requiring constant attention to a menubar icon.
- Visual Network Status: Shows a colored line at the top of your screen that indicates network status
- Multi-screen Support: Display on all screens, main screen only, or specific screens
- Customizable Appearance: Configure colors, height, position, and shadow effects
- Sound Alerts: Optional audio notifications for status changes
- Focus Mode Integration: Can respect Do Not Disturb/Focus modes for sound alerts
- Automatic Fading: Configure status line to automatically fade after specified duration
hs.loadSpoon("SpoonInstall")
spoon.SpoonInstall:andUse("NetLine")
- Download the NetLine.spoon zip file from GitHub
- Unzip the file
- Double-click the NetLine.spoon file to install it to your Hammerspoon Spoons directory
Add this to your init.lua
file:
hs.loadSpoon("NetLine")
spoon.NetLine:start()
NetLine can be configured through Hammerspoon's settings system. Here's a full example with all available options:
-- Load NetLine
hs.loadSpoon("NetLine")
-- Configure (Optional - these are all default values)
hs.settings.set("NetLine.targetHost", "1.1.1.1")
hs.settings.set("NetLine.screen", "all") -- "all", "main", or part of screen name/UUID
hs.settings.set("NetLine.barHeight", 3) -- Height in pixels
hs.settings.set("NetLine.barYOffset", 0) -- Distance from top of screen
hs.settings.set("NetLine.horizontalPadding", 0) -- Padding on left/right edges
hs.settings.set("NetLine.shadowSize", 3) -- Shadow blur radius
hs.settings.set("NetLine.shadowOffsetY", -2) -- Shadow vertical offset
hs.settings.set("NetLine.shadowColorAlpha", 0.8) -- Shadow transparency (0.0-1.0)
hs.settings.set("NetLine.fadeDuration", 0.5) -- Animation duration in seconds
-- Status colors (can be any hs.drawing.color format)
hs.settings.set("NetLine.colors.reachable", hs.drawing.color.definedCollections.hammerspoon.osx_green)
hs.settings.set("NetLine.colors.unreachable", hs.drawing.color.definedCollections.hammerspoon.osx_red)
hs.settings.set("NetLine.colors.unknown", hs.drawing.color.definedCollections.hammerspoon.osx_yellow)
-- How long to show the bar before fading (0 = stay visible)
hs.settings.set("NetLine.fadeSeconds.reachable", 5.0)
hs.settings.set("NetLine.fadeSeconds.unreachable", 0.0) -- Stay visible when unreachable
hs.settings.set("NetLine.fadeSeconds.unknown", 3.0)
-- Sound alerts
hs.settings.set("NetLine.sounds.enabled", false)
hs.settings.set("NetLine.sounds.reachable", "Glass") -- System sound name or file path
hs.settings.set("NetLine.sounds.unreachable", "Basso") -- System sound name or file path
hs.settings.set("NetLine.sounds.unknown", "") -- Empty string for no sound
hs.settings.set("NetLine.sounds.volume", 0.7) -- 0.0 to 1.0
-- Logging level: "verbose", "debug", "info", "warning", "error"
hs.settings.set("NetLine.logLevel", "info")
-- Start NetLine
spoon.NetLine:start()
targetHost
: IP address or hostname to monitor for reachability (default: "1.1.1.1")
screen
: Which screen(s) to display the status line on:"all"
: Display on all screens"main"
: Display only on the primary screen"partial name"
: Display on screens whose name or UUID contains this string
barHeight
: Height of the status line in pixels (default: 3)barYOffset
: Distance from the top edge of the screen (default: 0)horizontalPadding
: Distance from left/right screen edges (default: 0)shadowSize
: Size of the shadow effect (default: 3, 0 disables shadow)shadowOffsetY
: Vertical offset of the shadow (default: -2)shadowColorAlpha
: Transparency of the shadow (default: 0.8)fadeDuration
: Animation duration when showing/hiding the bar (default: 0.5)
colors.reachable
: Color when network is reachable (default: macOS green)colors.unreachable
: Color when network is unreachable (default: macOS red)colors.unknown
: Color when network status is unknown (default: macOS yellow)
fadeSeconds.reachable
: How long to display the bar when network becomes reachable (default: 5.0 seconds)fadeSeconds.unreachable
: How long to display the bar when network becomes unreachable (default: 0.0 - stay visible)fadeSeconds.unknown
: How long to display the bar when network status is unknown (default: 3.0 seconds)
sounds.enabled
: Master switch for sound notifications (default: false)sounds.reachable
: Sound to play when network becomes reachable (default: "")sounds.unreachable
: Sound to play when network becomes unreachable (default: "")sounds.unknown
: Sound to play when network status is unknown (default: "")sounds.volume
: Volume level for sound alerts (default: 0.7)
logLevel
: Detail level for logs: "verbose", "debug", "info", "warning", "error" (default: "info")
NetLine provides the following methods:
Starts the network monitoring and displays the status line.
spoon.NetLine:start()
Stops monitoring and removes the status line.
spoon.NetLine:stop()
Returns a table with information about the current status.
local status = spoon.NetLine:status()
hs.inspect(status)
The status table includes:
running
: Boolean indicating if NetLine is activelastDisplayedStatus
: Most recent status ("reachable", "unreachable", "unknown")targetHost
: Current host being monitoredwatcherActive
: Whether the reachability watcher is activecurrentReachabilityFlags
: Current network flagsactiveCanvases
: Information about displayed status lines
hs.loadSpoon("NetLine")
spoon.NetLine:start()
hs.loadSpoon("NetLine")
hs.settings.set("NetLine.screen", "all")
hs.settings.set("NetLine.colors.reachable", {green=0.4, blue=0.9, alpha=0.7})
hs.settings.set("NetLine.colors.unreachable", {red=0.9, alpha=0.9})
spoon.NetLine:start()
hs.loadSpoon("NetLine")
hs.settings.set("NetLine.sounds.enabled", true)
hs.settings.set("NetLine.sounds.reachable", "Glass")
hs.settings.set("NetLine.sounds.unreachable", "Basso")
hs.settings.set("NetLine.sounds.volume", 0.5)
spoon.NetLine:start()
hs.loadSpoon("NetLine")
hs.settings.set("NetLine.barHeight", 5)
hs.settings.set("NetLine.shadowSize", 8)
hs.settings.set("NetLine.shadowOffsetY", -4)
hs.settings.set("NetLine.horizontalPadding", 100) -- Inset from edges
spoon.NetLine:start()
NetLine requires the following Hammerspoon modules:
hs.canvas
hs.drawing.color
hs.logger
hs.network
hs.screen
hs.settings
hs.sound
hs.fnutils
hs.timer
hs.inspect
The hs.focus
module is used if available (for DND detection) but is optional.
https://github.com/FuzzyIdeas/IsThereNet For the idea and implementation details, this is more or less a port of that into hammerspoon.
- Check that Hammerspoon has accessibility permissions in System Preferences
- Try increasing the
barHeight
setting - Check your log console for errors (Console.app, filter for "Hammerspoon")
- Try changing the
targetHost
to a reliable server (like "1.1.1.1" or "8.8.8.8") - Restart Hammerspoon
- Verify that
sounds.enabled
is set totrue
- Check that the sound names are valid system sounds
- Make sure your system volume is not muted
NetLine is released under the MIT License.
- Added multi-screen support
- Added sound alerts
- Added customizable shadow effects
- Added Focus Mode (DND) detection for sounds
- Improved error handling and logging
- Initial release
Contributions are welcome! Please feel free to submit a Pull Request on the GitHub repository.