如何通过 hammerspoon 检查用户是通过 wifi 还是 LAN 连接

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

我正在考虑使用 hammerspoon wifi 观察器,它会定期检查并在未连接时禁用 wifi。

以下脚本执行此操作,

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()

这里我遇到了一个问题,比如如果用户已经通过 LAN 连接会怎样。此时我不需要启用此观察器(以停止打开和关闭 wifi 的切换)。所以我需要的是,是否有任何 API 可以告诉我用户是否已经通过 LAN 连接或至少连接到互联网?

我清楚了吗?

基本上你可以 ping google。如果你得到一个输出,并且没有通过 wifi 网络连接,你可以直接启动 wifi。这就是我的想法

发布问题后,我得到了类似于@TheFrenchPlays 的想法。这是我目前通过 hammerspoon 扩展这个想法的方法,

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

因此,当您检查状态变量时,如果在线,它将给出 200,如果离线,它将给出 0。所以通过检查这个变量,我可以解决这个问题。

如果我没记错的话,如果 hammerspoon 公开一个 API 是否 returns 一个 BOOL 连接与否,那就太好了。也可以通过 WiFi 或 LAN。

更新: 目前,当系统通过 LAN 连接时,此解决方法不能完全解决问题。由于我不知道它是通过 LAN 还是 WiFi 连接的,我不能直接关闭 WiFi。因此,当前的解决方法似乎很乏味

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()

更新 2:

看起来 Hammerspoon (0.9.47) 对此有解决方案。使用 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

0.9.47 在 hs.network 中有一些新功能应该对这里有所帮助。

hs.network.primaryInterfaces() returns 两个值,显示 ipv4 和 ipv6 流量的默认接口,因此如果您要执行以下操作:

v4,v6 = hs.network.primaryInterfaces()

然后,假设您最关心 v4,您可以检查 hs.network.interfaceDetails(v4)["AirPort"] 是否为 nil。如果它是 nil,则说明您没有使用 WiFi 接口,如果它是一个充满 wifi 值的 table,则说明您使用的是 wifi。