{
  "name": "WIFI",
  "status": "rc",
  "shortId": "wifi",
  "camelName": "wifi",
  "shortName": "wifi",
  "extends": [
    "_base"
  ],
  "notes": {
    "short": "Discovery and connection to WiFi networks. Separate TCP service can be used for data transfer.",
    "long": "## Connection\n\nThe device controlled by this service is meant to connect automatically, once configured.\nTo that end, it keeps a list of known WiFi networks, with priorities and passwords.\nIt will connect to the available network with numerically highest priority,\nbreaking ties in priority by signal strength (typically all known networks have priority of `0`).\nIf the connection fails (due to wrong password, radio failure, or other problem)\nan `connection_failed` event is emitted, and the device will try to connect to the next eligible network.\nWhen networks are exhausted, the scan is performed again and the connection process restarts.\n\nUpdating networks (setting password, priorties, forgetting) does not trigger an automatic reconnect.\n\n## Captive portals\n\nIf the Wifi is not able to join an AP because it needs to receive a password, it may decide to enter a mode\nwhere it waits for user input. Typical example of this mode would be a captive portal or waiting for a BLE interaction.\nIn that situation, the `status_code` should set to `WaitingForInput`."
  },
  "classIdentifier": 413852154,
  "enums": {
    "APFlags": {
      "name": "APFlags",
      "storage": 4,
      "isFlags": true,
      "members": {
        "HasPassword": 1,
        "WPS": 2,
        "HasSecondaryChannelAbove": 4,
        "HasSecondaryChannelBelow": 8,
        "IEEE_802_11B": 256,
        "IEEE_802_11A": 512,
        "IEEE_802_11G": 1024,
        "IEEE_802_11N": 2048,
        "IEEE_802_11AC": 4096,
        "IEEE_802_11AX": 8192,
        "IEEE_802_LongRange": 32768
      }
    }
  },
  "constants": {},
  "packets": [
    {
      "kind": "report",
      "name": "command_not_implemented",
      "identifier": 3,
      "description": "This report may be emitted by a server in response to a command (action or register operation)\nthat it does not understand.\nThe `service_command` and `packet_crc` fields are copied from the command packet that was unhandled.\nNote that it's possible to get an ACK, followed by such an error report.",
      "fields": [
        {
          "name": "service_command",
          "type": "u16",
          "storage": 2,
          "isSimpleType": true
        },
        {
          "name": "packet_crc",
          "type": "u16",
          "storage": 2,
          "isSimpleType": true
        }
      ],
      "identifierName": "command_not_implemented",
      "packFormat": "u16 u16",
      "derived": "_base"
    },
    {
      "kind": "const",
      "name": "instance_name",
      "identifier": 265,
      "description": "A friendly name that describes the role of this service instance in the device.\nIt often corresponds to what's printed on the device:\nfor example, `A` for button A, or `S0` for servo channel 0.\nWords like `left` should be avoided because of localization issues (unless they are printed on the device).",
      "fields": [
        {
          "name": "_",
          "type": "string",
          "storage": 0
        }
      ],
      "optional": true,
      "identifierName": "instance_name",
      "packFormat": "s",
      "derived": "_base"
    },
    {
      "kind": "ro",
      "name": "status_code",
      "identifier": 259,
      "description": "Reports the current state or error status of the device. ``code`` is a standardized value from \nthe Jacdac status/error codes. ``vendor_code`` is any vendor specific error code describing the device\nstate. This report is typically not queried, when a device has an error, it will typically\nadd this report in frame along with the announce packet. If a service implements this register,\nit should also support the ``status_code_changed`` event defined below.",
      "fields": [
        {
          "name": "code",
          "type": "u16",
          "storage": 2,
          "isSimpleType": true
        },
        {
          "name": "vendor_code",
          "type": "u16",
          "storage": 2,
          "isSimpleType": true
        }
      ],
      "optional": true,
      "identifierName": "status_code",
      "packFormat": "u16 u16",
      "derived": "_base"
    },
    {
      "kind": "rw",
      "name": "client_variant",
      "identifier": 9,
      "description": "An optional register in the format of a URL query string where the client can provide hints how\nthe device twin should be rendered. If the register is not implemented, the client library can simulate the register client side.",
      "fields": [
        {
          "name": "_",
          "type": "string",
          "storage": 0
        }
      ],
      "optional": true,
      "identifierName": "client_variant",
      "packFormat": "s",
      "derived": "_base"
    },
    {
      "kind": "event",
      "name": "status_code_changed",
      "identifier": 4,
      "description": "Notifies that the status code of the service changed.",
      "fields": [
        {
          "name": "code",
          "type": "u16",
          "storage": 2,
          "isSimpleType": true
        },
        {
          "name": "vendor_code",
          "type": "u16",
          "storage": 2,
          "isSimpleType": true
        }
      ],
      "optional": true,
      "identifierName": "status_code_changed",
      "packFormat": "u16 u16",
      "derived": "_base"
    },
    {
      "kind": "command",
      "name": "last_scan_results",
      "identifier": 128,
      "description": "Return list of WiFi network from the last scan.\nScans are performed periodically while not connected (in particular, on startup and after current connection drops),\nas well as upon `reconnect` and `scan` commands.",
      "fields": [
        {
          "name": "results",
          "type": "pipe",
          "storage": 12
        }
      ],
      "pipeType": "last_scan_results",
      "packFormat": "b[12]"
    },
    {
      "kind": "pipe_report",
      "name": "results",
      "identifier": 0,
      "description": "Return list of WiFi network from the last scan.\nScans are performed periodically while not connected (in particular, on startup and after current connection drops),\nas well as upon `reconnect` and `scan` commands.",
      "fields": [
        {
          "name": "flags",
          "type": "APFlags",
          "storage": 4
        },
        {
          "name": "reserved",
          "type": "u32",
          "storage": 4,
          "isSimpleType": true
        },
        {
          "name": "rssi",
          "unit": "dB",
          "type": "i8",
          "storage": -1,
          "isSimpleType": true,
          "typicalMin": -100,
          "typicalMax": -20
        },
        {
          "name": "channel",
          "type": "u8",
          "storage": 1,
          "isSimpleType": true,
          "typicalMin": 1,
          "typicalMax": 13
        },
        {
          "name": "bssid",
          "type": "u8[6]",
          "storage": 6
        },
        {
          "name": "ssid",
          "type": "string",
          "storage": 33,
          "maxBytes": 33
        }
      ],
      "pipeType": "last_scan_results",
      "packFormat": "u32 u32 i8 u8 b[6] s[33]"
    },
    {
      "kind": "command",
      "name": "add_network",
      "identifier": 129,
      "description": "Automatically connect to named network if available. Also set password if network is not open.",
      "fields": [
        {
          "name": "ssid",
          "type": "string0",
          "storage": 0
        },
        {
          "name": "password",
          "type": "string0",
          "storage": 0,
          "isOptional": true
        }
      ],
      "packFormat": "z z"
    },
    {
      "kind": "command",
      "name": "reconnect",
      "identifier": 130,
      "description": "Enable the WiFi (if disabled), initiate a scan, wait for results, disconnect from current WiFi network if any,\nand then reconnect (using regular algorithm, see `set_network_priority`).",
      "fields": []
    },
    {
      "kind": "command",
      "name": "forget_network",
      "identifier": 131,
      "description": "Prevent from automatically connecting to named network in future.\nForgetting a network resets its priority to `0`.",
      "fields": [
        {
          "name": "ssid",
          "type": "string",
          "storage": 0
        }
      ],
      "packFormat": "s"
    },
    {
      "kind": "command",
      "name": "forget_all_networks",
      "identifier": 132,
      "description": "Clear the list of known networks.",
      "fields": []
    },
    {
      "kind": "command",
      "name": "set_network_priority",
      "identifier": 133,
      "description": "Set connection priority for a network.\nBy default, all known networks have priority of `0`.",
      "fields": [
        {
          "name": "priority",
          "type": "i16",
          "storage": -2,
          "isSimpleType": true
        },
        {
          "name": "ssid",
          "type": "string",
          "storage": 0
        }
      ],
      "packFormat": "i16 s"
    },
    {
      "kind": "command",
      "name": "scan",
      "identifier": 134,
      "description": "Initiate search for WiFi networks. Generates `scan_complete` event.",
      "fields": []
    },
    {
      "kind": "command",
      "name": "list_known_networks",
      "identifier": 135,
      "description": "Return list of known WiFi networks.\n`flags` is currently always 0.",
      "fields": [
        {
          "name": "results",
          "type": "pipe",
          "storage": 12
        }
      ],
      "pipeType": "list_known_networks",
      "packFormat": "b[12]"
    },
    {
      "kind": "pipe_report",
      "name": "network_results",
      "identifier": 0,
      "description": "Return list of known WiFi networks.\n`flags` is currently always 0.",
      "fields": [
        {
          "name": "priority",
          "type": "i16",
          "storage": -2,
          "isSimpleType": true
        },
        {
          "name": "flags",
          "type": "i16",
          "storage": -2,
          "isSimpleType": true
        },
        {
          "name": "ssid",
          "type": "string",
          "storage": 0
        }
      ],
      "pipeType": "list_known_networks",
      "packFormat": "i16 i16 s"
    },
    {
      "kind": "ro",
      "name": "rssi",
      "identifier": 257,
      "description": "Current signal strength. Returns -128 when not connected.",
      "fields": [
        {
          "name": "_",
          "unit": "dB",
          "type": "i8",
          "storage": -1,
          "isSimpleType": true,
          "typicalMin": -128,
          "typicalMax": -20
        }
      ],
      "volatile": true,
      "identifierName": "reading",
      "preferredInterval": 15000,
      "packFormat": "i8"
    },
    {
      "kind": "rw",
      "name": "enabled",
      "identifier": 1,
      "description": "Determines whether the WiFi radio is enabled. It starts enabled upon reset.",
      "fields": [
        {
          "name": "_",
          "type": "bool",
          "storage": 1
        }
      ],
      "identifierName": "intensity",
      "packFormat": "u8"
    },
    {
      "kind": "ro",
      "name": "ip_address",
      "identifier": 385,
      "description": "0, 4 or 16 byte buffer with the IPv4 or IPv6 address assigned to device if any.",
      "fields": [
        {
          "name": "_",
          "type": "bytes",
          "storage": 16,
          "isSimpleType": true,
          "maxBytes": 16
        }
      ],
      "packFormat": "b[16]"
    },
    {
      "kind": "const",
      "name": "eui_48",
      "identifier": 386,
      "description": "The 6-byte MAC address of the device. If a device does MAC address randomization it will have to \"restart\".",
      "fields": [
        {
          "name": "_",
          "type": "bytes",
          "storage": 6,
          "isSimpleType": true,
          "maxBytes": 6
        }
      ],
      "packFormat": "b[6]"
    },
    {
      "kind": "ro",
      "name": "ssid",
      "identifier": 387,
      "description": "SSID of the access-point to which device is currently connected.\nEmpty string if not connected.",
      "fields": [
        {
          "name": "_",
          "type": "string",
          "storage": 32,
          "maxBytes": 32
        }
      ],
      "packFormat": "s[32]"
    },
    {
      "kind": "event",
      "name": "got_ip",
      "identifier": 1,
      "description": "Emitted upon successful join and IP address assignment.",
      "fields": [],
      "identifierName": "active"
    },
    {
      "kind": "event",
      "name": "lost_ip",
      "identifier": 2,
      "description": "Emitted when disconnected from network.",
      "fields": [],
      "identifierName": "inactive"
    },
    {
      "kind": "event",
      "name": "scan_complete",
      "identifier": 128,
      "description": "A WiFi network scan has completed. Results can be read with the `last_scan_results` command.\nThe event indicates how many networks where found, and how many are considered\nas candidates for connection.",
      "fields": [
        {
          "name": "num_networks",
          "type": "u16",
          "storage": 2,
          "isSimpleType": true
        },
        {
          "name": "num_known_networks",
          "type": "u16",
          "storage": 2,
          "isSimpleType": true
        }
      ],
      "packFormat": "u16 u16"
    },
    {
      "kind": "event",
      "name": "networks_changed",
      "identifier": 129,
      "description": "Emitted whenever the list of known networks is updated.",
      "fields": []
    },
    {
      "kind": "event",
      "name": "connection_failed",
      "identifier": 130,
      "description": "Emitted when when a network was detected in scan, the device tried to connect to it\nand failed.\nThis may be because of wrong password or other random failure.",
      "fields": [
        {
          "name": "ssid",
          "type": "string",
          "storage": 0
        }
      ],
      "packFormat": "s"
    }
  ],
  "tags": [],
  "group": "Iot"
}