GitBook: [master] 333 pages modified

This commit is contained in:
Daniel Spindelbauer
2018-09-19 15:38:13 +00:00
committed by gitbook-bot
parent 260e81c8e8
commit 015fdc88ef
170 changed files with 296 additions and 296 deletions

View File

@@ -1,4 +0,0 @@
# network
This module provides access to network drivers and routing configuration. Network drivers for specific hardware are available within this module and are used to configure specific hardware network interfaces.

View File

@@ -1,249 +0,0 @@
# Bluetooth
This class provides a driver for the Bluetooth radio in the module. Currently, only basic BLE functionality is available.
## Quick Usage Example
```python
from network import Bluetooth
import time
bt = Bluetooth()
bt.start_scan(-1)
while True:
adv = bt.get_adv()
if adv and bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'Heart Rate':
try:
conn = bt.connect(adv.mac)
services = conn.services()
for service in services:
time.sleep(0.050)
if type(service.uuid()) == bytes:
print('Reading chars from service = {}'.format(service.uuid()))
else:
print('Reading chars from service = %x' % service.uuid())
chars = service.characteristics()
for char in chars:
if (char.properties() & Bluetooth.PROP_READ):
print('char {} value = {}'.format(char.uuid(), char.read()))
conn.disconnect()
break
except:
print("Error while connecting or reading from the BLE device")
break
else:
time.sleep(0.050)
```
## Bluetooth Low Energy \(BLE\)
Bluetooth low energy \(BLE\) is a subset of classic Bluetooth, designed for easy connecting and communicating between devices \(in particular mobile platforms\). BLE uses a methodology known as Generic Access Profile \(GAP\) to control connections and advertising.
GAP allows for devices to take various roles but generic flow works with devices that are either a Server \(low power, resource constrained, sending small payloads of data\) or a Client device \(commonly a mobile device, PC or Pycom Device with large resources and processing power\). Pycom devices can act as both a Client and a Server.
## Constructors
#### class network.Bluetooth\(id=0, ...\)
Create a Bluetooth object, and optionally configure it. See init for params of configuration.
Example:
```python
from network import Bluetooth
bluetooth = Bluetooth()
```
## Methods
#### bluetooth.init\(id=0, mode=Bluetooth.BLE, antenna=None\)
* `id` Only one Bluetooth peripheral available so must always be 0
* `mode` currently the only supported mode is `Bluetooth.BLE`
* `antenna` selects between the internal and the external antenna. Can be either
`Bluetooth.INT_ANT`, `Bluetooth.EXT_ANT`.
With our development boards it defaults to using the internal antenna, but in
the case of an OEM module, the antenna pin \(`P12`\) is not used, so its free to be
used for other things.
Initialises and enables the Bluetooth radio in BLE mode.
#### bluetooth.deinit\(\)
Disables the Bluetooth radio.
#### bluetooth.start\_scan\(timeout\)
Starts performing a scan listening for BLE devices sending advertisements. This function always returns immediately, the scanning will be performed on the background. The return value is `None`. After starting the scan the function `get_adv()` can be used to retrieve the advertisements messages from the FIFO. The internal FIFO has space to cache 16 advertisements.
The arguments are:
* `timeout` specifies the amount of time in seconds to scan for advertisements, cannot be zero. If timeout is > 0, then the BLE radio will listen for advertisements until the specified value in seconds elapses. If timeout < 0, then theres no timeout at all, and stop\_scan\(\) needs to be called to cancel the scanning process.
Examples:
```python
bluetooth.start_scan(10) # starts scanning and stop after 10 seconds
bluetooth.start_scan(-1) # starts scanning indefinitely until bluetooth.stop_scan() is called
```
#### bluetooth.stop\_scan\(\)
Stops an ongoing scanning process. Returns `None`.
#### bluetooth.isscanning\(\)
Returns `True` if a Bluetooth scan is in progress. `False` otherwise.
#### bluetooth.get\_adv\(\)
Gets an named tuple with the advertisement data received during the scanning. The tuple has the following structure: `(mac, addr_type, adv_type, rssi, data)`
* `mac` is the 6-byte ling mac address of the device that sent the advertisement.
* `addr_type` is the address type. See the constants section below for more details.
* `adv_type` is the advertisement type received. See the constants section below fro more details.
* `rssi` is signed integer with the signal strength of the advertisement.
* `data` contains the complete 31 bytes of the advertisement message. In order to parse the data and get the specific types, the method `resolve_adv_data()` can be used.
Example for getting `mac` address of an advertiser:
```python
import ubinascii
bluetooth = Bluetooth()
bluetooth.start_scan(20) # scan for 20 seconds
adv = bluetooth.get_adv() #
ubinascii.hexlify(adv.mac) # convert hexadecimal to ascii
```
#### bluetooth.get\_advertisements\(\)
Same as the `get_adv()` method, but this one returns a list with all the advertisements received.
#### bluetooth.resolve\_adv\_data\(data, data\_type\)
Parses the advertisement data and returns the requested `data_type` if present. If the data type is not present, the function returns `None`.
Arguments:
* `data` is the bytes object with the complete advertisement data.
* `data_type` is the data type to resolve from from the advertisement data. See constants section below for details.
Example:
```python
import ubinascii
from network import Bluetooth
bluetooth = Bluetooth()
bluetooth.start_scan(20)
while bluetooth.isscanning():
adv = bluetooth.get_adv()
if adv:
# try to get the complete name
print(bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL))
mfg_data = bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_MANUFACTURER_DATA)
if mfg_data:
# try to get the manufacturer data (Apple's iBeacon data is sent here)
print(ubinascii.hexlify(mfg_data))
```
#### bluetooth.connect\(mac\_addr\)
Opens a BLE connection with the device specified by the `mac_addr` argument. This function blocks until the connection succeeds or fails. If the connections succeeds it returns a object of type `GATTCConnection`.
```python
bluetooth.connect('112233eeddff') # mac address is accepted as a string
```
#### bluetooth.callback\(trigger=None, handler=None, arg=None\)
Creates a callback that will be executed when any of the triggers occurs. The arguments are:
* `trigger` can be either `Bluetooth.NEW_ADV_EVENT`, `Bluetooth.CLIENT_CONNECTED`, or `Bluetooth.CLIENT_DISCONNECTED`
* `handler` is the function that will be executed when the callback is triggered.
* `arg` is the argument that gets passed to the callback. If nothing is given the bluetooth object itself is used.
An example of how this may be used can be seen in the [`bluetooth.events()`](./#bluetooth-events) method.
#### bluetooth.events\(\)
Returns a value with bit flags identifying the events that have occurred since the last call. Calling this function clears the events.
Example of usage:
```python
from network import Bluetooth
bluetooth = Bluetooth()
bluetooth.set_advertisement(name='LoPy', service_uuid=b'1234567890123456')
def conn_cb (bt_o):
events = bt_o.events() # this method returns the flags and clears the internal registry
if events & Bluetooth.CLIENT_CONNECTED:
print("Client connected")
elif events & Bluetooth.CLIENT_DISCONNECTED:
print("Client disconnected")
bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb)
bluetooth.advertise(True)
```
#### bluetooth.set\_advertisement\(\* , name=None, manufacturer\_data=None, service\_data=None, service\_uuid=None\)
Configure the data to be sent while advertising. If left with the default of `None` the data wont be part of the advertisement message.
The arguments are:
* `name` is the string name to be shown on advertisements.
* `manufacturer_data` manufacturer data to be advertised \(hint: use it for iBeacons\).
* `service_data` service data to be advertised.
* `service_uuid` uuid of the service to be advertised.
Example:
```python
bluetooth.set_advertisement(name="advert", manufacturer_data="lopy_v1")
```
#### bluetooth.advertise\(\[Enable\]\)
Start or stop sending advertisements. The `set_advertisement()` method must have been called prior to this one.
#### bluetooth.service\(uuid, \* , isprimary=True, nbr\_chars=1, start=True\)
Create a new service on the internal GATT server. Returns a object of type `BluetoothServerService`.
The arguments are:
* `uuid` is the UUID of the service. Can take an integer or a 16 byte long string or bytes object.
* `isprimary` selects if the service is a primary one. Takes a `bool` value.
* `nbr_chars` specifies the number of characteristics that the service will contain.
* `start` if `True` the service is started immediately.
```python
bluetooth.service('abc123')
```
#### bluetooth.disconnect\_client\(\)
Closes the BLE connection with the client.
## Constants
* Bluetooth mode: `Bluetooth.BLE`
* Advertisement type: `Bluetooth.CONN_ADV`, `Bluetooth.CONN_DIR_ADV`, `Bluetooth.DISC_ADV`, `Bluetooth.NON_CONN_ADV`, `Bluetooth.SCAN_RSP`
* Address type: `Bluetooth.PUBLIC_ADDR`, `Bluetooth.RANDOM_ADDR`, `Bluetooth.PUBLIC_RPA_ADDR`, `Bluetooth.RANDOM_RPA_ADDR`
* Advertisement data type: `Bluetooth.ADV_FLAG`, `Bluetooth.ADV_16SRV_PART`, `Bluetooth.ADV_T16SRV_CMPL`, `Bluetooth.ADV_32SRV_PART`, `Bluetooth.ADV_32SRV_CMPL`, `Bluetooth.ADV_128SRV_PART`, `Bluetooth.ADV_128SRV_CMPL`, `Bluetooth.ADV_NAME_SHORT`, `Bluetooth.ADV_NAME_CMPL`, `Bluetooth.ADV_TX_PWR`, `Bluetooth.ADV_DEV_CLASS`, `Bluetooth.ADV_SERVICE_DATA`, `Bluetooth.ADV_APPEARANCE`, `Bluetooth.ADV_ADV_INT`, `Bluetooth.ADV_32SERVICE_DATA`, `Bluetooth.ADV_128SERVICE_DATA`, `Bluetooth.ADV_MANUFACTURER_DATA`
* Characteristic properties \(bit values that can be combined\): `Bluetooth.PROP_BROADCAST`, `Bluetooth.PROP_READ`, `Bluetooth.PROP_WRITE_NR`, `Bluetooth.PROP_WRITE`, `Bluetooth.PROP_NOTIFY`, `Bluetooth.PROP_INDICATE`, `Bluetooth.PROP_AUTH`, `Bluetooth.PROP_EXT_PROP`
* Characteristic callback events: `Bluetooth.CHAR_READ_EVENT`, `Bluetooth.CHAR_WRITE_EVENT`, `Bluetooth.NEW_ADV_EVENT`, `Bluetooth.CLIENT_CONNECTED`, `Bluetooth.CLIENT_DISCONNECTED`, `Bluetooth.CHAR_NOTIFY_EVENT`
* Antenna type: `Bluetooth.INT_ANT`, `Bluetooth.EXT_ANT`

View File

@@ -1,8 +0,0 @@
# GATT
GATT stands for the Generic Attribute Profile and it defines the way that two Bluetooth Low Energy devices communicate between each other using concepts called Services and Characteristics. GATT uses a data protocol known as the Attribute Protocol \(ATT\), which is used to store/manage Services, Characteristics and related data in a lookup table.
GATT comes into use once a connection is established between two devices, meaning that the device will have already gone through the advertising process managed by GAP. Its important to remember that this connection is exclusive; i.e. that only one client is connected to one server at a time. This means that the client will stop advertising once a connection has been made. This remains the case, until the connection is broken or disconnected.
The GATT Server, which holds the ATT lookup data and service and characteristic definitions, and the GATT Client \(the phone/tablet\), which sends requests to this server.

View File

@@ -1,44 +0,0 @@
# GATTCCharacteristic
The smallest concept in GATT is the Characteristic, which encapsulates a single data point \(though it may contain an array of related data, such as X/Y/Z values from a 3-axis accelerometer, longitude and latitude from a GPS, etc.\).
The following class allows you to manage characteristics from a Client.
## Methods
#### characteristic.uuid\(\)
Returns the UUID of the service. In the case of 16-bit or 32-bit long UUIDs, the value returned is an integer, but for 128-bit long UUIDs the value returned is a bytes object.
#### characteristic.instance\(\)
Returns the instance ID of the service.
#### characteristic.properties\(\)
Returns an integer indicating the properties of the characteristic. Properties are represented by bit values that can be OR-ed together. See the constants section for more details.
#### characteristic.read\(\)
Read the value of the characteristic, sending a request to the GATT server. Returns a bytes object representing the characteristic value.
#### characteristic.value\(\)
Returns the locally stored value of the characteristic without sending a read request to the GATT server. If the characteristic value hasn't been read from the GATT server yet, the value returned will be 0.
#### characteristic.write\(value\)
Writes the given value on the characteristic. For now it only accepts bytes object representing the value to be written.
```python
characteristic.write(b'x0f')
```
#### characteristic.callback\(trigger=None, handler=None, arg=None\)
This method allows to register for notifications on the characteristic.
* `trigger` can must be `Bluetooth.CHAR_NOTIFY_EVENT`.
* `handler` is the function that will be executed when the callback is triggered.
* `arg` is the argument that gets passed to the callback. If nothing is given, the characteristic object that owns the callback will be used.

View File

@@ -1,51 +0,0 @@
# GATTCConnection
The GATT Client is the device that requests data from the server, otherwise known as the master device \(commonly this might be a phone/tablet/PC\). All transactions are initiated by the master, which receives a response from the slave.
## Methods
#### connection.disconnect\(\)
Closes the BLE connection. Returns `None`.
#### connection.isconnected\(\)
Returns `True` if the connection is still open. `False` otherwise.
Example:
```python
from network import Bluetooth
import ubinascii
bluetooth = Bluetooth()
# scan until we can connect to any BLE device around
bluetooth.start_scan(-1)
adv = None
while True:
adv = bluetooth.get_adv()
if adv:
try:
bluetooth.connect(adv.mac)
except:
# start scanning again
bluetooth.start_scan(-1)
continue
break
print("Connected to device with addr = {}".format(ubinascii.hexlify(adv.mac)))
```
#### connection.services\(\)
Performs a service search on the connected BLE peripheral \(server\) a returns a list containing objects of the class GATTCService if the search succeeds.
Example:
```python
# assuming that a BLE connection is already open
services = connection.services()
print(services)
for service in services:
print(service.uuid())
```

View File

@@ -1,24 +0,0 @@
# GATTCService
Services are used to categorise data up into specific chunks of data known as characteristics. A service may have multiple characteristics, and each service has a unique numeric ID called a UUID.
The following class allows control over Client services.
## Methods
#### service.isprimary\(\)
Returns `True` if the service is a primary one. `False` otherwise.
#### service.uuid\(\)
Returns the UUID of the service. In the case of 16-bit or 32-bit long UUIDs, the value returned is an integer, but for 128-bit long UUIDs the value returned is a bytes object.
#### service.instance\(\)
Returns the instance ID of the service.
#### service.characteristics\(\)
Performs a get characteristics request on the connected BLE peripheral a returns a list containing objects of the class GATTCCharacteristic if the request succeeds.

View File

@@ -1,83 +0,0 @@
# GATTSCharacteristic
The smallest concept in GATT is the Characteristic, which encapsulates a single data point \(though it may contain an array of related data, such as X/Y/Z values from a 3-axis accelerometer, longitude and latitude from a GPS, etc.\).
The following class allows you to manage Server characteristics.
## Methods
#### characteristic.value\(\[value\]\)
Gets or sets the value of the characteristic. Can take an integer, a string or a bytes object.
```python
characteristic.value(123) # set characteristic value to an integer with the value 123
characteristic.value() # get characteristic value
```
#### characteristic.callback\(trigger=None, handler=None, arg=None\)
Creates a callback that will be executed when any of the triggers occurs. The arguments are:
* `trigger` can be either `Bluetooth.CHAR_READ_EVENT` or `Bluetooth.CHAR_WRITE_EVENT`.
* `handler` is the function that will be executed when the callback is triggered.
* `arg` is the argument that gets passed to the callback. If nothing is given, the characteristic object that owns the callback will be used.
An example of how this could be implemented can be seen in the [`characteristic.events()` ](gattscharacteristic.md#characteristic-events)section.
#### characteristic.events\(\)
Returns a value with bit flags identifying the events that have occurred since the last call. Calling this function clears the events.
An example of advertising and creating services on the device:
```python
from network import Bluetooth
bluetooth = Bluetooth()
bluetooth.set_advertisement(name='LoPy', service_uuid=b'1234567890123456')
def conn_cb (bt_o):
events = bt_o.events()
if events & Bluetooth.CLIENT_CONNECTED:
print("Client connected")
elif events & Bluetooth.CLIENT_DISCONNECTED:
print("Client disconnected")
bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb)
bluetooth.advertise(True)
srv1 = bluetooth.service(uuid=b'1234567890123456', isprimary=True)
chr1 = srv1.characteristic(uuid=b'ab34567890123456', value=5)
char1_read_counter = 0
def char1_cb_handler(chr):
global char1_read_counter
char1_read_counter += 1
events = chr.events()
if events & Bluetooth.CHAR_WRITE_EVENT:
print("Write request with value = {}".format(chr.value()))
else:
if char1_read_counter < 3:
print('Read request on char 1')
else:
return 'ABC DEF'
char1_cb = chr1.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=char1_cb_handler)
srv2 = bluetooth.service(uuid=1234, isprimary=True)
chr2 = srv2.characteristic(uuid=4567, value=0x1234)
char2_read_counter = 0xF0
def char2_cb_handler(chr):
global char2_read_counter
char2_read_counter += 1
if char2_read_counter > 0xF1:
return char2_read_counter
char2_cb = chr2.callback(trigger=Bluetooth.CHAR_READ_EVENT, handler=char2_cb_handler)
```

View File

@@ -1,31 +0,0 @@
# GATTSService
The GATT Server allows the device to act as a peripheral and hold its own ATT lookup data, server & characteristic definitions. In this mode, the device acts as a slave and a master must initiate a request.
Services are used to categorise data up into specific chunks of data known as characteristics. A service may have multiple characteristics, and each service has a unique numeric ID called a UUID.
The following class allows control over Server services.
## Methods
#### service.start\(\)
Starts the service if not already started.
#### service.stop\(\)
Stops the service if previously started.
#### service.characteristic\(uuid, \* , permissions, properties, value\)
Creates a new characteristic on the service. Returns an object of the class `GATTSCharacteristic`. The arguments are:
* `uuid` is the UUID of the service. Can take an integer or a 16 byte long string or bytes object.
* `permissions` configures the permissions of the characteristic. Takes an integer with a combination of the flags.
* `properties` sets the properties. Takes an integer with an OR-ed combination of the flags.
* `value` sets the initial value. Can take an integer, a string or a bytes object.
```python
service.characteristic('temp', value=25)
```

View File

@@ -1,486 +0,0 @@
# LoRa
This class provides a LoRaWAN 1.0.2 compliant driver for the LoRa network processor in the LoPy and FiPy. Below is an example demonstrating LoRaWAN Activation by Personalisation usage:
```python
from network import LoRa
import socket
import ubinascii
import struct
# Initialise LoRa in LORAWAN mode.
# Please pick the region that matches where you are using the device:
# Asia = LoRa.AS923
# Australia = LoRa.AU915
# Europe = LoRa.EU868
# United States = LoRa.US915
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
# create an ABP authentication params
dev_addr = struct.unpack(">l", binascii.unhexlify('00000005'))[0]
nwk_swkey = ubinascii.unhexlify('2B7E151628AED2A6ABF7158809CF4F3C')
app_swkey = ubinascii.unhexlify('2B7E151628AED2A6ABF7158809CF4F3C')
# join a network using ABP (Activation By Personalisation)
lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))
# create a LoRa socket
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
# set the LoRaWAN data rate
s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
# make the socket non-blocking
s.setblocking(False)
# send some data
s.send(bytes([0x01, 0x02, 0x03]))
# get any data received...
data = s.recv(64)
print(data)
```
{% hint style="danger" %}
Please ensure that there is an antenna connected to your device before sending/receiving LoRa messages as improper use \(e.g. without an antenna\), may damage the device.
{% endhint %}
## Additional Examples
For various other complete LoRa examples, check here for additional examples.
## Constructors
#### class network.LoRa\(id=0, ...\)
Create and configure a LoRa object. See init for params of configuration.
```python
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
```
## Methods
#### lora.init\(mode, \* ,region=LoRa.EU868, frequency=868000000, tx\_power=14, bandwidth=LoRa.BW\_125KHZ, sf=7, preamble=8, coding\_rate=LoRa.CODING\_4\_5, power\_mode=LoRa.ALWAYS\_ON, tx\_iq=False, rx\_iq=False, adr=False, public=True, tx\_retries=1, device\_class=LoRa.CLASS\_A\)
This method is used to set the LoRa subsystem configuration and to specific raw LoRa or LoRaWAN.
The arguments are:
* `mode` can be either `LoRa.LORA` or `LoRa.LORAWAN`.
* `region` can take the following values: `LoRa.AS923`, `LoRa.AU915`, `LoRa.EU868` or `LoRa.US915`. If not provided this will default to `LoRaEU868`. If they are not specified, this will also set appropriate defaults for `frequency` and `tx_power`.
* `frequency` accepts values between `863000000` and `870000000` in the 868 band, or between `902000000` and `928000000` in the 915 band.
* `tx_power` is the transmit power in dBm. It accepts between 2 and 14 for the 868 band, and between 5 and 20 in the 915 band.
* `bandwidth` is the channel bandwidth in KHz. In the 868 band the accepted values are `LoRa.BW_125KHZ` and `LoRa.BW_250KHZ`. In the 915 band the accepted values are `LoRa.BW_125KHZ` and `LoRa.BW_500KHZ`.
* `sf` sets the desired spreading factor. Accepts values between 7 and 12.
* `preamble` configures the number of pre-amble symbols. The default value is 8.
* `coding_rate` can take the following values: `LoRa.CODING_4_5`, `LoRa.CODING_4_6`, `LoRa.CODING_4_7` or `LoRa.CODING_4_8`.
* `power_mode` can be either `LoRa.ALWAYS_ON`, `LoRa.TX_ONLY` or `LoRa.SLEEP`. In `ALWAYS_ON` mode, the radio is always listening for incoming - packets whenever a transmission is not taking place. In `TX_ONLY` the radio goes to sleep as soon as the transmission completes. In `SLEEP` mode the radio is sent to sleep permanently and wont accept any commands until the power mode is changed.
* `tx_iq` enables TX IQ inversion.
* `rx_iq` enables RX IQ inversion.
* `adr` enables Adaptive Data Rate.
* `public` selects between the public and private sync word.
* `tx_retries` sets the number of TX retries in `LoRa.LORAWAN` mode.
* `device_class` sets the LoRaWAN device class. Can be either `LoRa.CLASS_A` or `LoRa.CLASS_C`.
{% hint style="info" %}
In `LoRa.LORAWAN` mode, only `adr`, `public`, `tx_retries` and `device_class` are used. All the other params will be ignored as they are handled by the LoRaWAN stack directly. On the other hand, in `LoRa.LORA` mode from those 4 arguments, only the public one is important in order to program the sync word. In `LoRa.LORA` mode `adr`, `tx_retries` and `device_class` are ignored since they are only relevant to the LoRaWAN stack.
{% endhint %}
For example, you can do:
```python
# initialize in raw LoRa mode
lora.init(mode=LoRa.LORA, tx_power=14, sf=12)
```
or
```python
# initialize in LoRaWAN mode
lora.init(mode=LoRa.LORAWAN)
```
#### lora.join\(activation, auth, \* ,timeout=None, dr=None\)
Join a LoRaWAN network. Internally the stack will automatically retry every 15 seconds until a Join Accept message is received.
The parameters are:
* `activation`: can be either `LoRa.OTAA` or `LoRa.ABP`.
* `auth`: is a tuple with the authentication data.
* `timeout`: is the maximum time in milliseconds to wait for the Join Accept message to be received. If no timeout \(or zero\) is given, the call returns immediately and the status of the join request can be checked with `lora.has_joined()`.
* `dr`: is an optional value to specify the initial data rate for the Join Request. Possible values are 0 to 5 for **EU868**, or 0 to 4 for **US915**.
In the case of `LoRa.OTAA` the authentication tuple is: `(dev_eui, app_eui, app_key)` where `dev_eui` is optional. If it is not provided the LoRa MAC will be used. Therefore, you can do OTAA in 2 different ways:
```python
lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0) # the device MAC address is used as DEV_EUI
```
or
```python
lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0) # a custom DEV_EUI is specified
```
Example:
```python
from network import LoRa
import socket
import time
import ubinascii
# Initialise LoRa in LORAWAN mode.
# Please pick the region that matches where you are using the device:
# Asia = LoRa.AS923
# Australia = LoRa.AU915
# Europe = LoRa.EU868
# United States = LoRa.US915
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
# create an OTAA authentication parameters
app_eui = ubinascii.unhexlify('ADA4DAE3AC12676B')
app_key = ubinascii.unhexlify('11B0282A189B75B0B4D2D8C7FA38548B')
# join a network using OTAA (Over the Air Activation)
lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0)
# wait until the module has joined the network
while not lora.has_joined():
time.sleep(2.5)
print('Not yet joined...')
```
In the case of `LoRa.ABP` the authentication tuple is: `(dev_addr, nwk_swkey, app_swkey)`. Example:
```python
from network import LoRa
import socket
import ubinascii
import struct
# Initialise LoRa in LORAWAN mode.
# Please pick the region that matches where you are using the device:
# Asia = LoRa.AS923
# Australia = LoRa.AU915
# Europe = LoRa.EU868
# United States = LoRa.US915
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
# create an ABP authentication params
dev_addr = struct.unpack(">l", ubinascii.unhexlify('00000005'))[0]
nwk_swkey = ubinascii.unhexlify('2B7E151628AED2A6ABF7158809CF4F3C')
app_swkey = ubinascii.unhexlify('2B7E151628AED2A6ABF7158809CF4F3C')
# join a network using ABP (Activation By Personalisation)
lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))
```
#### lora.bandwidth\(\[bandwidth\]\)
Get or set the bandwidth in raw LoRa mode \(`LoRa.LORA`\). Can be either `LoRa.BW_125KHZ` \(0\), `LoRa.BW_250KHZ` \(1\) or `LoRa.BW_500KHZ` \(2\):
```python
# get raw LoRa Bandwidth
lora.bandwidth()
# set raw LoRa Bandwidth
lora.bandwidth(LoRa.BW_125KHZ)
```
#### lora.frequency\(\[frequency\]\)
Get or set the frequency in raw LoRa mode \(`LoRa.LORA`\). The allowed range is between `863000000` and `870000000` Hz for the 868 MHz band version or between `902000000` and `928000000` Hz for the 915 MHz band version.
```python
# get raw LoRa Frequency
lora.frequency()
# set raw LoRa Frequency
lora.frequency(868000000)
```
#### lora.coding\_rate\(\[coding\_rate\]\)
Get or set the coding rate in raw LoRa mode \(`LoRa.LORA`\). The allowed values are: `LoRa.CODING_4_5` \(1\), `LoRa.CODING_4_6` \(2\), `LoRa.CODING_4_7` \(3\) and `LoRa.CODING_4_8` \(4\).
```python
# get raw LoRa Coding Rate
lora.coding_rate()
# set raw LoRa Coding Rate
lora.coding_rate(LoRa.CODING_4_5)
```
#### lora.preamble\(\[preamble\]\)
Get or set the number of preamble symbols in raw LoRa mode \(`LoRa.LORA`\):
```python
# get raw LoRa preamble symbols
lora.preamble()
# set raw LoRa preamble symbols
lora.preamble(LoRa.CODING_4_5)
```
#### lora.sf\(\[sf\]\)
Get or set the spreading factor value in raw LoRa mode \(`LoRa.LORA`\). The minimum value is 7 and the maximum is 12:
```python
# get raw LoRa spread factor value
lora.sf()
# set raw LoRa spread factor value
lora.sf(7)
```
#### lora.power\_mode\(\[power\_mode\]\)
Get or set the power mode in raw LoRa mode \(`LoRa.LORA`\). The accepted values are: `LoRa.ALWAYS_ON`, `LoRa.TX_ONLY`, and `LoRa.SLEEP`:
#### lora.stats\(\)
Return a named tuple with useful information from the last received LoRa or LoRaWAN packet. The named tuple has the following form:
`(rx_timestamp, rssi, snr, sftx, sfrx, tx_trials, tx_power, tx_time_on_air, tx_counter, tx_frequency)`
Example:
```python
lora.stats()
```
Where:
* `rx_timestamp` is an internal timestamp of the last received packet with microseconds precision.
* `rssi` holds the received signal strength in dBm.
* `snr` contains the signal to noise ratio id dB \(as a single precision float\).
* `sfrx` tells the data rate \(in the case of LORAWAN mode\) or the spreading factor \(in the case of LORA mode\) of the last packet received.
* `sftx` tells the data rate \(in the case of LORAWAN mode\) or the spreading factor \(in the case of LORA mode\) of the last packet transmitted.
* `tx_trials` is the number of tx attempts of the last transmitted packet \(only relevant for LORAWAN confirmed packets\).
* `tx_power` is the power of the last transmission \(in dBm\).
* `tx_time_on_air` is the time on air of the last transmitted packet \(in ms\).
* `tx_counter` is the number of packets transmitted.
* `tx_frequency` is the frequency used for the last transmission.
#### lora.has\_joined\(\)
Returns `True` if a LoRaWAN network has been joined. `False` otherwise.
#### lora.add\_channel\(index, \* , frequency, dr\_min, dr\_max\)
Add a LoRaWAN channel on the specified `index`. If theres already a channel with that index it will be replaced with the new one.
The arguments are:
* `index`: Index of the channel to add. Accepts values between 0 and 15 for EU and between 0 and 71 for US.
* `frequency`: Centre frequency in Hz of the channel.
* `dr_min`: Minimum data rate of the channel \(0-7\).
* `dr_max`: Maximum data rate of the channel \(0-7\).
Examples:
```python
lora.add_channel(index=0, frequency=868000000, dr_min=5, dr_max=6)
```
#### lora.remove\_channel\(index\)
Removes the channel from the specified `index`. On the 868MHz band the channels 0 to 2 cannot be removed, they can only be replaced by other channels using the `lora.add_channel` method. A way to remove all channels except for one is to add the same channel, 3 times on indexes 0, 1 and 2. An example can be seen below:
```python
lora.remove_channel()
```
On the 915MHz band there are no restrictions around this.
#### lora.mac\(\)
Returns a byte object with the 8-Byte MAC address of the LoRa radio.
#### lora.callback\(trigger, handler=None, arg=None\)
Specify a callback handler for the LoRa radio. The `trigger` types are `LoRa.RX_PACKET_EVENT`, `LoRa.TX_PACKET_EVENT`, and `LoRa.TX_FAILED_EVENT`
The `LoRa.RX_PACKET_EVENT` event is raised for every received packet. The `LoRa.TX_PACKET_EVENT` event is raised as soon as the packet transmission cycle ends, which includes the end of the receive windows \(even if a downlink is received, the `LoRa.TX_PACKET_EVENT` will come last\). In the case of non-confirmed transmissions, this will occur at the end of the receive windows, but, in the case of confirmed transmissions, this event will only be raised if the `ack` is received. If the `ack` is not received `LoRa.TX_FAILED_EVENT` will be raised after the number of `tx_retries` configured have been performed.
An example of how this callback functions can be seen the in method [`lora.events()`](lora.md#lora-events).
#### lora.ischannel\_free\(rssi\_threshold\)
This method is used to check for radio activity on the current LoRa channel, and if the `rssi` of the measured activity is lower than the `rssi_threshold` given, the return value will be `True`, otherwise `False`. Example:
```python
lora.ischannel_free(-100)
```
#### lora.set\_battery\_level\(level\)
Set the battery level value that will be sent when the LoRaWAN MAC command that retrieves the battery level is received. This command is sent by the network and handled automatically by the LoRaWAN stack. The values should be according to the LoRaWAN specification:
* `0` means that the end-device is connected to an external power source.
* `1..254` specifies the battery level, 1 being at minimum and 254 being at maximum.
* `255` means that the end-device was not able to measure the battery level.
```python
lora.set_battery_level(127) # 50% battery
```
#### lora.events\(\)
This method returns a value with bits sets \(if any\) indicating the events that have triggered the callback. Please note that by calling this function the internal events registry is cleared automatically, therefore calling it immediately for a second time will most likely return a value of 0.
Example:
```python
def lora_cb(lora):
events = lora.events()
if events & LoRa.RX_PACKET_EVENT:
print('Lora packet received')
if events & LoRa.TX_PACKET_EVENT:
print('Lora packet sent')
lora.callback(trigger=(LoRa.RX_PACKET_EVENT | LoRa.TX_PACKET_EVENT), handler=lora_cb)
```
#### lora.nvram\_save\(\)
Save the LoRaWAN state \(joined status, network keys, packet counters, etc\) in non-volatile memory in order to be able to restore the state when coming out of deepsleep or a power cycle.
```python
lora.nvram_save()
```
#### lora.nvram\_restore\(\)
Restore the LoRaWAN state \(joined status, network keys, packet counters, etc\) from non-volatile memory. State must have been previously stored with a call to `nvram_save` before entering deepsleep. This is useful to be able to send a LoRaWAN message immediately after coming out of deepsleep without having to join the network again. This can only be used if the current region matches the one saved.
```python
lora.nvram_restore()
```
#### lora.nvram\_erase\(\)
Remove the LoRaWAN state \(joined status, network keys, packet counters, etc\) from non-volatile memory.
```python
lora.nvram_erase()
```
## Constants
* LoRa stack mode: `LoRa.LORA`, `LoRa.LORAWAN`
* LoRaWAN join procedure: `LoRa.OTAA`, `LoRa.ABP`
* Raw LoRa power mode: `LoRa.ALWAYS_ON`, `LoRa.TX_ONLY`, `LoRa.SLEEP`
* Raw LoRa bandwidth: `LoRa.BW_125KHZ`, `LoRa.BW_250KHZ`, `LoRa.BW_500KHZ`
* Raw LoRa coding rate: `LoRa.CODING_4_5`, `LoRa.CODING_4_6`, `LoRa.CODING_4_7`, `LoRa.CODING_4_8`
* Callback trigger types \(may be ORed\): `LoRa.RX_PACKET_EVENT`, `LoRa.TX_PACKET_EVENT`, `LoRa.TX_FAILED_EVENT`
* LoRaWAN device class: `LoRa.CLASS_A`, `LoRa.CLASS_C`
* LoRaWAN regions: `LoRa.AS923`, `LoRa.AU915`, `LoRa.EU868`, `LoRa.US915`
## Working with LoRa and LoRaWAN Sockets
LoRa sockets are created in the following way:
```python
import socket
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
```
And they must be created after initialising the LoRa network card.
LoRa sockets support the following standard methods from the socket module:
#### socket.close\(\)
Usage:
```python
s.close()
```
#### socket.bind\(port\_number\)
Usage:
```python
s.bind(1)
```
{% hint style="info" %}
The `bind()` method is only applicable when the radio is configured in `LoRa.LORAWAN` mode.
{% endhint %}
#### socket.send\(bytes\)
Usage:
```python
s.send(bytes([1, 2, 3]))
```
or
```python
s.send('Hello')
```
#### socket.recv\(bufsize\)
Usage:
```python
s.recv(128)
```
#### socket.recvfrom\(bufsize\)
This method is useful to know the destination port number of the message received. Returns a tuple of the form: `(data, port)`
Usage:
```python
s.recvfrom(128)
```
#### socket.setsockopt\(level, optname, value\)
Set the value of the given socket option. The needed symbolic constants are defined in the socket module \(`SO_*` etc.\). In the case of LoRa the values are always integers. Examples:
```python
# configuring the data rate
s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
# selecting non-confirmed type of messages
s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, False)
# selecting confirmed type of messages
s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, True)
```
{% hint style="info" %}
Socket options are only applicable when the LoRa radio is used in LoRa.LORAWAN mode. When using the radio in LoRa.LORA mode, use the class methods to change the spreading factor, bandwidth and coding rate to the desired values.
{% endhint %}
#### socket.settimeout\(value\)
Sets the socket timeout value in seconds. Accepts floating point values.
Usage:
```python
s.settimeout(5.5)
```
#### socket.setblocking\(flag\)
Usage:
```python
s.setblocking(True)
```

View File

@@ -1,125 +0,0 @@
# LTE
The LTE class provides access to the LTE-M/NB-IoT modem on the GPy and FiPy. LTE-M/NB-IoT are new categories of cellular protocols developed by the [3GPP](http://www.3gpp.org) and optimised for long battery life power and longer range. These are new protocols currently in the process of being deployed by mobile networks across the world.
The GPy and FiPy support both new LTE-M protocols:
* **Cat-M1**: also known as **LTE-M** defines a 1.4 MHz radio channel size and about 375 kbps of throughput. It is optimised for coverage and long battery life, outperforming 2G/GPRS, while being similar to previous LTE standards.
* **Cat-NB1** also known as **NB-IoT**, defines a 200 kHz radio channel size and around 60 kbps of uplink speed. It's optimised for ultra low throughput and specifically designed for IoT devices with a very long battery life. NB-IoT shares some features with LTE such as operating in licensed spectrum, but it's a very different protocol. It should be noted that NB-IoT has many restrictions as does not offer full IP connectivity and does not support mobility. When moving between cells, you will need to reconnect.
{% hint style="info" %}
**Please note:** The GPy and FiPy only support the two protocols above and are not compatible with older LTE standards.
{% endhint %}
{% hint style="info" %}
The Sequans modem used on Pycom's cellular enabled modules can only work in one of these modes at a time. In order to switch between the two protocols you need to flash a different firmware to the Sequans modem. Instructions for this can be found [here](../../../tutorials-and-examples/lte/firmware.md).
{% endhint %}
## AT Commands
The AT commands for the Sequans Monarch modem on the GPy/FiPy are available in a PDF file.
{% file src="../../../.gitbook/assets/monarch\_4g-ez\_lr5110\_atcommands\_referencemanual\_rev3\_noconfidential.pdf" caption="AT Commands for Sequans" %}
## Constructors
#### class network.LTE\(id=0, ...\)
Create and configure a LTE object. See init for params of configuration.
```python
from network import LTE
lte = LTE()
```
## Methods
#### lte.init\(\*, carrier=None\)
This method is used to set up the LTE subsystem. After a `deinit()` this method can take several seconds to return waiting for the LTE modem to start-up. Optionally specify a carrier name. The available options are: `verizon, at&t, standard`. `standard` is generic for any carrier, and it's also the option used when no arguments are given.
#### lte.deinit\(\)
Disables LTE modem completely. This reduces the power consumption to the minimum. Call this before entering deepsleep.
#### lte.attach\(\*, band=None\)
Enable radio functionality and attach to the LTE Cat M1 network authorised by the inserted SIM card. Optionally specify the band to scan for networks. If no band \(or `None`\) is specified, all 6 bands will be scanned. The possible values for the band are: `3, 4, 12, 13, 20 and 28`.
#### lte.isattached\(\)
Returns `True` if the cellular mode is attached to the network. `False` otherwise.
#### lte.dettach\(\)
Detach the modem from the LTE Cat M1 and disable the radio functionality.
#### lte.connect\(\*, cid=1\)
Start a data session and obtain and IP address. Optionally specify a CID \(Connection ID\) for the data session. The arguments are:
* `cid` is a Connection ID. This is carrier specific, for Verizon use `cid=3`. For others like Telstra it should be `cid=1`.
For instance, to attach and connect to Verizon:
```python
import time
from network import LTE
lte = LTE(carrier="verizon")
lte.attach(band=13)
while not lte.isattached():
time.sleep(0.5)
print('Attaching...')
lte.connect(cid=3)
while not lte.isconnected():
time.sleep(0.5)
print('Connecting...')
# Now use sockets as usual...
```
#### lte.isconnected\(\)
Returns `True` if there is an active LTE data session and IP address has been obtained. `False` otherwise.
#### lte.disconnect\(\)
End the data session with the network.
#### lte.send\_at\_cmd\(cmd\)
Send an AT command directly to the modem. Returns the raw response from the modem as a string object. **IMPORTANT:** If a data session is active \(i.e. the modem is _connected_\), sending the AT commands requires to pause and then resume the data session. This is all done automatically, but makes the whole request take around 2.5 seconds.
Example:
```python
lte.send_at_cmd('AT+CEREG?') # check for network registration manually (sames as lte.isattached())
```
Optionally the response can be parsed for pretty printing:
```python
def send_at_cmd_pretty(cmd):
response = lte.send_at_cmd(cmd).split('\r\n')
for line in response:
print(line)
send_at_cmd_pretty('AT!="showphy"') # get the PHY status
send_at_cmd_pretty('AT!="fsm"') # get the System FSM
```
#### lte.imei\(\)
Returns a string object with the IMEI number of the LTE modem.
#### lte.iccid\(\)
Returns a string object with the ICCID number of the SIM card.
#### lte.reset\(\)
Perform a hardware reset on the cellular modem. This function can take up to 5 seconds to return as it waits for the modem to shutdown and reboot.

View File

@@ -1,50 +0,0 @@
# Server
The `Server` class controls the behaviour and the configuration of the FTP and telnet services running on the Pycom device. Any changes performed using this class methods will affect both.
Example:
```python
import network
server = network.Server()
server.deinit() # disable the server
# enable the server again with new settings
server.init(login=('user', 'password'), timeout=600)
```
## Quick Usage Example
```python
from network import Server
# init with new user, password and seconds timeout
server = Server(login=('user', 'password'), timeout=60)
server.timeout(300) # change the timeout
server.timeout() # get the timeout
server.isrunning() # check whether the server is running or not
```
## Constructors
#### class network.Server\(id, ...\)
Create a server instance, see `init` for parameters of initialisation.
## Methods
#### server.init\(\* , login=\('micro', 'python'\), timeout=300\)
Init \(and effectively start the server\). Optionally a new `user`, `password` and `timeout` \(in seconds\) can be passed.
#### server.deinit\(\)
Stop the server.
#### server.timeout\(\[timeout\_in\_seconds\]\)
Get or set the server timeout.
#### server.isrunning\(\)
Returns `True` if the server is running \(connected or accepting connections\), `False` otherwise.

View File

@@ -1,279 +0,0 @@
# Sigfox
Sigfox is a Low Power Wide Area Network protocol that enables remote devices to connect using ultra-narrow band, UNB technology. The protocol is bi-directional, messages can both be sent up to and down from the Sigfox servers.
{% hint style="info" %}
When operating in `RCZ2` and `RCZ4` the module can only send messages on the default macro-channel \(this is due to Sigfox network limitations\). Therefore, the device needs to reset automatically to the default macro-channel after every 2 transmissions. However, due to FCC duty cycle limitations, there must a minimum of a 20s delay after resetting to the default macro-channel. Our API takes care of this, \(and in real life applications you should not be in the need to send Sigfox messages that often\), so it will wait for the necessary amount of time to make sure that the duty cycle restrictions are fulfilled.
This means that if you run a piece of test code like:
```python
for i in range(1, 100):
# send something
s.send('Hello ' + str(i))
```
There will be a 20 second delay after every 2 packets.
{% endhint %}
This class provides a driver for the Sigfox network processor in the Sigfox enabled Pycom devices.
## Quick Usage Example
```python
from network import Sigfox
import socket
# init Sigfox for RCZ1 (Europe)
sigfox = Sigfox(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ1)
# create a Sigfox socket
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
# make the socket blocking
s.setblocking(True)
# configure it as uplink only
s.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, False)
# send some bytes
s.send(bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]))
```
{% hint style="danger" %}
Please ensure that there is an antenna connected to your device before sending/receiving Sigfox messages as in proper use \(e.g. without an antenna\), may damage the device.
{% endhint %}
## Constructors
#### class network.Sigfox\(id=0, ...\)
Create and configure a Sigfox object. See init for params of configuration. Examples:
```python
# configure radio for the Sigfox network, using RCZ1 (868 MHz)
sigfox = Sigfox(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ1)
# configure radio for FSK, device to device across 912 MHz
sigfox = Sigfox(mode=Sigfox.FSK, frequency=912000000)
```
{% hint style="info" %}
`Sigfox.FSK` mode is not supported on LoPy 4 and FiPy.
{% endhint %}
## Methods
#### sigfox.init\(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ1, \* , frequency=None\)
Set the Sigfox radio configuration.
The arguments are:
* `mode` can be either `Sigfox.SIGFOX` or `Sigfox.FSK`. `Sigfox.SIGFOX` uses the Sigfox modulation and protocol while `Sigfox.FSK` allows to create point to point communication between 2 Devices using FSK modulation. _Note:_ `Sigfox.FSK` _mode is not supported on LoPy 4 and FiPy._
* `rcz` takes the following values: `Sigfox.RCZ1`, `Sigfox.RCZ2`, `Sigfox.RCZ3`, `Sigfox.RCZ4`. The `rcz` argument is only required if the mode is `Sigfox.SIGFOX`.
* `frequency` sets the frequency value in `FSK` mode. Can take values between 863 and 928 MHz.
{% hint style="info" %}
The SiPy comes in 2 different hardware flavours: a +14dBm Tx power version which can only work with `RCZ1` and `RCZ3` and a +22dBm version which works exclusively on `RCZ2` and `RCZ4`.
{% endhint %}
#### sigfox.mac\(\)
Returns a byte object with the 8-Byte MAC address of the Sigfox radio.
#### sigfox.id\(\)
Returns a byte object with the 4-Byte bytes object with the Sigfox ID.
#### sigfox.rssi\(\)
Returns a signed integer with indicating the signal strength value of the last received packet.
#### sigfox.pac\(\)
Returns a byte object with the 8-Byte bytes object with the Sigfox PAC.
{% hint style="info" %}
To return human-readable values you should import `ubinascii` and convert binary values to hexidecimal representation. For example:
```python
print(ubinascii.hexlify(sigfox.mac()))
```
{% endhint %}
#### sigfox.frequencies\(\)
Returns a tuple of the form: `(uplink_frequency_hz, downlink_frequency_hz)`
#### sigfox.public\_key\(\[public\]\)
Sets or gets the public key flag. When called passing a `True` value the Sigfox public key will be used to encrypt the packets. Calling it without arguments returns the state of the flag.
```python
# enable encrypted packets
sigfox.public_key(True)
# return state of public_key
sigfox.public_key()
```
## Constants
* Sigfox radio mode: `sigfox.SIGFOX`, `sigfox.FSK` .
* `SIGFOX` to specify usage of the Sigfox Public Network.
* `FSK` to specify device to device communication.
* Sigfox zones: `sigfox.RCZ1`, `sigfox.RCZ2`, `sigfox.RCZ3`, `sigfox.RCZ4`
* `RCZ1` to specify Europe, Oman & South Africa.
* `RCZ2` for the USA, Mexico & Brazil.
* `RCZ3` for Japan.
* `RCZ4` for Australia, New Zealand, Singapore, Taiwan, Hong Kong, Colombia & Argentina.
## Working with Sigfox Sockets
Sigfox sockets are created in the following way:
```python
import socket
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
```
And they must be created after initialising the Sigfox network card.
Sigfox sockets support the following standard methods from the `socket` module:
#### socket.close\(\)
Use it to close an existing socket.
#### socket.send\(bytes\)
In Sigfox mode the maximum data size is 12 bytes. In FSK the maximum is 64.
```python
# send a Sigfox payload of bytes
s.send(bytes([1, 2, 3]))
# send a Sigfox payload containing a string
s.send('Hello')
```
#### socket.recv\(bufsize\)
This method can be used to receive a Sigfox downlink or FSK message.
```python
# size of buffer should be passed for expected payload, e.g. 64 bytes
s.recv(64)
```
#### socket.setsockopt\(level, optname, value\)
Set the value of the given socket option. The needed symbolic constants are defined in the socket module \(`SO_*` etc.\). In the case of Sigfox the values are always an integer. Examples:
```python
# wait for a downlink after sending the uplink packet
s.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, True)
# make the socket uplink only
s.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, False)
# use the socket to send a Sigfox Out Of Band message
s.setsockopt(socket.SOL_SIGFOX, socket.SO_OOB, True)
# disable Out-Of-Band to use the socket normally
s.setsockopt(socket.SOL_SIGFOX, socket.SO_OOB, False)
# select the bit value when sending bit only packets
s.setsockopt(socket.SOL_SIGFOX, socket.SO_BIT, False)
```
Sending a Sigfox packet with a single bit is achieved by sending an empty string, i.e.:
```python
import socket
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
# send a 1 bit
s.setsockopt(socket.SOL_SIGFOX, socket.SO_BIT, True)
s.send('')
socket.settimeout(value)
# set timeout for the socket, e.g. 5 seconds
s.settimeout(5.0)
socket.setblocking(flag)
# specifies if socket should be blocking based upon Boolean flag.
s.setblocking(True)
```
If the socket is set to blocking, your code will be wait until the socket completes sending/receiving.
## Sigfox Downlink
A Sigfox capable Pycom devices \(SiPy\) can both send and receive data from the Sigfox network. To receive data, a message must first be sent up to Sigfox, requesting a downlink message. This can be done by passing a `True` argument into the `setsockopt()` method.
```python
s.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, True)
```
An example of the downlink procedure can be seen below:
```python
# init Sigfox for RCZ1 (Europe)
sigfox = Sigfox(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ1)
# create a Sigfox socket
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
# make the socket blocking
s.setblocking(True)
# configure it as DOWNLINK specified by 'True'
s.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, True)
# send some bytes and request DOWNLINK
s.send(bytes([1, 2, 3]))
# await DOWNLINK message
s.recv(32)
```
## Sigfox FSK \(Device to Device\)
To communicate between two Sigfox capable devices, it may be used in FSK mode. Two devices are required to be set to the same frequency, both using FSK.
{% hint style="info" %}
`Sigfox.FSK` mode is not supported on LoPy 4 and FiPy.
{% endhint %}
**Device 1**:
```python
sigfox = Sigfox(mode=Sigfox.FSK, frequency=868000000)
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
s.setblocking(True)
while True:
s.send('Device-1')
time.sleep(1)
print(s.recv(64))
```
**Device 2**:
```python
sigfox = Sigfox(mode=Sigfox.FSK, frequency=868000000)
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
s.setblocking(True)
while True:
s.send('Device-2')
time.sleep(1)
print(s.recv(64))
```
{% hint style="danger" %}
Remember to use the correct frequency for your region \(868 MHz for Europe, 912 MHz for USA, etc.\)
{% endhint %}

View File

@@ -1,156 +0,0 @@
# WLAN
This class provides a driver for the WiFi network processor in the module. Example usage:
```python
import network
import time
# setup as a station
wlan = network.WLAN(mode=network.WLAN.STA)
wlan.connect('your-ssid', auth=(network.WLAN.WPA2, 'your-key'))
while not wlan.isconnected():
time.sleep_ms(50)
print(wlan.ifconfig())
# now use socket as usual
```
## Quick Usage Example
```python
import machine
from network import WLAN
# configure the WLAN subsystem in station mode (the default is AP)
wlan = WLAN(mode=WLAN.STA)
# go for fixed IP settings (IP, Subnet, Gateway, DNS)
wlan.ifconfig(config=('192.168.0.107', '255.255.255.0', '192.168.0.1', '192.168.0.1'))
wlan.scan() # scan for available networks
wlan.connect(ssid='mynetwork', auth=(WLAN.WPA2, 'my_network_key'))
while not wlan.isconnected():
pass
print(wlan.ifconfig())
```
## Constructors
#### class network.WLAN\(id=0, ...\)
Create a WLAN object, and optionally configure it. See [`init`](wlan.md#wlan-init-mode-ssid-none-auth-none-channel-1-antenna-none-power_save-false-hidden-false) for params of configuration.
{% hint style="info" %}
The WLAN constructor is special in the sense that if no arguments besides the `id` are given, it will return the already existing WLAN instance without re-configuring it. This is because WLAN is a system feature of the WiPy. If the already existing instance is not initialised it will do the same as the other constructors an will initialise it with default values.
{% endhint %}
## Methods
#### wlan.init\(mode, \* , ssid=None, auth=None, channel=1, antenna=None, power\_save=False, hidden=False\)
Set or get the WiFi network processor configuration.
Arguments are:
* `mode` can be either `WLAN.STA`, `WLAN.AP`, or `WLAN.STA_AP`.
* `ssid` is a string with the SSID name. Only needed when mode is `WLAN.AP`.
* `auth` is a tuple with \(sec, key\). Security can be `None`, `WLAN.WEP`, `WLAN.WPA`, or `WLAN.WPA2`. The key is a string with the network password.
* If `sec` is `WLAN.WEP` the key must be a string representing hexadecimal values \(e.g. `ABC1DE45BF`\). Only needed when mode is `WLAN.AP`.
* `channel` a number in the range 1-11. Only needed when mode is `WLAN.AP`.
* `antenna` selects between the internal and the external antenna. Can be either `WLAN.INT_ANT`, `WLAN.EXT_ANT`. With our development boards it defaults to using the internal antenna, but in the case of an OEM module, the antenna pin \(`P12`\) is not used, so its free to be
used for other things.
* `power_save` enables or disables power save functions in `STA` mode.
* `hidden` only valid in `WLAN.AP` mode to create an access point with a hidden SSID when set to `True`.
For example, you can do:
```python
# create and configure as an access point
wlan.init(mode=WLAN.AP, ssid='wipy-wlan', auth=(WLAN.WPA2,'www.wipy.io'), channel=7, antenna=WLAN.INT_ANT)
```
or
```python
# configure as an station
wlan.init(mode=WLAN.STA)
```
#### wlan.deinit\(\)
Disables the WiFi radio.
#### wlan.connect\(ssid, \* , auth=None, bssid=None, timeout=None, ca\_certs=None, keyfile=None, certfile=None, identity=None\)
Connect to a wifi access point using the given SSID, and other security parameters.
* `auth` is a tuple with `(sec, key)`. Security can be `None`, `WLAN.WEP`, `WLAN.WPA`, `WLAN.WPA2` or `WLAN.WPA2_ENT`. The key is a string with the network password.
* If `sec` is `WLAN.WEP` the key must be a string representing hexadecimal values \(e.g. `ABC1DE45BF`\).
* If `sec` is `WLAN.WPA2_ENT` then the `auth` tuple can have either 3 elements: `(sec, username, password)`, or just 1: `(sec,)`. When passing the 3 element tuple, the`keyfile` and `certifle` arguments must not be given.
* `bssid` is the MAC address of the AP to connect to. Useful when there are several APs with the same SSID.
* `timeout` is the maximum time in milliseconds to wait for the connection to succeed.
* `ca_certs` is the path to the CA certificate. This argument is not mandatory.
* `keyfile` is the path to the client key. Only used if `username` and `password` are not part of the `auth` tuple.
* `certfile` is the path to the client certificate. Only used if `username` and `password` are not part of the `auth` tuple.
* `identity` is only used in case of `WLAN.WPA2_ENT` security. Needed by the server.
{% hint style="info" %}
The ESP32 only handles certificates with `pkcs8` format \(but not the "Traditional SSLeay RSAPrivateKey" format\). The private key should be RSA coded with 2048 bits at maximum.
{% endhint %}
#### wlan.scan\(\)
Performs a network scan and returns a list of named tuples with `(ssid, bssid, sec, channel, rssi)`. Note that channel is always `None` since this info is not provided by the WiPy.
#### wlan.disconnect\(\)
Disconnect from the WiFi access point.
#### wlan.isconnected\(\)
In case of STA mode, returns `True` if connected to a WiFi access point and has a valid IP address. In AP mode returns `True` when a station is connected, `False` otherwise.
#### wlan.ifconfig\(id=0, config=\['dhcp' or configtuple\]\)
When `id` is 0, the configuration will be get/set on the Station interface. When `id` is 1 the configuration will be done for the AP interface.
With no parameters given returns a 4-tuple of `(ip, subnet_mask, gateway, DNS_server)`.
If `dhcp` is passed as a parameter then the DHCP client is enabled and the IP params are negotiated with the AP.
If the 4-tuple config is given then a static IP is configured. For instance:
```python
wlan.ifconfig(config=('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
```
#### wlan.mode\(\[mode\]\)
Get or set the WLAN mode.
#### wlan.ssid\(\[ssid\]\)
Get or set the SSID when in AP mode.
#### wlan.auth\(\[auth\]\)
Get or set the authentication type when in AP mode.
#### wlan.channel\(\[channel\]\)
Get or set the channel \(only applicable in AP mode\).
#### wlan.antenna\(\[antenna\]\)
Get or set the antenna type \(external or internal\).
#### wlan.mac\(\)
Get a 6-byte long `bytes` object with the WiFI MAC address.
## Constants
* WLAN mode: `WLAN.STA`, `WLAN.AP`, `WLAN.STA_AP`
* WLAN network security: `WLAN.WEP`, `WLAN.WPA`, `WLAN.WPA2`, `WLAN.WPA2_ENT`
* Antenna type: `WLAN.INT_ANT`, `WLAN.EXT_ANT`