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

3

7

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?

Sickroom answered 13/9, 2016 at 16:19 Comment(0)
S
4

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
Sickroom answered 13/9, 2016 at 16:26 Comment(1)
hs.network.interfaceDetails(v4) looks like a snippet from a larger config, because it's wrong in isolation.Tennyson
R
2

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

Reality answered 13/9, 2016 at 16:22 Comment(4)
Appreciate the Idea dudeSickroom
because i don't have the reputation to answer YOUR post: can't you see the name of the wireless conector? if so, you can simply test, if the name is blankReality
Yes I am doing the same in the updated answer. Though it solves the problem, it doesn't love it in a straight forward waySickroom
Sometimes dirty ways of solving are better than installing a new package ¦~}Reality
T
2

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.

Tennyson answered 16/9, 2016 at 11:28 Comment(4)
Appreciate the solution given. Based on my understanding, I have updated my answer above using the hs.network.interfaceDetails(v4). Could you please confirm me, is that a right solution (though I checked my end its working with the code just want to know from you :) )?Sickroom
Looks reasonable to me :) I'd also note that there's hs.network.reachability if you want to detect whether various forms of connectivity are functioning at all (e.g. is a particular host routable, is any internet routable, is a VPN routable, etc)Tennyson
Cool. Thanks for a great tool, Chris. Loving it :)Sickroom
Do you know is there any way of invoking hammerspoon api when screen is locked (possibly through hotkey triggering) - #39434536Sickroom

© 2022 - 2024 — McMap. All rights reserved.