Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 874
Gopinath Shiva Avatar asked Sep 13 '16 16:09

Gopinath Shiva


3 Answers

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
like image 139
Gopinath Shiva Avatar answered Nov 11 '22 13:11

Gopinath Shiva


basically you can just ping google. If you get an output, and aren't connected trough an wifi-Network, you can just set off the wifi. Thats my idea

like image 28
TheFrenchPlays Hd Micraftn Avatar answered Nov 11 '22 12:11

TheFrenchPlays Hd Micraftn


0.9.47 has some new features in hs.network that should help here.

hs.network.primaryInterfaces() returns two values, showing the default interface for ipv4 and ipv6 traffic, so if you were to do something like:

v4,v6 = hs.network.primaryInterfaces()

then, assuming you care most about v4, you could check if hs.network.interfaceDetails(v4)["AirPort"] is nil. If it's nil you're not on a WiFi interface, if it's a table full of wifi values, you're on wifi.

like image 2
Chris Jones Avatar answered Nov 11 '22 11:11

Chris Jones