Gopinath Shiva Gopinath Shiva - 2 months ago 13
AppleScript Question

How to check if user is connected via wifi or LAN through hammerspoon

I am thinking of having a hammerspoon wifi watcher, which do a periodic check and will disable wifi if its not connected.

The following script does this,

function checkAndDisableWifi()
hs.timer.doAfter(45, function()
local current_network = hs.wifi.currentNetwork()
if current_network == nil then
hs.wifi.setPower(false)
hs.notify.new({title="Hammerspoon",informativeText="Disabling wifi due to inactivity"}):send()
end
end)
end

function wifi_timer_callback()
local wifi_state = hs.wifi.interfaceDetails().power
if wifi_state then
local current_network = hs.wifi.currentNetwork()
if current_network == nil then
hs.wifi.setPower(false)
hs.notify.new({title="Hammerspoon",informativeText="Disabling wifi due to inactivity"}):send()
end
else
hs.wifi.setPower(true)
checkAndDisableWifi()
end
end

local wifi_timer = hs.timer.doEvery((10*60), wifi_timer_callback)
wifi_timer:start()


Here I am facing an issue like what if the user is already connected via LAN. At this point of time I dont need to do enable this watcher ( so as to stop doing switching of wifi ON and OFF). So what I need is , Is there any API which can tell me whether the user is already connected via LAN or atleast connected to internet?

Am I clear?

Answer

Right after posting the question, I got an idea similar to @TheFrenchPlays. This is my current approach of expanding this idea via hammerspoon,

status, data, headers = hs.http.get("http://google.com")

so when you inspect the status variable, it will give 200 if it's online and 0 if it's offline. So by inspecting this variable , I can do the workaround of this problem.

If am not wrong, it would be great if the hammerspoon exposes an API whether returns a BOOL if its connected or not. And also via WiFi or LAN.

UPDATE: Right now this work around doesn't solve the problem completely when the system is connected via LAN. Since I don't know whether its connected via LAN or WiFi, I cant turn OFF the WiFi directly. Hence the current workaround seems tedious

function checkAndDisableWifi()
  hs.timer.doAfter(45, function()
    local current_network = hs.wifi.currentNetwork()
    if current_network == nil then
      disableWifi()
    end
  end)
end

function disableWifi()
  hs.wifi.setPower(false)
  hs.notify.new({title="Hammerspoon",informativeText="Disabling wifi due to inactivity"}):send()
end

function wifi_timer_callback()
  local status, data, headers = hs.http.get("http://google.com")
  local wifi_state = hs.wifi.interfaceDetails().power
  local current_network = hs.wifi.currentNetwork()
  if not status == 200 then -- user is offline mean not connected to LAN. So do WiFi check
    if wifi_state and current_network == nil then
      disableWifi()
    else
      hs.wifi.setPower(true)
      checkAndDisableWifi()
    end
  else 
    --[[
        since user is connected to online, check whether user is connected through wifi or not. If wifi is on and not connected to any network then disable wifi
    --]]
    if wifi_state and current_network == nil then
      disableWifi()
    end
  end
end

local wifi_timer = hs.timer.doEvery((10*60), wifi_timer_callback)
wifi_timer:start()

UPDATE 2:

Looks like Hammerspoon (0.9.47) has solution to this. Updating the code using the solution given by Chris,

  if hs.network.interfaceDetails(v4) then
    if hs.network.interfaceDetails(v4)["AirPort"] then
      print("on wifi")
    else
      print("on Lan")
    end
  else
    print("not connected to internet")
  end
Comments