Skip to content

Conversation

@lockenkop
Copy link
Contributor

@lockenkop lockenkop commented Dec 26, 2023

I saw the network entity lingering in ToImplement and while wokring on that did the wifi entity first, since this was the original functionality of the network entity.

Options for configuration:

  • Linux:
    • check the interfaces output in iwconfig, it will report "no wireless extensions"
  • Windows:
    • checks for the interface name with "netsh wlan show interfaces"
    • this reports all wireless interfaces
    • output is locale dependant -.-
    • right now i check for english locale, if not raise exception and link to github for logs
  • Macos:
    • cannot test everything is more or less yolo

EntityState

  • will be in dbm on all OS
    • Windows dBm is calculated from signal percent
    • you can find the percentage value in extraAttributes

ExtraAttributes

Multiple Instances:

  • will probably remain experimental, since i can't test that easily at the time
  • if a second usb wifi adapter falls into my hands i'll have a look at it

Configuration:

  • select config
    image

Windows:
image

Linux:
image

Edgecases:
If some Information is not available it is not shown: (behaviour is the same on all OS)
image

@lockenkop lockenkop marked this pull request as draft December 26, 2023 14:22
@richibrics
Copy link
Owner

Yes I agree with setting the full path in the command

@richibrics
Copy link
Owner

richibrics commented Jan 8, 2024

We need to find a way to define a different unit for different OS in Hass: % if Windows, dBm otherwise.
It would be simpler to convert the value from % to dBm for windows too

Comment on lines 191 to 196
if OsD.IsWindows():
self.keySignalStrength = KEY_SIGNAL_STRENGTH_PERCENT
self.valueFormatterOptionsSignalStrength = VALUEFORMATTEROPTIONS_PERCENTAGE
else:
self.keySignalStrength = KEY_SIGNAL_STRENGTH_DBM
self.valueFormatterOptionsSignalStrength = VALUEFORMATTEROPTIONS_DBM
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@richibrics
Shouldnt this already do the trick?
I'll add the conversion from percent to dbm
Maybe we let the user configure if he wants percent or dbm?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
What about this?

I'd be fine with defaulting to dBm, since the signal in percent will be sent as an extra attribute in windows anyways

@infeeeee infeeeee mentioned this pull request Jan 12, 2024
30 tasks
@lockenkop lockenkop marked this pull request as ready for review January 15, 2024 14:12
Copy link
Collaborator

@infeeeee infeeeee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to find some language agnostic solution for this, this is not maintainable.

Check how this old python module works: https://github.com/awkman/pywifi

}
self.patterns = {
OsD.WINDOWS: {
"en": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this is the only way to get this data? Windows 11 has support for 110 languages, are you sure you want to write this for all of them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My intent never was to support all languages. I'll look at other ways.

KEY_SIGNAL_STRENGTH_PERCENT = "signal_strength_percent"
KEY_SIGNAL_STRENGTH_DBM = "signal_strength_dbm"

# WINDOWS
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need so much KEYS? I think the most important 5-10 would be enough (state, ssid, ip and mac address, signal level, etc.)

Take a look at the HomeAssistant mobile app, there are only 10 wifi related sensors there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reduced them to be less than 10 for each OS.
Though i just deleted some that i valued the less.

@lockenkop
Copy link
Contributor Author

@infeeeee suggested to have a look at https://github.com/awkman/pywifi. They take a better approach on getting wifi information. They utilize the ctypes module and directly communicate with windows apis.
This apporach is very powerfull but needs alot of boilerplate.
The only elegant way i see, is to include this dependency.
Changing locales on the fly is, as far as my research went, not possible.

@infeeeee
Copy link
Collaborator

The only elegant way i see, is to include this dependency.

I was also thinking about this, but that module seems not really maintained, last commit was 5 years ago, the maintainer hasn't done anything on Github since 2019. And it has a lot of features we don't need (e.g. it can connect to network). So using this as a dependency would be a bit risky and overkill.

We already use ctypes in other entities. The license of pywifi is more lax, so you can copy paste code from there.

On linux I played a bit with it. We should use iw for this, as iwconfig is part of the wireless-tools package, and that's deprecated. Here is the official docs how to replace iwconfig commands with iw: https://wireless.wiki.kernel.org/en/users/Documentation/iw/replace-iwconfig And I also found that on linux the output is always in English, regardless of the language of the system, so you shouldn't check the language there, so it's already solved. iw documentation

@lockenkop
Copy link
Contributor Author

as i was fiddling around wit pywifi i came to the same conclusion. Pywifi itself is built upon https://github.com/6e726d/PyWiWi (same boilerplate for ctypes etc.). I'll try to get a minimum working example going.

The change to iw looks pretty straightforward, having no locales to worry about is also a +.

@lockenkop lockenkop marked this pull request as draft January 22, 2024 15:31
@lockenkop
Copy link
Contributor Author

lockenkop commented Jan 27, 2024

I got a necessary minimum copied from PyWifi.
Getting all wifi interfaces works.
Querying an interface for its status (connected, connecting, disconnected, etc. ) works.

    def status(self, obj):
        """Get the wifi interface status."""

        data_size = DWORD()
        data = PDWORD()
        opcode_value_type = DWORD()
        self._wlan_query_interface(self._handle, obj['guid'], 6,
                                   byref(data_size), byref(data),
                                   byref(opcode_value_type))

        return status_dict[data.contents.value]

image
4

# Define interface status.
IFACE_DISCONNECTED = 0
IFACE_SCANNING = 1
IFACE_INACTIVE = 2
IFACE_CONNECTING = 3
IFACE_CONNECTED = 4

Querying for its rssi is giving me a headache though, my very basic c knowledge is keeping me back understanding this approach and microsofts docs.
https://learn.microsoft.com/en-us/windows/win32/api/wlanapi/nf-wlanapi-wlanqueryinterface

Keeping close to PyWifis usage above

    def rssi(self, obj):
        """Get the wifi interface status."""

        data_size = PDWORD()
        data = LONG()
        opcode_value_type = DWORD()
        self._wlan_query_interface(self._handle, obj['guid'], 23,
                                   byref(data_size), byref(data),
                                   byref(opcode_value_type))

        return data.contents.value

changing the opcode from 6 to 23
Guessing with this enum doc https://learn.microsoft.com/en-us/windows/win32/api/wlanapi/ne-wlanapi-wlan_intf_opcode-r1

This presents the following output in data.contents:
image
image
I'm stuck there, i fiddled around with datatypes and other different opcodes. I couldn't make the most sense of what i was doing and i was just guessing.

I pushed my test script if anyone wants to take a look.

@lockenkop
Copy link
Contributor Author

I'll have to drop windows support if it has to be done by calling windows apis directly. That stuff just flies right over my head.

@richibrics shall I refactor Linux and mac support into another pr? This way the beginning of the windows implementation will just remain her for someone to pickup on.

@richibrics
Copy link
Owner

Yes sounds great, I will make it working on Windows in the future

@richibrics richibrics changed the title Wifi Entity Wifi Entity for Windows Jun 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants