Skip to content

Device Heuristics: Icon and Type Guessing

This module is responsible for inferring the most likely device type and icon based on minimal identifying data like MAC address, vendor, IP, or device name.

It does this using a set of heuristics defined in an external JSON rules file, which it evaluates in priority order.

Note

You can find the full source code of the heuristics module in the device_heuristics.py file.


JSON Rule Format

Rules are defined in a file called device_heuristics_rules.json (located under /back), structured like:

[
  {
    "dev_type": "Phone",
    "icon_html": "<i class=\"fa-brands fa-apple\"></i>",
    "matching_pattern": [
      { "mac_prefix": "001A79", "vendor": "Apple" }
    ],
    "name_pattern": ["iphone", "pixel"]
  }
]

Note

Feel free to raise a PR in case you'd like to add any rules into the device_heuristics_rules.json file. Please place new rules into the correct position and consider the priority of already available rules.

Supported fields:

Field Type Description
dev_type string Type to assign if rule matches (e.g. "Gateway", "Phone")
icon_html string Icon (HTML string) to assign if rule matches. Encoded to base64 at load time.
matching_pattern array List of { mac_prefix, vendor } objects for first strict and then loose matching
name_pattern array (optional) List of lowercase substrings (used with regex)
ip_pattern array (optional) Regex patterns to match IPs

Order in this array defines priority — rules are checked top-down and short-circuit on first match.


Matching Flow (in Priority Order)

The function guess_device_attributes(...) runs a series of matching functions in strict order:

  1. MAC + Vendor → match_mac_and_vendor()
  2. Vendor only → match_vendor()
  3. Name pattern → match_name()
  4. IP pattern → match_ip()
  5. Final fallback → defaults defined in the NEWDEV_devIcon and NEWDEV_devType settings.

Note

The app will try guessing the device type or icon if devType or devIcon are "" or "null".

Use of default values

The guessing process runs for every device as long as the current type or icon still matches the default values. Even if earlier heuristics return a match, the system continues evaluating additional clues — like name or IP — to try and replace placeholders.

# Still considered a match attempt if current values are defaults
if (not type_ or type_ == default_type) or (not icon or icon == default_icon):
    type_, icon = match_ip(ip, default_type, default_icon)

In other words: if the type or icon is still "unknown" (or matches the default), the system assumes the match isn’t final — and keeps looking. It stops only when both values are non-default (defaults are defined in the NEWDEV_devIcon and NEWDEV_devType settings).


Match Behavior (per function)

These functions are executed in the following order:

match_mac_and_vendor(mac_clean, vendor, ...)

  • Looks for MAC prefix and vendor substring match
  • Most precise
  • Stops as soon as a match is found

match_vendor(vendor, ...)

  • Falls back to substring match on vendor only
  • Ignores rules where mac_prefix is present (ensures this is really a fallback)

match_name(name, ...)

  • Lowercase name is compared against all name_pattern values using regex
  • Good for user-assigned labels (e.g. "AP Office", "iPhone")

match_ip(ip, ...)

  • If IP is present and matches regex patterns under any rule, it returns that type/icon
  • Usually used for gateways or local IP ranges

Icons

  • Each rule can define an icon_html, which is converted to a icon_base64 on load
  • If missing, it falls back to the passed-in default_icon (NEWDEV_devIcon setting)
  • If a match is found but icon is still blank, default is used

TL;DR: Type and icon must both be matched. If only one is matched, the other falls back to the default.


Priority Mechanics

  • JSON rules are evaluated top-to-bottom
  • Matching is first-hit wins — no scoring, no weights
  • Rules that are more specific (e.g. exact MAC prefixes) should be listed earlier