diff --git a/amplify.yml b/amplify.yml
index 02fa6ac..9bf1489 100644
--- a/amplify.yml
+++ b/amplify.yml
@@ -1,12 +1,12 @@
-version: 0.1
+version: 0.2
frontend:
phases:
build:
commands:
- - wget https://github.com/gohugoio/hugo/releases/download/v0.54.0/hugo_0.54.0_Linux-64bit.tar.gz
- - tar -xf hugo_0.54.0_Linux-64bit.tar.gz hugo
+ - wget https://github.com/gohugoio/hugo/releases/download/v0.58.3/hugo_0.58.3_Linux-64bit.tar.gz
+ - tar -xf hugo_0.58.3_Linux-64bit.tar.gz hugo
- mv hugo /usr/bin/hugo
- - rm -rf hugo_0.54.0_Linux-64bit.tar.gz
+ - rm -rf hugo_0.58.3_Linux-64bit.tar.gz
- hugo
artifacts:
baseDirectory: public
diff --git a/config.toml b/config.toml
index e797b22..e94ecdc 100644
--- a/config.toml
+++ b/config.toml
@@ -359,6 +359,20 @@ theme = "doc-theme"
parent = "tutorials@all"
weight = 10
+[[menu.main]]
+ name = "PyGate"
+ url = "/tutorials/all/PyGate/"
+ identifier = "tutorials@all@PyGate"
+ parent = "tutorials@all"
+ weight = 10
+
+[[menu.main]]
+ name = "PoE"
+ url = "/tutorials/all/PoE/"
+ identifier = "tutorials@all@PoE"
+ parent = "tutorials@all"
+ weight = 12
+
[[menu.main]]
name = "WLAN"
url = "/tutorials/all/wlan/"
@@ -373,6 +387,13 @@ theme = "doc-theme"
parent = "tutorials@all"
weight = 30
+[[menu.main]]
+ name = "Pymesh BLE"
+ url = "/tutorials/all/ble_mesh/"
+ identifier = "tutorials@all@ble_mesh"
+ parent = "tutorials@all"
+ weight = 35
+
[[menu.main]]
name = "HTTPS"
url = "/tutorials/all/https/"
@@ -541,6 +562,20 @@ theme = "doc-theme"
parent = "tutorials@lora"
weight = 70
+[[menu.main]]
+ name = "LoRa Mesh"
+ url = "/tutorials/lora/lora-mesh/"
+ identifier = "tutorials@lora@lora-mesh"
+ parent = "tutorials@lora"
+ weight = 80
+
+[[menu.main]]
+ name = "PyMesh Border Router"
+ url = "/tutorials/lora/pymesh-br/"
+ identifier = "tutorials@lora@pymesh-br"
+ parent = "tutorials@lora"
+ weight = 90
+
[[menu.main]]
name = "Sigfox Examples"
url = "/tutorials/sigfox/"
@@ -569,6 +604,13 @@ theme = "doc-theme"
parent = "tutorials@lte"
weight = 20
+[[menu.main]]
+ name = "Power consumption"
+ url = "/tutorials/lte/power/"
+ identifier = "tutorials@lte@power"
+ parent = "tutorials@lte"
+ weight = 20
+
[[menu.main]]
name = "Module IMEI"
url = "/tutorials/lte/imei/"
@@ -632,26 +674,26 @@ theme = "doc-theme"
parent = "firmwareapi@pycom@machine"
weight = 10
+[[menu.main]]
+ name = "CAN"
+ url = "/firmwareapi/pycom/machine/can/"
+ identifier = "firmwareapi@pycom@machine@can"
+ parent = "firmwareapi@pycom@machine"
+ weight = 20
+
[[menu.main]]
name = "DAC"
url = "/firmwareapi/pycom/machine/dac/"
identifier = "firmwareapi@pycom@machine@dac"
parent = "firmwareapi@pycom@machine"
- weight = 20
+ weight = 30
[[menu.main]]
name = "I2C"
url = "/firmwareapi/pycom/machine/i2c/"
identifier = "firmwareapi@pycom@machine@i2c"
parent = "firmwareapi@pycom@machine"
- weight = 30
-
-[[menu.main]]
- name = "Pin"
- url = "/firmwareapi/pycom/machine/pin/"
- identifier = "firmwareapi@pycom@machine@pin"
- parent = "firmwareapi@pycom@machine"
- weight = 40
+ weight = 35
[[menu.main]]
name = "PWM"
@@ -661,58 +703,65 @@ theme = "doc-theme"
weight = 50
[[menu.main]]
- name = "RTC"
- url = "/firmwareapi/pycom/machine/rtc/"
- identifier = "firmwareapi@pycom@machine@rtc"
+ name = "Pin"
+ url = "/firmwareapi/pycom/machine/pin/"
+ identifier = "firmwareapi@pycom@machine@pin"
parent = "firmwareapi@pycom@machine"
weight = 60
[[menu.main]]
- name = "SPI"
- url = "/firmwareapi/pycom/machine/spi/"
- identifier = "firmwareapi@pycom@machine@spi"
+ name = "Pygate"
+ url = "/firmwareapi/pycom/machine/pygate/"
+ identifier = "firmwareapi@pycom@machine@pygate"
+ parent = "firmwareapi@pycom@machine"
+ weight = 65
+
+[[menu.main]]
+ name = "RMT"
+ url = "/firmwareapi/pycom/machine/rmt/"
+ identifier = "firmwareapi@pycom@machine@rmt"
parent = "firmwareapi@pycom@machine"
weight = 70
[[menu.main]]
- name = "UART"
- url = "/firmwareapi/pycom/machine/uart/"
- identifier = "firmwareapi@pycom@machine@uart"
+ name = "RTC"
+ url = "/firmwareapi/pycom/machine/rtc/"
+ identifier = "firmwareapi@pycom@machine@rtc"
parent = "firmwareapi@pycom@machine"
weight = 80
-[[menu.main]]
- name = "WDT"
- url = "/firmwareapi/pycom/machine/wdt/"
- identifier = "firmwareapi@pycom@machine@wdt"
- parent = "firmwareapi@pycom@machine"
- weight = 90
-
-[[menu.main]]
- name = "Timer"
- url = "/firmwareapi/pycom/machine/timer/"
- identifier = "firmwareapi@pycom@machine@timer"
- parent = "firmwareapi@pycom@machine"
- weight = 100
-
[[menu.main]]
name = "SD"
url = "/firmwareapi/pycom/machine/sd/"
identifier = "firmwareapi@pycom@machine@sd"
parent = "firmwareapi@pycom@machine"
+ weight = 90
+
+[[menu.main]]
+ name = "SPI"
+ url = "/firmwareapi/pycom/machine/spi/"
+ identifier = "firmwareapi@pycom@machine@spi"
+ parent = "firmwareapi@pycom@machine"
+ weight = 100
+
+[[menu.main]]
+ name = "Timer"
+ url = "/firmwareapi/pycom/machine/timer/"
+ identifier = "firmwareapi@pycom@machine@timer"
+ parent = "firmwareapi@pycom@machine"
weight = 110
[[menu.main]]
- name = "CAN"
- url = "/firmwareapi/pycom/machine/can/"
- identifier = "firmwareapi@pycom@machine@can"
+ name = "UART"
+ url = "/firmwareapi/pycom/machine/uart/"
+ identifier = "firmwareapi@pycom@machine@uart"
parent = "firmwareapi@pycom@machine"
weight = 120
[[menu.main]]
- name = "RMT"
- url = "/firmwareapi/pycom/machine/rmt/"
- identifier = "firmwareapi@pycom@machine@rmt"
+ name = "WDT"
+ url = "/firmwareapi/pycom/machine/wdt/"
+ identifier = "firmwareapi@pycom@machine@wdt"
parent = "firmwareapi@pycom@machine"
weight = 130
@@ -744,6 +793,13 @@ theme = "doc-theme"
parent = "firmwareapi@pycom@network"
weight = 20
+[[menu.main]]
+ name = "Ethernet"
+ url = "/firmwareapi/pycom/network/eth/"
+ identifier = "firmwareapi@pycom@network@eth"
+ parent = "firmwareapi@pycom@network"
+ weight = 25
+
[[menu.main]]
name = "Bluetooth"
url = "/firmwareapi/pycom/network/bluetooth/"
@@ -793,6 +849,13 @@ theme = "doc-theme"
parent = "firmwareapi@pycom@network@bluetooth"
weight = 60
+[[menu.main]]
+ name = "Pymesh BLE"
+ url = "/firmwareapi/pycom/network/bluetooth/BLE_Mesh/"
+ identifier = "firmwareapi@pycom@network@bluetooth@BLE_Mesh"
+ parent = "firmwareapi@pycom@network@bluetooth"
+ weight = 70
+
# [Errno 2] No such file or directory: './content/firmwareapi/pycom/network/lora/README.md'
[[menu.main]]
name = "LoRa"
@@ -969,7 +1032,6 @@ theme = "doc-theme"
parent = "firmwareapi@micropython"
weight = 90
-# [Errno 2] No such file or directory: './content/firmwareapi/micropython/ustruct/README.md'
[[menu.main]]
name = "ustruct"
url = "/firmwareapi/micropython/ustruct/"
@@ -977,6 +1039,13 @@ theme = "doc-theme"
parent = "firmwareapi@micropython"
weight = 180
+[[menu.main]]
+ name = "uzlib"
+ url = "/firmwareapi/micropython/uzlib/"
+ identifier = "firmwareapi@micropython@uzlib"
+ parent = "firmwareapi@micropython"
+ weight = 200
+
[[menu.main]]
name = "_thread"
url = "/firmwareapi/micropython/_thread/"
diff --git a/content/advance/downgrade.md b/content/advance/downgrade.md
index 9d133e8..0a52472 100644
--- a/content/advance/downgrade.md
+++ b/content/advance/downgrade.md
@@ -4,7 +4,6 @@ aliases:
- advance/downgrade.html
- advance/downgrade.md
- chapter/advance/downgrade
-
---
The firmware upgrade tool usually updates your device to the latest available firmware version. If you require to downgrade your device to a previous firmware there are two methods to achieve this.
diff --git a/content/docnotes/syntax.md b/content/docnotes/syntax.md
index 3f93fda..7436ee4 100644
--- a/content/docnotes/syntax.md
+++ b/content/docnotes/syntax.md
@@ -15,14 +15,12 @@ The Pycom documentation follows standard Python Library format using the popular
The values of the arguments (as seen in the examples/docs) refer to the default values that are passed into the constructor if nothing is provided.
```python
-
i2c.init(mode, * , baudrate=100000, pins=(SDA, SCL))
```
An example of what this method might be called:
```python
-
i2c.init(I2C.MASTER, pins=('P12', 'P11'))
```
@@ -37,12 +35,10 @@ It is important to note that there are certain class methods that can only accep
An asterisk `*` in a method description \(in the docs\), denotes that the following arguments require a keyword, i.e. `pin='P16'` in the example below.
```python
-
adc.channel(* , pin, attn=ADC.ATTN_0DB)
```
```python
-
from machine import ADC
adc = ADC() # create an ADC object
@@ -54,7 +50,6 @@ apin = adc.channel(pin='P16') # create an analog pin on P16
Another example shows how the `PWM` class, `pwm.channel()` requires a keyword argument for `pin` but does not for `id`.
```python
-
from machine import PWM
pwm = PWM(0, frequency=5000)
@@ -66,14 +61,12 @@ pwm_c = pwm.channel(0, pin='P12') # no keyword argument required for id (0) but
The documentation may refer to a method that takes an argument listed by name but does allow for a keyword to be passed. For example, the `pycom` class contains a method `rgbled`. This lists that the method accepts a value for `color`, however this may not be specified by `keyword`, only `value`. This is intentional as the `value` being passed is the only argument valid for this method
```python
-
pycom.rgbled(color)
```
If the argument is passed into the method with a keyword, it will return an error stating TypeError: function does not take keyword arguments.
```python
-
import pycom
pycom.rgbled(color=0xFF0000) # Incorrect
@@ -83,12 +76,10 @@ pycom.rgbled(0xFF0000) # Correct
Another example of a method that only accepts value input. In this case, the `RTC.init()` method require a value (`tuple`) input for the `datetime`. It will not accept a keyword.
```python
-
rtc.init(datetime)
```
```python
-
from machine import RTC
rtc = RTC()
@@ -101,7 +92,6 @@ rtc.init((2014, 5, 1, 4, 13, 0, 0, 0)) # Correct
The `constants` section of a library within the docs refers to specific values from that library's class. These might be used when constructing an object from that class or when utilising a method from within that class. These are generally listed by the library name followed by the specific value. See the example below:
```python
-
I2C.MASTER()
```
diff --git a/content/firmwareapi/micropython/ussl.md b/content/firmwareapi/micropython/ussl.md
index 1cdfc87..8b7e9d7 100644
--- a/content/firmwareapi/micropython/ussl.md
+++ b/content/firmwareapi/micropython/ussl.md
@@ -10,9 +10,9 @@ This module provides access to Transport Layer Security (often known as "Secure
## Methods
-#### ssl.wrap\_socket(sock, keyfile=None, certfile=None, server\_side=False, cert\_reqs=CERT\_NONE, ca\_certs=None\, timeout=10sec)
+#### ssl.wrap\_socket(sock, keyfile=None, certfile=None, server\_side=False, cert\_reqs=CERT\_NONE, ssl\_version=0, ca\_certs=None, server\_hostname=None, saved_session=None, timeout=10sec)
-Takes an instance `sock` of `socket.socket`, and returns an instance of ssl.SSLSocket, a subtype of `socket.socket`, which wraps the underlying socket in an SSL context. Example:
+Takes an instance `sock` of `socket.socket`, and returns an instance of `ssl.SSLSocket`, a subtype of `socket.socket`, which wraps the underlying socket in an SSL context. Example:
```python
@@ -38,8 +38,27 @@ ss.connect(socket.getaddrinfo('cloud.blynk.cc', 8441)[0][-1])
SSL sockets inherit all methods and from the standard sockets, see the `usocket` module.
+`saved_session` : Takes a saved session instance of `ssl.SSLSocket`, and retrieve an already established TLS connection.
+
`timeout` : specify a Timeout in Seconds for the SSL handshake operation between client and server, default is 10 seconds
+#### ssl.save\_session(ssl_sock)
+
+Takes an instance `ssl_sock` of `ssl.SSLSocket`, and returns an instance of `ssl.SSLSession`. Saved session can be resumed later, thereby reducing mobile data and time required. Example:
+
+```python
+
+import socket
+import ssl
+s = socket.socket()
+ss = ssl.wrap_socket(s)
+ss.connect(socket.getaddrinfo('www.google.com', 443)[0][-1])
+ses = ssl.save_session(ss)
+ss.close()
+ss = ssl.wrap_socket(s, saved_session=ses)
+ss.connect(socket.getaddrinfo('www.google.com', 443)[0][-1])
+```
+
## Exceptions
* `ssl.SSLError`
@@ -47,4 +66,3 @@ SSL sockets inherit all methods and from the standard sockets, see the `usocket`
## Constants
* `ssl.CERT_NONE`, `ssl.CERT_OPTIONAL`, `ssl.CERT_REQUIRED`: Supported values in `cert_reqs`
-
diff --git a/content/firmwareapi/pycom/aes.md b/content/firmwareapi/pycom/aes.md
index 45ba961..543a18d 100644
--- a/content/firmwareapi/pycom/aes.md
+++ b/content/firmwareapi/pycom/aes.md
@@ -15,7 +15,6 @@ AES is implemented using the ESP32 hardware module.
## Quick Usage Example
```python
-
from crypto import AES
import crypto
key = b'notsuchsecretkey' # 128 bit (16 bytes) key
diff --git a/content/firmwareapi/pycom/machine/_index.md b/content/firmwareapi/pycom/machine/_index.md
index c51fb3b..8b17eaf 100644
--- a/content/firmwareapi/pycom/machine/_index.md
+++ b/content/firmwareapi/pycom/machine/_index.md
@@ -46,6 +46,17 @@ Returns CPU frequency in hertz.
Gates the clock to the CPU, useful to reduce power consumption at any time during short or long periods. Peripherals continue working and execution resumes as soon as any interrupt is triggered (on many ports this includes system timer interrupt occurring at regular intervals on the order of millisecond).
+#### machine.sleep(\[time\_ms\], resume\_wifi\_ble)
+
+Sets the device in to light sleep mode , where in this mode digital peripherals, most of the RAM, and CPUs are clock-gated, and supply voltage is reduced. Upon exit from light sleep, peripherals and CPUs resume operation, their internal state is preserved.
+
+* `time_ms` is the time in milliseconds that the device should wakeup after, if no time is given the device will sleep until the next reset cycle unless another wakeup source is configured.
+* `resume_wifi_ble` is a boolean value that enables or disable restoring after wakeup any WiFi or BLE connection that was interrupted by light sleep.
+* `True` Enable WiFi/BLE connections restoration
+* `False` Disable Wifi/BLE connections restoration, default option is Disabled
+
+_Note: in light sleep mode LoRa/Lte modems are stopped and have to be re-initialized after wakeup._
+
#### machine.deepsleep(\[time\_ms\])
Stops the CPU and all peripherals, including the networking interfaces (except for LTE). Execution is resumed from the main script, just as with a reset. If a value in milliseconds is given then the device will wake up after that period of time, otherwise it will remain in deep sleep until the reset button is pressed.
diff --git a/content/firmwareapi/pycom/machine/pygate.md b/content/firmwareapi/pycom/machine/pygate.md
new file mode 100644
index 0000000..d7b1e7a
--- /dev/null
+++ b/content/firmwareapi/pycom/machine/pygate.md
@@ -0,0 +1,39 @@
+---
+title: "Pygate"
+aliases:
+ - firmwareapi/pycom/machine/pygate.html
+ - firmwareapi/pycom/machine/pygate.md
+ - chapter/firmwareapi/pycom/machine/pygate
+---
+
+The Pygate is an 8-channel LoRaWAN gateway. Connect a WiPy, Gpy or LoPy4 board to the Pygate and flash the Pygate firmware. See the [Pygate tutorial](/tutorials/all/pygate) to get started.
+
+## Methods
+
+#### machine.pygate\_init(buff)
+
+This function is used to initialize the Pygate
+
+- `buff`: the data contents of the gateway global config json file
+
+#### machine.pygate\_deinit()
+
+This shuts down the concentrator.
+
+#### machine.callback(trigger, handler=None, arg=None)
+
+- `trigger`: A trigger event(s) for invoking the callback function `handler`, the triggers/events are:
+
+ `machine.PYGATE_START_EVT`
+
+ `machine.PYGATE_STOP_EVT`
+
+ `machine.MP_QSTR_PYGATE_ERROR_EVT`
+
+- `handler`: The callback function to be called. When not passed to function, any pre-registered callback will be disabled/removed.
+
+- `arg`: Optional argument to be passed to the callback function.
+
+#### machine.events()
+
+Get the Pygate events
diff --git a/content/firmwareapi/pycom/machine/rtc.md b/content/firmwareapi/pycom/machine/rtc.md
index 7714b14..d2c8b73 100644
--- a/content/firmwareapi/pycom/machine/rtc.md
+++ b/content/firmwareapi/pycom/machine/rtc.md
@@ -85,6 +85,24 @@ Returns `True` if the last `ntp_sync` has been completed, `False` otherwise:
rtc.synced()
```
+#### rtc.memory(\[data\])
+
+Reads RTC memory contents or write data in passed Buffer in to RTC memory
+
+Example:
+
+```python
+rtc = RTC()
+rtc.memory(b'10101010') # writes data in RTC memory
+rtc.memory()
+```
+
+Output:
+
+```python
+b'10101010'
+```
+
## Constants
* Clock source: `RTC.INTERNAL_RC`, `RTC.XTAL_32KHZ`
diff --git a/content/firmwareapi/pycom/machine/timer.md b/content/firmwareapi/pycom/machine/timer.md
index 62be9a2..bb3fcd6 100644
--- a/content/firmwareapi/pycom/machine/timer.md
+++ b/content/firmwareapi/pycom/machine/timer.md
@@ -72,7 +72,6 @@ Get the elapsed time in microseconds.
Example:
```python
-
from machine import Timer
import time
@@ -111,7 +110,6 @@ Disables the alarm.
Example:
```python
-
from machine import Timer
class Clock:
diff --git a/content/firmwareapi/pycom/machine/uart.md b/content/firmwareapi/pycom/machine/uart.md
index 882e111..f611bf9 100644
--- a/content/firmwareapi/pycom/machine/uart.md
+++ b/content/firmwareapi/pycom/machine/uart.md
@@ -83,7 +83,7 @@ On the GPy/FiPy UART2 is unavailable because it is used to communicate with the
## Methods
-#### uart.init(baudrate=9600, bits=8, parity=None, stop=1, \* , timeout\_chars=2, pins=(TXD, RXD, RTS, CTS))
+#### uart.init(baudrate=9600, bits=8, parity=None, stop=1, \* , timeout\_chars=2, pins=(TXD, RXD, RTS, CTS), rx\_buffer\_size=512)
Initialise the UART bus with the given parameters:
@@ -93,6 +93,7 @@ Initialise the UART bus with the given parameters:
* `stop` is the number of stop bits, `1 or 2`.
* `timeout_chars` Rx timeout defined in number of characters. The value given here will be multiplied by the time a characters takes to be transmitted at the configured `baudrate`.
* `pins` is a 4 or 2 item list indicating the TXD, RXD, RTS and CTS pins (in that order). Any of the pins can be `None` if one wants the UART to operate with limited functionality. If the RTS pin is given the the RX pin must be given as well. The same applies to CTS. When no pins are given, then the default set of TXD (P1) and RXD (P0) pins is taken, and hardware flow control will be disabled. If `pins=None`, no pin assignment will be made.
+* `rx_buffer_size` is the size of the buffer used for storing the RX packets. By default is is 512 bytes.
#### uart.deinit()
diff --git a/content/firmwareapi/pycom/network/bluetooth/BLE_Mesh.md b/content/firmwareapi/pycom/network/bluetooth/BLE_Mesh.md
new file mode 100644
index 0000000..1d99823
--- /dev/null
+++ b/content/firmwareapi/pycom/network/bluetooth/BLE_Mesh.md
@@ -0,0 +1,116 @@
+---
+title: "Pymesh BLE"
+aliases:
+ - firmwareapi/pycom/network/bluetooth/BLE_Mesh.html
+ - firmwareapi/pycom/network/bluetooth/BLE_Mesh.md
+---
+
+The Pymesh BLE library provides support for connecting to a BLE Mesh Network with various Server and Client models.
+
+For examples, please check the section [Pymesh BLE Examples](/tutorials/all/ble_mesh).
+
+Pymesh BLE features:
+
+* Supported Models:
+ * Configuration Server Model (automatically generated together with primary Element)
+ * Generic OnOff Server Model
+ * Generic OnOff Client Model
+ * Generic Level Server Model
+ * Generic Level Client Model
+ * Sensor Server Model
+ * Sensor Client Model
+* Supported OOB authentication types:
+ * No OOB
+ * Output OOB
+* Supported Node Features:
+ * GATT Proxy
+ * Relay
+* Only one Element (primary) can be added to the Node.
+* Node cannot be configured as Provisioner and a mobile application should be used for Provisioning process
+ * nRF Mesh (iOS and Android)
+ * Silicon Labs Bluetoth Mesh (iOS)
+ * ST BLE Mesh (Android)
+ * EspBLEMesh (Android)
+
+
+## Methods of BLE_Mesh class
+
+#### BLE_Mesh.init(name="PYCOM-ESP-BLE-MESH", *, auth=0, callback=None)
+
+Initializes the BLE Mesh module with the pre-configured Elements and Models.
+
+* `name` is the name which will be used to identify the device during Provisioning
+* `auth` is the Out-Of-Band (OOB) method. Currently `BLE_Mesh.OOB_OUTPUT` is supported. Without specifying this argument, `NO_OOB` will be used during provisioning.
+* `callback` is the callback to be registered. It must have the following arguments:
+ * `event` returns current event of provisioning.
+ * `oob_pass` returns the generated pass in case of `BLE_Mesh.OOB_OUTPUT`.
+
+#### BLE_Mesh.set_node_prov(bearer=BLE_Mesh.PROV_NONE, *)
+
+Enable provisioning bearers to get the device ready for provisioning. If OOB is enabled, the callback is used to inform the user about OOB information.
+
+* `bearer` is the transport data protocol between endpoints, can be `BLE_Mesh.PROV_ADV` and/or `BLE_Mesh.PROV_GATT`.
+
+#### BLE_Mesh.reset_node_prov()
+
+Resets the Node Provisioning information.
+
+#### BLE_Mesh.create_element(*, primary, feature=0, beacon=true, ttl=7)
+
+This API creates a new BLE_Mesh_Element object. The BLE_Mesh_Element on concept level is equivalent to the Element in the BLE Mesh terminology.
+
+* `primary` shows whether this new Element will act as the Primary Element of the Node. When a Primary Element is created, the corresponding Configuration Server Model is also automatically created. There can only be 1 Primary Element per Node.
+* `feature` shows what features to enable on the new Element. It is an ORED combination of `BLE_Mesh.RELAY`, `BLE_Mesh.LOW_POWER`, `BLE_Mesh.GATT_PROXY`, `BLE_Mesh.FRIEND`
+* `ttl` is the default Time To Live value of the packets belonging to the new Element
+
+## Methods of BLE_Mesh_Element object
+
+#### BLE_Mesh_Element.add_model(type=BLE_Mesh.GEN_ONOFF, server_client=BLE_Mesh.SERVER, *, callback=None, value=None, sen_min=-100, sen_max=100, sen_res=0.1)
+
+This API creates a new BLE_Mesh_Model object. The BLE_Mesh_Model on concept level is equivalent to the Model in the BLE Mesh terminology.
+
+* `type` is the type of the new Model.
+* `server_client` shows whether the new Model will act as a Server or Client.
+* `callback` is the user defined callback to call when any event happens on the Model. It accepts 3 parameters: `new_state`, `event`, `op_code`. The `new_state` is the corresponding state of BLE_Mesh_Model, the `event` and the `op_code` are belonging of the BLE Mesh packet received.
+* `value` is the initial value represented by the Model.
+* `sen_min` is the minimum value of Sensor State in case of Sensor Model.
+* `sen_max` is the maximum value of Sensor State in case of Sensor Model.
+* `sen_res` is the resolution of Sensor State in case of Sensor Model.
+
+## Methods of BLE_Mesh_Model object
+
+#### BLE_Mesh_Model.get_state(addr=BLE_Mesh.ADDR_ALL_NODES, app_idx=0, state_type=None)
+
+Gets the State of the Sensor Model. If called from Server Model, returnes with State, in case of Client Model, it sends a Get Message, and returns State through the registered callback.
+
+* `addr` is the address of the remote Node to send the update message.
+* `app_idx` is the index of one of the registered Application IDs to use when sending out the message.
+* `state_type` is the type of Get State.
+
+#### BLE_Mesh_Model.set_state(state, addr=BLE_Mesh.ADDR_ALL_NODES, app_idx=0, state_type=None)
+
+Sets the State of the Sensor Model. If called from Server Model, sets State directly, in case of Client Model, it sends a Set Message, and updates State.
+
+* `state` is the new value to update the current value with.
+* `addr` is the address of the remote Node to send the update message.
+* `app_idx` is the index of one of the registered Application IDs to use when sending out the message.
+* `state_type` is the type of Set State.
+
+#### BLE_Mesh_Model.status_state(addr=BLE_Mesh.ADDR_ALL_NODES, app_idx=0, state_type=None)
+
+Calling this function only makes sense when the BLE_Mesh_Model is a Server Model. It sends a Status message with the State to the Client Model(s).
+
+* `addr` is the address of the remote Node to send the update message.
+* `app_idx` is the index of one of the registered Application IDs to use when sending out the message.
+* `state_type` is the type of Status State.
+
+## Constants
+
+* Advertisement options: `BLE_Mesh.PROV_ADV`, `BLE_Mesh.PROV_GATT`, `BLE_Mesh.PROV_NONE`
+* Features of an Element: `BLE_Mesh.RELAY`, `BLE_Mesh.LOW_POWER`, `BLE_Mesh.GATT_PROXY`, `BLE_Mesh.FRIEND`
+* Authentication options: `BLE_Mesh.OOB_INPUT`, `BLE_Mesh.OOB_OUTPUT`
+* Constants for Node addresses: `BLE_Mesh.ADDR_ALL_NODES`, `BLE_Mesh.ADDR_PUBLISH`
+* Constants for Model - type: `BLE_Mesh.GEN_ONOFF`, `BLE_Mesh.GEN_LEVEL`, `BLE_Mesh.GEN_SENSOR`, `BLE_Mesh.GEN_SENSOR_SETUP`
+* Constants for Model - server or client: `BLE_Mesh.SERVER`, `BLE_Mesh.CLIENT`
+* Constants for Model - states: `BLE_Mesh.STATE_ONOFF`, `BLE_Mesh.STATE_LEVEL`, `BLE_Mesh.STATE_LEVEL_DELTA`, `BLE_Mesh.STATE_LEVEL_MOVE`, `BLE_Mesh.SEN_DESCRIPTOR`, `BLE_Mesh.SEN`, `BLE_Mesh.SEN_COLUMN`, `BLE_Mesh.SEN_SERIES`, `BLE_Mesh.SEN_SET_CADENCE`, `BLE_Mesh.SEN_SETTINGS`, `BLE_Mesh.SEN_SETTING`
+* Constants for Provision Events: `BLE_Mesh.PROV_REGISTER_EVT`, `BLE_Mesh.PROV_ENABLE_EVT`, `BLE_Mesh.PROV_DISABLE_EVT`, `BLE_Mesh.LINK_OPEN_EVT`, `BLE_Mesh.LINK_CLOSE_EVT`, `BLE_Mesh.PROV_COMPLETE_EVT`, `BLE_Mesh.PROV_RESET_EVT`, `BLE_Mesh.PROV_OUTPUT_OOB_REQ_EVT`, `BLE_Mesh.PROV_INPUT_OOB_REQ_EVT`
diff --git a/content/firmwareapi/pycom/network/bluetooth/README.md b/content/firmwareapi/pycom/network/bluetooth/README.md
deleted file mode 100644
index 333d3bd..0000000
--- a/content/firmwareapi/pycom/network/bluetooth/README.md
+++ /dev/null
@@ -1,271 +0,0 @@
----
-title: "Bluetooth"
-aliases:
- - chapter/firmwareapi/pycom/network/bluetooth
----
-search: false
----
-
-# 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 it's free to be used for other things.
-
-Initialises and enables the Bluetooth radio in BLE mode.
-
-{{% hint style="info" %}}
-To use an external antenna, set `P12 as output pin.`
-
-```python
-
-Pin('P12', mode=Pin.OUT)(True)
-```
-{{% /hint %}}
-
-### 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 there's 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`.
-
-Connections are initiated by the central device. There is a maximum of 4 simultaneous connections.
-
-```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 won't 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`
-
diff --git a/content/firmwareapi/pycom/network/bluetooth/_index.md b/content/firmwareapi/pycom/network/bluetooth/_index.md
index 421bd03..43cd33b 100644
--- a/content/firmwareapi/pycom/network/bluetooth/_index.md
+++ b/content/firmwareapi/pycom/network/bluetooth/_index.md
@@ -47,14 +47,13 @@ GAP allows for devices to take various roles but generic flow works with devices
## Constructors
-### class network.Bluetooth(id=0, ...)
+#### 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()
```
@@ -76,16 +75,7 @@ With our development boards it defaults to using the internal antenna, but in th
Initialises and enables the Bluetooth radio in BLE mode.
-{{% hint style="info" %}}
-To use an external antenna, set `P12 as output pin.`
-
-```python
-
-Pin('P12', mode=Pin.OUT)(True)
-```
-{{% /hint %}}
-
-### bluetooth.deinit()
+#### bluetooth.deinit()
Disables the Bluetooth radio.
diff --git a/content/firmwareapi/pycom/network/bluetooth/gattccharacteristic.md b/content/firmwareapi/pycom/network/bluetooth/gattccharacteristic.md
index 9eef49c..6a60c47 100644
--- a/content/firmwareapi/pycom/network/bluetooth/gattccharacteristic.md
+++ b/content/firmwareapi/pycom/network/bluetooth/gattccharacteristic.md
@@ -48,3 +48,25 @@ This method allows to register for notifications on the characteristic.
* `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.
+#### characteristic.read\_descriptor(uuid)
+
+Returns the value of the descriptor specified by the `uuid` parameter. If no descriptor found for the characteristic returns None.
+
+```python
+descriptor = char.read_descriptor(0x2900)
+if(descriptor != None):
+ print("Characteristic Extended Properties: " + str(binascii.hexlify((descriptor))))
+
+descriptor = char.read_descriptor(0x2901)
+if(descriptor != None):
+ print("Characteristic User Description: " + str(binascii.hexlify((descriptor))))
+
+descriptor = char.read_descriptor(0x2902)
+if(descriptor != None):
+ print("Client Characteristic Configuration: " + str(binascii.hexlify((descriptor))))
+
+descriptor = char.read_descriptor(0x2904)
+if(descriptor != None):
+ print("Characteristic Presentation Format: " + str(binascii.hexlify((descriptor))))
+```
+
diff --git a/content/firmwareapi/pycom/network/eth.md b/content/firmwareapi/pycom/network/eth.md
new file mode 100644
index 0000000..2e307de
--- /dev/null
+++ b/content/firmwareapi/pycom/network/eth.md
@@ -0,0 +1,70 @@
+---
+title: "Ethernet"
+aliases:
+ - firmwareapi/pycom/network/eth.html
+ - firmwareapi/pycom/network/eth.md
+ - chapter/firmwareapi/pycom/network/eth
+---
+
+The ETH class enables the use of an ethernet connection via the PyEthernet board plugged into a Pygate.
+
+---
+*NOTE* :
+Ethernet support is only available in the Pygate firmware build.
+
+---
+
+*NOTE2* :
+The PyEthernet board is connected via SPI bus 3 and GPIO's 17-19 and 21-23. So this bus and pins cannot be used concurrently with ethernet. This also means that on a LoPy4 with Pygate firmware, the LoRa module of the LoPy4 is disabled, since it is also connected via SPI 3. Of course you can still use the LoRa gateway functionality since this uses the LoRa modules on the the Pygate board itself.
+
+---
+
+## Constructors
+
+### class network.ETH(id=0, ...)
+
+Create and configure an ETH object. See init for params of configuration.
+
+```python
+from network import ETH
+eth = ETH()
+```
+
+## Methods
+
+
+### eth.init(hostname=None)
+
+This function starts the Ethernet interface and enables the ethernet adapter.
+
+`hostname`: set the interface hostname
+
+### eth.ifconfig(config=\['dhcp' or configtuple\])
+
+With no parameters given, this returns a 4-tuple of (ip, subnet mask, gateway, DNS server).
+
+Optionally specify the configuration parameter:
+
+- `config='dhcp'`
+
+If 'dhcp' is passed as a parameter, then the DHCP client is enabled and the IP parameters are negotiated with the DHCP server.
+
+- `config=(ip, nm, gw, dns)`
+
+If the 4-tuple config is given then a static IP is configured. For example: `eth.ifconfig(config=('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))`.
+
+### eth.hostname(string)
+
+Set the interface host name.
+
+### eth.mac()
+
+Get the ethernet interface mac address.
+
+### eth.deinit()
+
+Shuts down the ethernet interface.
+
+### eth.isconnected()
+
+Returns `True` if the ethernet link is up and IP is accquired, `False` otherwise.
diff --git a/content/firmwareapi/pycom/network/lte.md b/content/firmwareapi/pycom/network/lte.md
index 2d29443..9ca1ced 100644
--- a/content/firmwareapi/pycom/network/lte.md
+++ b/content/firmwareapi/pycom/network/lte.md
@@ -54,9 +54,21 @@ lte = LTE()
## Methods
-#### lte.init(\*, carrier=None)
+#### lte.init(\*, carrier=None, psm_period_value=0, psm_period_unit=LTE.PSM_PERIOD_DISABLED, psm_active_value=0, psm_active_unit=LTE.PSM_ACTIVE_DISABLED )
+
+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 you can 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.
+
+For *Power Saving Mode* (PSM), you can use the following four arguments:
+
+- `psm_period_value` : Configure at which period the device will connect to the network. Values from 0 to 31 are allowed.
+- `psm_period_unit` : Specify the _unit_ to be used for `psm_period_value`.
+- `psm_active_value` : Configure how long the device will be connected. Values from 0 to 31 are allowed.
+- `psm_active_unit` : Specify the _unit_ for `psm_active_value`.
+
+The LTE specification defines the _units_ for configuring PSM. See the [constants](#constants) below. Also see the [PSM example](/tutorials/lte/power) in the tutorials.
-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(detach=True, reset = False)
@@ -66,12 +78,18 @@ Disables LTE modem completely. This reduces the power consumption to the minimum
- `reset` : reset LTE modem.
+#### lte.psm()
+
+Query the PSM timers. The return value is a 5-tuple with the following structure: `(enabled, period_value, period_unit, active_value, active_unit)`.
+
#### lte.attach(\*, band=None, apn=None, cid=None, type=LTE.IP, legacyattach=True)
Enable radio functionality and attach to the LTE network authorised by the inserted SIM card. Optionally specify:
- `band` : to scan for networks. If no band (or `None`) is specified, all 8 bands will be scanned. The possible values for the band are: `3, 4, 5, 8, 12, 13, 20 and 28`.
+- `bands` : similar to `band`, but specify a set of bands to scan. E.g. `bands=(8,20)`.
+
- `apn` : Specify the APN (Access point Name).
- `cid` : connection ID, see `LTE.connect()`. when the ID is set here it will be remembered when doint connect so no need to specify again
@@ -204,8 +222,13 @@ Check Network Coverage for UE device (i.e LTE modem).
`False`: No Netwok Coverage.
-## Constants
+## Constants
- `LTE.IP` : Internet Protocol IP
- `LTE.IPV4V6` : Internet protocol ver. 4/6
+
+- `PSM_PERIOD_2S`, `PSM_PERIOD_30S`, `PSM_PERIOD_1M`, `PSM_PERIOD_10M`, `PSM_PERIOD_1H`, `PSM_PERIOD_10H`, `PSM_PERIOD_320H`: Specify the unit for the PSM period to be 2 seconds, 30 seconds, 1 minute, 10 minutes, 1 hour, 10 hours, or 320 hours, respectively.
+- `PSM_PERIOD_DISABLED`: Specifying the unit for PSM period of `PSM_PERIOD_DISABLED` means turning PSM off.
+- `PSM_ACTIVE_2S`, `PSM_ACTIVE_1M`, `PSM_ACTIVE_6M`: Specify the unit for the PSM active duration to be 2 seconds, 1 minute, or 6 minutes, respectively.
+- `PSM_ACTIVE_DISABLED`: Specifying the active duration unit of `PSM_ACTIVE_DISABLED` means turning PSM off.
diff --git a/content/firmwareapi/pycom/network/sigfox.md b/content/firmwareapi/pycom/network/sigfox.md
index 2094f5d..ced6216 100644
--- a/content/firmwareapi/pycom/network/sigfox.md
+++ b/content/firmwareapi/pycom/network/sigfox.md
@@ -9,12 +9,11 @@ aliases:
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.
+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))
@@ -28,7 +27,6 @@ This class provides a driver for the Sigfox network processor in the Sigfox enab
## Quick Usage Example
```python
-
from network import Sigfox
import socket
@@ -59,7 +57,6 @@ Please ensure that there is an antenna connected to your device before sending/r
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)
@@ -68,7 +65,7 @@ sigfox = Sigfox(mode=Sigfox.FSK, frequency=912000000)
```
{{% hint style="info" %}}
-Sigfox.FSK mode is not supported on LoPy 4 and FiPy.
+`Sigfox.FSK` mode is not supported on LoPy 4 and FiPy.
{{% /hint %}}
## Methods
@@ -107,7 +104,6 @@ Returns a byte object with the 8-Byte bytes object with the Sigfox PAC.
To return human-readable values you should import `ubinascii` and convert binary values to hexidecimal representation. For example:
```python
-
print(ubinascii.hexlify(sigfox.mac()))
```
{{% /hint %}}
@@ -121,7 +117,6 @@ Returns a tuple of the form: `(uplink_frequency_hz, downlink_frequency_hz)`
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)
@@ -145,7 +140,6 @@ sigfox.public_key()
Sigfox sockets are created in the following way:
```python
-
import socket
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
```
@@ -163,7 +157,6 @@ Use it to close an existing socket.
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]))
@@ -176,7 +169,6 @@ s.send('Hello')
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)
```
@@ -186,7 +178,6 @@ s.recv(64)
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)
@@ -206,7 +197,6 @@ 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)
@@ -228,14 +218,12 @@ If the socket is set to blocking, your code will be wait until the socket comple
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)
@@ -261,13 +249,12 @@ print(ubinascii.hexlify(r))
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.
+`Sigfox.FSK` mode is not supported on LoPy 4 and FiPy.
{{% /hint %}}
**Device 1**:
```python
-
sigfox = Sigfox(mode=Sigfox.FSK, frequency=868000000)
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
@@ -282,7 +269,6 @@ while True:
**Device 2**:
```python
-
sigfox = Sigfox(mode=Sigfox.FSK, frequency=868000000)
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
diff --git a/content/firmwareapi/pycom/network/wlan.md b/content/firmwareapi/pycom/network/wlan.md
index ac4fc2b..0b651bb 100644
--- a/content/firmwareapi/pycom/network/wlan.md
+++ b/content/firmwareapi/pycom/network/wlan.md
@@ -5,11 +5,9 @@ aliases:
- firmwareapi/pycom/network/wlan.md
- chapter/firmwareapi/pycom/network/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
@@ -25,7 +23,6 @@ print(wlan.ifconfig())
## Quick Usage Example
```python
-
import machine
from network import WLAN
@@ -42,9 +39,9 @@ print(wlan.ifconfig())
## Constructors
-#### class network.WLAN(id=0, ...)
+### 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.
+Create a WLAN object, and optionally configure it. See [`init`](../wlan#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.
@@ -52,7 +49,7 @@ The WLAN constructor is special in the sense that if no arguments besides the `i
## Methods
-#### wlan.init(mode, \* , ssid=None, auth=None, channel=1, antenna=None, power\_save=False, hidden=False)
+#### wlan.init(mode, \* , ssid=None, auth=None, channel=1, antenna=None, power\_save=False, hidden=False, bandwidth=HT40, max\_tx\_pwr=20, country=CN)
Set or get the WiFi network processor configuration.
@@ -69,11 +66,13 @@ Arguments are:
* `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`.
+* `bandwidth` is the Bandwidth to use, either 20MHz or 40 MHz , use `HT20` or `HT40`
+* `max_tx_pwr` is the maximum WiFi Tx power allowed. see `WLAN.max_tx_power()` for more details
+* `country` tuple representing the country configuration parameters. see `WLAN.country()` for more details
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)
```
@@ -81,25 +80,15 @@ wlan.init(mode=WLAN.AP, ssid='wipy-wlan', auth=(WLAN.WPA2,'www.wipy.io'), channe
or
```python
-
# configure as an station
wlan.init(mode=WLAN.STA)
```
-{{% hint style="info" %}}
-To use an external antenna, set `P12 as output pin.`
-
-```python
-
-Pin('P12', mode=Pin.OUT)(True)
-```
-{{% /hint %}}
-
-#### wlan.deinit()
+### wlan.deinit()
Disables the WiFi radio.
-#### wlan.connect(ssid, \* , auth=None, bssid=None, timeout=None, ca\_certs=None, keyfile=None, certfile=None, identity=None)
+### wlan.connect(ssid, \* , auth=None, bssid=None, timeout=None, ca\_certs=None, keyfile=None, certfile=None, identity=None, hostname=None)
Connect to a wifi access point using the given SSID, and other security parameters.
@@ -112,24 +101,48 @@ Connect to a wifi access point using the given SSID, and other security paramete
* `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.
+* `hostname` is the name of the host connecting to the AP. Max length of name string is 32 Bytes
{{% 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.
{{% /hint %}}
-#### wlan.scan()
+#### wlan.scan(\[ssid=NULL, bssid=NULL, channel=0, show\_hidden=False, type=WLAN.SCAN\_ACTIVE, scantime=120ms\])
-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.
+Performs a network scan and returns a list of named tuples with (ssid, bssid, sec, channel, rssi). When no config args passed scan will be performed with default configurations.
-#### wlan.disconnect()
+Note: For Fast scan mode ssid/bssid and channel should be
+
+* `ssid` : If the SSID is not NULL, it is only the AP with the same SSID that can be scanned.
+* `bssid` : If the BSSID is not NULL, it is only the AP with the same BSSID that can be scanned. The bssid is given as 6 Hexadecimal bytes literals (i.e b'\xff\xff\xff\xff\xff\xff')
+* `channel` : If “channel” is 0, there will be an all-channel scan; otherwise, there will be a specific-channel scan.
+* `show_hidden` : If “show\_hidden” is 0, the scan ignores the AP with a hidden SSID; otherwise, the scan considers the hidden AP a normal one.
+* `type` : If “type” is `WLAN.SCAN_ACTIVE`, the scan is “active”; otherwise, it is a “passive” one.
+ * Active Scan is performed by sending a probe request. The default scan is an active scan
+ * Passive Scan sends no probe request. Just switch to the specific channel and wait for a beacon.
+* `scantime` :
+
+ This field is used to control how long the scan dwells on each channel. For passive scans, scantime=\[int\] designates the dwell time for each channel.
+
+ For active scans, dwell times for each channel are listed below. scantime is given as a tuple for min and max times (min,max)
+
+min=0, max=0: scan dwells on each channel for 120 ms.
+
+min>0, max=0: scan dwells on each channel for 120 ms.
+
+min=0, max>0: scan dwells on each channel for max ms.
+
+min>0, max>0: The minimum time the scan dwells on each channel is min ms. If no AP is found during this time frame, the scan switches to the next channel. Otherwise, the scan dwells on the channel for max ms.If you want to improve the performance of the the scan, you can try to modify these two parameters.
+
+### wlan.disconnect()
Disconnect from the WiFi access point.
-#### wlan.isconnected()
+### 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\])
+### 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.
@@ -140,45 +153,245 @@ If `dhcp` is passed as a parameter then the DHCP client is enabled and the IP pa
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\])
+### wlan.mode(\[mode\])
Get or set the WLAN mode.
-#### wlan.ssid(\[ssid\])
+### wlan.ssid(\[ssid\])
-Get or set the SSID when in AP mode.
+Get or set the SSID (Set SSID of AP).
-#### wlan.auth(\[auth\])
+In case if mode = `WLAN.STA` this method can get the ssid of AP the board is connected to.
+
+In case of mode = `WLAN.AP` this method can get the ssid of the board's own AP.
+
+In case of mode = `WLAN.STA_AP` this method can get the ssid of board's own AP plus the AP the STA is connected to in form of a tuple:
+
+_\_
+
+### wlan.auth(\[auth\])
Get or set the authentication type when in AP mode.
-#### wlan.channel(\[channel\])
+### wlan.channel(\[channel, sec\_chn\])
-Get or set the channel (only applicable in AP mode).
+_In AP mode:_
-#### wlan.antenna(\[antenna\])
+Get or set the wifi channel
+
+_In STA mode:_
+
+`channel`: is the primary channel to listen to.
+
+`sec_chn` : Only in case of Bandwidth = HT40 this should specify the position of the secondary channel weather above or below primary channel. `WLAN.SEC_CHN_POS_ABOVE` or `WLAN.SEC_CHN_POS_BELOW`
+
+_Note: Setting Channel in STA mode is only Allowed in Promiscuous mode_
+
+### wlan.antenna(\[antenna\])
Get or set the antenna type (external or internal).
-{{% hint style="info" %}}
-To use an external antenna, set `P12 as output pin.`
+### wlan.mac(\[mac, mode\])
+
+when no arguments are passed a 6-byte long `bytes` tuple object with the WiFI MAC address of both Wifi Station mode and Acces Point mode
+
+`mac`: a 6 bytes bytearray mac address
+
+`mode`: The Interface to set the given MAC address to `WLAN.STA` or `WLAN.AP`
+
+Ex: To set the mac address of Wifi Station mode:
```python
-
-Pin('P12', mode=Pin.OUT)(True)
+wlan.mac(bytearray([0xAE, 0x77, 0x88, 0x99, 0x22, 0x44]), WLAN.STA)
```
-{{% /hint %}}
-#### wlan.mac()
+_Note: STA and AP cannot have the Same Mac Address_
-Get a 6-byte long `bytes` object with the WiFI MAC address.
+### wlan.bandwidth()
+
+Set the bandwidth of the wifi, either 20 MHz or 40 MHz can be configured, use constants `HT20` or `HT40`
+
+### wlan.hostname()
+
+Set the Host name of the device connecting to the AP in case of Wifi `mode=WLAN.STA`, in case of `mode=WLAN.AP` this is the name of the host hosting the AP. Max length of name string is 32 Bytes
+
+### wlan.ap\_sta\_list()
+
+Gets an info list of all stations connected to the board's AP.
+
+Info returned is a list of tuples containning (\[mac address of connected STA\], \[average rssi value\], \[Wlan protocol enabled by STA\]).
+
+Protocol types are either : `WLAN.PHY_11_B`, `WLAN.PHY_11_G`, `WLAN.PHY_11_N` or `WLAN.PHY_LOW_RATE`
+
+### wlan.max\_tx\_power(\[power\])
+
+Gets or Sets the maximum allowable transmission power for wifi.
+
+Packets of different rates are transmitted in different powers according to the configuration in phy init data. This API only sets maximum WiFi transmiting power. If this API is called, the transmiting power of every packet will be less than or equal to the value set by this API. Default is Level 0.
+
+Values passed in power are mapped to transmit power levels as follows:
+
+* \[78, 127\]: level0
+* \[76, 77\]: level1
+* \[74, 75\]: level2
+* \[68, 73\]: level3
+* \[60, 67\]: level4
+* \[52, 59\]: level5
+* \[44, 51\]: level5 - 2dBm
+* \[34, 43\]: level5 - 4.5dBm
+* \[28, 33\]: level5 - 6dBm
+* \[20, 27\]: level5 - 8dBm
+* \[8, 19\]: level5 - 11dBm
+* \[-128, 7\]: level5 - 14dBm
+
+### wlan.country(\[country, schan, nchan, max\_tx\_pwr, policy\])
+
+Gets or set s Country configuration parameters for wifi.
+
+* `country` That is the country name code , it is max 2 characters string representing the country eg: "CN" for china nad "NL" for Netherlands
+* `scahn` is the start channel number, in scan process scanning will be performed starting from this channels till the total number of channels. it should be less than or equal 14.
+* `nchan` is the total number of channels in the specified country. maximum is 14
+* `max_tx_pwr` Maximum transmission power allowed. see `WLAN.max_tx_power()` for more details.
+* `policy` Is the method when setting country configuration for `WLAN.COUNTRY_POL_AUTO` in STA mode the wifi will aquire the same country config of the connected AP, for `WLAN.COUNTRY_POL_MAN` the configured country parameters will take effect regardless of Connected AP.
+
+### wlan.joined\_ap\_info()
+
+Returns a tuple with (bssid, ssid, primary channel, rssi, Authorization method, wifi standard used) of the connected AP in case of STA mode.
+
+### wlan.wifi\_protocol(\[(bool PHY11\_\_B, bool PHY11\_G, bool PHY11\_N)\])
+
+Sets or gets Wifi Protocol supported.
+
+### wlan.send\_raw(Buffer, interface=STA, use\_sys\_seq=True)
+
+Send raw data through the Wifi Interface.
+
+`Buffer`: Buffer of bytes object Containning Data to be transmitted. Data should not be greater than 1500 nor smaller than 24.
+
+`interface`: The Interface to use for transmitting Data AP or STA in case the mode used is APSTA. other wise the interface currently active will be used.
+
+`use_sys_seq`: `True` to use the systems next sequance number for sending the data, `False` for keeping the sequance number in the given raw data buffer unchanged.
+
+### wlan.callback(trigger, handler=Null, arg=Null)
+
+Register a user callback function `handler` to be called once any of the `trigger` events occures optionally with a passed `arg`. by default the wlan obj is passed as arg to the handler. To unregister the callback you can call the `wlan.callback` function with empty `handler` and `arg` parameters.
+
+For trigger events see `Constants` section.
+
+### wlan.promiscuous(\[bool\])
+
+* To enable Promiscuous mode `WLAN.promiscuous(True)` should be called, and `WLAN.promiscuous(False)` for disabling
+* To get current mode setting call function with empty args
+
+Note:
+
+* Promiscuous mode should be enabled for Wifi packets types Events to be triggered
+* for changing wifi channel via `wlan.channel()` promiscuous mode should be enabled.
+
+Example using promoscious mode:
+
+```python
+from network import WLAN
+import ubinascii
+
+def pack_cb(pack):
+ mac = bytearray(6)
+ pk = wlan.wifi_packet()
+ control = pk.data[0]
+ subtype = (0xF0 & control) >> 4
+ type = 0x0C & control
+ #print("Control:{}, subtype:{}, type:{}".format(control, subtype, type))
+ if subtype == 4:
+ for i in range (0,6):
+ mac[i] = pk.data[10 + i]
+ print ("Wifi Node with MAC: {}".format(ubinascii.hexlify(mac)))
+
+wlan = WLAN(mode=WLAN.STA, antenna=WLAN.EXT_ANT)
+wlan.callback(trigger=WLAN.EVENT_PKT_MGMT, handler=pack_cb)
+wlan.promiscuous(True)
+```
+
+### wlan.events()
+
+This function will return an integer object as mask for triggered events.
+
+### wlan.wifi\_packet()
+
+This function will return a tuble with Wifi packet info captured in promiscuous mode.
+
+### wlan.ctrl\_pkt\_filter(\[int\])
+
+This function is used to set the filter mask for Wifi control packets in promiscuous mode. for Filter masks, see `Constants` section.
+
+To get the current Filter mask, call the function with empty args.
+
+### wlan.smartConfig\(\)
+
+Start SmartConfig operation, the smartConfig is a provisioning technique that enables setting Wifi credentials for station mode wirelessly via mobile app.
+
+####Steps:
+- call **wlan.smartConfig()** \(if smartConfig is not enabled on boot or you want to restart smartConfig\)
+- Use mobile App (ESP touch or Pycom App) to set ssid and password for the AP
+- You can register a callback to be triggered when smart Config is Finesed successfuly or timedout.
+
+### wlan.Connected\_ap\_pwd()
+
+Get the password of AP the Device is connected to.
+
+### wlan.ap\_tcpip\_sta\_list()
+
+This API returns with a list of the devices connected to the Pycom board when it is in AP mode.
+Each element of the returned list is a tuple, containing the MAC address and IP address of the device.
## 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`
+* WLAN Bandwidth: `WLAN.HT20`, `WLAN.HT40`
+* WLAN protocol: `WLAN.PHY_11_B`, `WLAN.PHY_11_G`, `WLAN.PHY_11_N`, `WLAN.PHY_LOW_RATE`
+* Scan Type: `WLAN.SCAN_ACTIVE` `WLAN.SCAN_PASSIVE`
+* WLAN country config policy: `WLAN.COUNTRY_POL_AUTO`, `WLAN.COUNTRY_POL_MAN`
+* Secondary Channel position: `WLAN.SEC_CHN_POS_ABOVE`, `WLAN.SEC_CHN_POS_BELOW`
+* Wlan callback triggers:
+
+ `WLAN.EVENT_PKT_MGMT`: Managment packet recieved in promiscuous mode.
+
+ `WLAN.EVENT_PKT_CTRL`: Control Packet recieved in promiscuous mode
+
+ `WLAN.EVENT_PKT_DATA`: Data packet recieved in promiscuous mode
+
+ `WLAN.EVENT_PKT_DATA_MPDU`: MPDU data packet recieved in promiscuous mode
+
+ `WLAN.EVENT_PKT_DATA_AMPDU`: AMPDU data packet recieved in promiscuous mode
+
+ `WLAN.EVENT_PKT_MISC`: misc paket recieved in promiscuous mode.
+
+ `WLAN.EVENT_PKT_ANY`: Any packet recieved in promiscuous mode.
+
+ `SMART_CONF_DONE`: Smart Config of wifi ssid/pwd Finished
+
+ `SMART_CONF_TIEMOUT`: Smart Config of wifi ssid/pwd timed-out
+
+* Control packet filters in promiscuous mode:
+
+ `WLAN.FILTER_CTRL_PKT_ALL`: Filter all Control packets
+
+ `WLAN.FILTER_CTRL_PKT_WRAPPER`: Filter control wrapper packets
+
+ `WLAN.FILTER_CTRL_PKT_BAR`: Filter Control BAR packets
+
+ `WLAN.FILTER_CTRL_PKT_BA`: Filter Control BA packets
+
+ `WLAN.FILTER_CTRL_PKT_PSPOLL`: Filter Control PSPOLL Packets
+
+ `WLAN.FILTER_CTRL_PKT_CTS`: Filter Control CTS packets
+
+ `WLAN.FILTER_CTRL_PKT_ACK`: Filter Control ACK packets
+
+ `WLAN.FILTER_CTRL_PKT_CFEND`: Filter Control CFEND Packets
+
+ `WLAN.FILTER_CTRL_PKT_CFENDACK`: Filter Control CFENDACK Packets
diff --git a/content/firmwareapi/pycom/pycom.md b/content/firmwareapi/pycom/pycom.md
index bb5daa3..fbb363f 100644
--- a/content/firmwareapi/pycom/pycom.md
+++ b/content/firmwareapi/pycom/pycom.md
@@ -11,7 +11,6 @@ The `pycom` module contains functions to control specific features of the Pycom
## Quick Usage Example
```python
-
import pycom
pycom.heartbeat(False) # disable the heartbeat LED
@@ -22,11 +21,11 @@ pycom.rgbled(0xff00) # make the LED light up in green color
## Methods
-#### pycom.heartbeat(\[enable\])
+#### pycom.heartbeat\(\[boolean\]\)
Get or set the state (enabled or disabled) of the heartbeat LED. Accepts and returns boolean values (`True` or `False`).
-#### pycom.heartbeat\_on\_boot(\[enable\])
+#### pycom.heartbeat\_on\_boot\(\[boolean\]\)
Allows you permanently disable or enable the heartbeat LED. Once this setting is set, it will persist between reboots. Note, this only comes into effect on the next boot, it does not stop the already running heartbeat.
@@ -39,7 +38,6 @@ Set the colour of the RGB LED. The colour is specified as 24 bit value represent
Set the value of the specified key in the NVRAM memory area of the external flash. Data stored here is preserved across resets and power cycles. Value can only take 32-bit integers at the moment. Example:
```python
-
import pycom
pycom.nvs_set('temp', 25)
@@ -51,7 +49,6 @@ pycom.nvs_set('count', 10)
Get the value the specified key from the NVRAM memory area of the external flash. Example:
```python
-
import pycom
pulses = pycom.nvs_get('count')
@@ -67,50 +64,78 @@ Erase the given key from the NVRAM memory area.
Erase the entire NVRAM memory area.
-#### pycom.wifi\_on\_boot(\[enable\])
+#### pycom.wifi\_on\_boot\(\[boolean\]\)
-Get or set the WiFi on boot flag. When this flag is set to `True`, the AP with the default SSID (`lopy-wlan-xxx` for example) will be enabled as part of the boot process. If the flag is set to False, the module will boot with WiFi disabled until it's enabled by the script via the `WLAN` class. This setting is stored in non-volatile memory which preserves it across resets and power cycles. Example:
+Get or set the WiFi on boot flag. When this flag is set to `True`, The Wifi will be enabled according to the other wifi settings eg (ssid\_sta, pwd\_sta, ssid\_ap, pwd\_ap). when `False` the Wifi module will be disabled untill enabled directly via WLAN class.
+
+This setting is stored in non-volatile memory which preserves it across resets and power cycles. Example:
```python
-
import pycom
pycom.wifi_on_boot(True) # enable WiFi on boot
pycom.wifi_on_boot() # get the wifi on boot flag
```
-#### pycom.wdt\_on\_boot(\[enable\])
+#### pycom.wifi\_ssid\_sta\([ssid]\)
-Enables the WDT at boot time with the timeout in ms set by the function `wdt_on_boot_timeout`. If this flag is set, the application needs to reconfigure the WDT with a new timeout and feed it regularly to avoid a reset.
+Get or set the ssid of the Access point the device should connect to on startup.
+This setting is stored in non-volatile memory which preserves it across resets and power cycles
-```python
+#### pycom.wifi\_ssid\_ap\([ssid]\)
-import pycom
+Get or set the ssid of the Access point that should be started by the device at startup, if not set and startup Wifi mode is AP the default AP name \(\-wlan-\\) will be used.This setting is stored in non-volatile memory which preserves it across resets and power cycles
-pycom.wdt_on_boot(True) # enable WDT on boot
-pycom.wdt_on_boot() # get the WDT on boot flag
-```
+#### pycom.wifi\_pwd\_sta\([key]\)
+
+Get or set the Password of the Access point the device should connect to on startup, leave the password unset if the AP is open.This setting is stored in non-volatile memory which preserves it across resets and power cycles
+
+#### pycom.wifi\_pwd\_ap\([key]\)
+
+Get or set the Password of the Access point that should be started by the device at startup, leave unset if the AP should be open.This setting is stored in non-volatile memory which preserves it across resets and power cycles
+
+#### pycom.smart\_config\_on\_boot\([boolean]\)
+
+Read or (Enable/Disable) SmartConfig functionality on startup, this flag will be reset after successful completion of the smartConfig process after startup.This setting is stored in non-volatile memory which preserves it across resets and power cycles
+
+#### pycom.smart\_config\_on\_boot\([boolean]\)
+
+Read or (Enable/Disable) SmartConfig functionality on startup, this flag will be reset after successful completion of the smartConfig process after startup.This setting is stored in non-volatile memory which preserves it across resets and power cycles
+
+#### pycom.wifi\_mode\_on\_boot\(\[boolean\]\)
+
+Set or get the Wifi Mode at startup , `WLAN.STA`, `WLAN.AP` or `WLAN.APSTA`.This setting is stored in non-volatile memory which preserves it across resets and power cycles
#### pycom.wdt\_on\_boot\_timeout(\[timeout\])
Sets or gets the WDT on boot timeout in milliseconds. The minimum value is 5000 ms.
```python
-
import pycom
pycom.wdt_on_boot_timeout(10000) # set the timeout to 5000ms
pycom.wdt_on_boot_timeout() # get the WDT timeout value
```
-#### pycom.pulses\_get(pin, timeout)
+#### pycom.wdt\_on\_boot\(\[enable\]\)
+
+Enables the WDT at boot time with the timeout in ms set by the function `wdt_on_boot_timeout`. If this flag is set, the application needs to reconfigure the WDT with a new timeout and feed it regularly to avoid a reset
+
+
+```python
+import pycom
+
+pycom.wdt_on_boot(True) # enable WDT on boot
+pycom.wdt_on_boot() # get the WDT on boot flag
+```
+
+#### pycom.pulses\_get\(pin, timeout\)
Return a list of pulses at `pin`. The methods scans for transitions at `pin` and returns a list of tuples, each telling the pin value and the duration in microseconds of that value. `pin` is a pin object, which must have set to `INP` or `OPEN_DRAIN` mode. The scan stops if not transitions occurs within `timeout` milliseconds.
Example:
```python
-
# get the raw data from a DHT11/DHT22/AM2302 sensor
from machine import Pin
from pycom import pulses_get
@@ -134,7 +159,6 @@ Perform a firmware update. These methods are internally used by a firmware updat
Example:
```python
-
# Firmware update by reading the image from the SD card
#
from pycom import ota_start, ota_write, ota_finish
@@ -165,3 +189,13 @@ with open(APPIMG, "rb") as f:
Instead of reading the data to be written from a file, it can obviously also be received from a server using any suitable protocol, without the need to store it in the devices file system.
+#### pycom.bootmgr(boot\_partition=pycom.FACTORY, fs\_type=FAT, safeboot=False, reset=False)
+
+* `boot_partition` This is to set the partition to boot from , this could be set to either `pycom.FACTORY` or `pycom.OTA_0`
+* `fs_type` This is to set the filesystem to use for the flash memory (`/flash`). This could be set to `pycom.FAT` for FAT16 or `pycom.LittleFS` for LittleFS filesystem.
+
+ _Note: When the firmware is built with option_ `FS_USE_LITTLEFS` _the file system for_ `/flash` _is forced to be LittleFS._
+
+* `safeboot` Enable or Disable safemoot mode.
+* `reset` Set `True` to reset target after updating the `bootmgr` options , `False` for not resetting.
+
diff --git a/content/gettingstarted/registration/lora/_index.md b/content/gettingstarted/registration/lora/_index.md
index 47f5854..a8138a0 100644
--- a/content/gettingstarted/registration/lora/_index.md
+++ b/content/gettingstarted/registration/lora/_index.md
@@ -16,8 +16,6 @@ In order to connect your LoRa capable Pycom module to a LoRaWAN network you will
Firstly you will need to get your modules `Device EUI`, this can be achieved using the following code:
```python
-
-
from network import LoRa
import ubinascii
diff --git a/content/pymesh/_index.md b/content/pymesh/_index.md
index ebca14b..daec1bc 100644
--- a/content/pymesh/_index.md
+++ b/content/pymesh/_index.md
@@ -17,6 +17,8 @@ Pymesh works on all of our LoRa supporting development boards, the LoPy4 and FiP
_**Note: For obtaining the Pymesh firmware please follow the steps from [Pymesh LICENCE page](/pymesh/licence).**_
+_**Note: For obtaining the Pymesh firmware please follow the steps from [Pymesh LICENCE page](/pymesh/licence).**_
+
## What does Pymesh offer you?
* An ad-hoc communication network over raw-LoRa radio
diff --git a/content/tutorials/all/PoE.md b/content/tutorials/all/PoE.md
new file mode 100644
index 0000000..2394a21
--- /dev/null
+++ b/content/tutorials/all/PoE.md
@@ -0,0 +1,22 @@
+---
+title: "PoE"
+aliases:
+ - tutorials/all/PoE.html
+ - tutorials/all/PoE.md
+ - chapter/tutorials/all/PoE
+---
+
+The PyEthernet module has onboard Power over Ethernet (PoE) power supply. This means that you can power your hardware with only an ethernet cable coming from a power injector. However, since the PoE is non-isolated, you must adhere to the following warning!
+
+WARNING:
+
+PoE power supply of PyEthernet module has no galvanic isolation. This means, that in accordance with
+IEEE 802.3-2005 standard you must make sure that when powered from PoE power injector there are no other external connections to any part of the module or other hardware where it is installed. Such as USB cable, serial to USB bridge, logic analyser, an oscilloscope, etc.
+
+As in certain hardware configurations it can lead to unrecoverable damage of not only the PyEthernet module but all hardware connected to it.
+
+Be aware - violation of that requirement voids Pycom warranty.
+
+The use of battery with PoE is allowed.
+
+
diff --git a/content/tutorials/all/PyGate.md b/content/tutorials/all/PyGate.md
new file mode 100644
index 0000000..e29202e
--- /dev/null
+++ b/content/tutorials/all/PyGate.md
@@ -0,0 +1,278 @@
+## Pygate
+
+The Pygate is an 8-channel LoRaWAN gateway. This page will help you get started with it.
+
+The Pygate board can have an PyEthernet adapter connected which allows an ethernet connection. The PyEthernet also support PoE. Do check the separate [page and warning for PoE-NI!](/tutorials/all/poe)
+
+### Quickstart
+
+To connect your Pygate to a LoRa server, follow these steps:
+
+1. Attach a WiPy, GPy or LoPy4 to the Pygate. The RGB LED of the development board should be aligned with the USB port of the Pygate.
+1. Attach the LoRa Antenna to the Pygate.
+1. Flash the Pycom Device with with a firmware build where Pygate functionality is enabled.
+1. Create a `config.json` for your Pygate and upload it.
+1. Create a `main.py` that creates an uplink (wifi, ethernet or lte) and runs the LoRa packet fowarder.
+1. Run the `main.py`.
+1. Now it is operational. The communication from other LoRa nodes such as a LoPy4 will now reach the gateway and will receive up and downlink via the PyGate.
+1. To stop the Pygate at any time press Ctrl-C on the REPL and run `machine.pygate_deinit()`. It will take a few seconds to stop the gateway tasks and safely power-off the concentrator.
+
+
+Make sure you supply a config matching your region (EU868, US915, etc), e.g. https://github.com/Lora-net/packet_forwarder/tree/master/lora_pkt_fwd/cfg. If you are in EU region, it should be sufficent to update the example below with your GW ID, the LoRa server address and port number.
+
+
+### Example TTN Wifi
+
+The following example shows the script and json file to run the Pygate over Wifi connecting to [The Things Network](https://www.thethingsnetwork.org/).
+
+1. log in to https://console.thethingsnetwork.org/
+1. go to Gateways and register a new gateway
+1. select "I'm using a legacy packet forwarder"
+1. make up a EUI (8 byte hexadecimal value) and register it on the TTN website
+1. enter the EUI in your `config.json` under `gateway_ID` (Just enter the hex digits without the "eui-" prefix and without spaces)
+1. select your Frequency Plan
+1. select a router - also enter the hostname in your `config.json` under `server_address`
+1. enter your wifi SSID and password in `main.py`
+1. upload `config.json` and `main.py` and reset the board
+1. you will see how it creates the uplink connection and then start the LoRa GW. It will print out some debug information while it is running. After some initialization it will print "LoRa GW started" and the LED will turn green.
+
+
+
+```python
+from network import WLAN
+import time
+import machine
+from machine import RTC
+import pycom
+
+# Disable Hearbeat
+pycom.heartbeat(False)
+
+# Define callback function for Pygate events
+def machine_cb (arg):
+ evt = machine.events()
+ if (evt & machine.PYGATE_START_EVT):
+ # Green
+ pycom.rgbled(0x103300)
+ elif (evt & machine.PYGATE_ERROR_EVT):
+ # Red
+ pycom.rgbled(0x331000)
+ elif (evt & machine.PYGATE_STOP_EVT):
+ # RGB off
+ pycom.rgbled(0x000000)
+
+# register callback function
+machine.callback(trigger = (machine.PYGATE_START_EVT | machine.PYGATE_STOP_EVT | machine.PYGATE_ERROR_EVT), handler=machine_cb)
+
+# Connect to a Wifi Network
+wlan = WLAN(mode=WLAN.STA)
+wlan.connect(ssid='', auth=(WLAN.WPA2, ""))
+
+while not wlan.isconnected():
+ time.sleep(1)
+
+print("Wifi Connection established")
+
+# Sync time via NTP server for GW timestamps on Events
+rtc = RTC()
+rtc.ntp_sync(server="0.pool.ntp.org")
+
+# Read the GW config file from Filesystem
+fp = open('/flash/config.json','r')
+buf = fp.read()
+
+# Start the Pygate
+machine.pygate_init(buf)
+
+```
+
+A sample `config.json` file for gateway configuration in EU868 region:
+
+```json
+{
+ "SX1301_conf": {
+ "lorawan_public": true,
+ "clksrc": 1,
+ "antenna_gain": 0,
+ "radio_0": {
+ "enable": true,
+ "type": "SX1257",
+ "freq": 867500000,
+ "rssi_offset": -164.0,
+ "tx_enable": true,
+ "tx_freq_min": 863000000,
+ "tx_freq_max": 870000000
+ },
+ "radio_1": {
+ "enable": true,
+ "type": "SX1257",
+ "freq": 868500000,
+ "rssi_offset": -164.0,
+ "tx_enable": false
+ },
+ "chan_multiSF_0": {
+ "enable": true,
+ "radio": 1,
+ "if": -400000
+ },
+ "chan_multiSF_1": {
+ "enable": true,
+ "radio": 1,
+ "if": -200000
+ },
+ "chan_multiSF_2": {
+ "enable": true,
+ "radio": 1,
+ "if": 0
+ },
+ "chan_multiSF_3": {
+ "enable": true,
+ "radio": 0,
+ "if": -400000
+ },
+ "chan_multiSF_4": {
+ "enable": true,
+ "radio": 0,
+ "if": -200000
+ },
+ "chan_multiSF_5": {
+ "enable": true,
+ "radio": 0,
+ "if": 0
+ },
+ "chan_multiSF_6": {
+ "enable": true,
+ "radio": 0,
+ "if": 200000
+ },
+ "chan_multiSF_7": {
+ "enable": true,
+ "radio": 0,
+ "if": 400000
+ },
+ "chan_Lora_std": {
+ "enable": true,
+ "radio": 1,
+ "if": -200000,
+ "bandwidth": 250000,
+ "spread_factor": 7
+ },
+ "chan_FSK": {
+ "enable": true,
+ "radio": 1,
+ "if": 300000,
+ "bandwidth": 125000,
+ "datarate": 50000
+ },
+ "tx_lut_0": {
+ "pa_gain": 0,
+ "mix_gain": 5,
+ "rf_power": 9,
+ "dig_gain": 3
+ },
+ "tx_lut_1": {
+ "pa_gain": 0,
+ "mix_gain": 5,
+ "rf_power": 9,
+ "dig_gain": 3
+ },
+ "tx_lut_2": {
+ "pa_gain": 0,
+ "mix_gain": 5,
+ "rf_power": 9,
+ "dig_gain": 3
+ },
+ "tx_lut_3": {
+ "pa_gain": 0,
+ "mix_gain": 5,
+ "rf_power": 9,
+ "dig_gain": 3
+ },
+ "tx_lut_4": {
+ "pa_gain": 0,
+ "mix_gain": 5,
+ "rf_power": 9,
+ "dig_gain": 3
+ },
+ "tx_lut_5": {
+ "pa_gain": 0,
+ "mix_gain": 5,
+ "rf_power": 9,
+ "dig_gain": 3
+ },
+ "tx_lut_6": {
+ "pa_gain": 0,
+ "mix_gain": 5,
+ "rf_power": 9,
+ "dig_gain": 3
+ },
+ "tx_lut_7": {
+ "pa_gain": 0,
+ "mix_gain": 6,
+ "rf_power": 11,
+ "dig_gain": 3
+ },
+ "tx_lut_8": {
+ "pa_gain": 0,
+ "mix_gain": 5,
+ "rf_power": 13,
+ "dig_gain": 2
+ },
+ "tx_lut_9": {
+ "pa_gain": 0,
+ "mix_gain": 8,
+ "rf_power": 14,
+ "dig_gain": 3
+ },
+ "tx_lut_10": {
+ "pa_gain": 0,
+ "mix_gain": 6,
+ "rf_power": 15,
+ "dig_gain": 2
+ },
+ "tx_lut_11": {
+ "pa_gain": 0,
+ "mix_gain": 6,
+ "rf_power": 16,
+ "dig_gain": 1
+ },
+ "tx_lut_12": {
+ "pa_gain": 0,
+ "mix_gain": 9,
+ "rf_power": 17,
+ "dig_gain": 3
+ },
+ "tx_lut_13": {
+ "pa_gain": 0,
+ "mix_gain": 10,
+ "rf_power": 18,
+ "dig_gain": 3
+ },
+ "tx_lut_14": {
+ "pa_gain": 0,
+ "mix_gain": 11,
+ "rf_power": 19,
+ "dig_gain": 3
+ },
+ "tx_lut_15": {
+ "pa_gain": 0,
+ "mix_gain": 12,
+ "rf_power": 20,
+ "dig_gain": 3
+ }
+ },
+
+ "gateway_conf": {
+ "gateway_ID": "XXXXXXXXXXXXXXXX",
+ "server_address": "router.eu.thethings.network",
+ "serv_port_up": 1700,
+ "serv_port_down": 1700,
+ "keepalive_interval": 10,
+ "stat_interval": 30,
+ "push_timeout_ms": 100,
+ "forward_crc_valid": true,
+ "forward_crc_error": false,
+ "forward_crc_disabled": false
+ }
+}
+```
diff --git a/content/tutorials/all/ble_mesh.md b/content/tutorials/all/ble_mesh.md
new file mode 100644
index 0000000..4eae0fb
--- /dev/null
+++ b/content/tutorials/all/ble_mesh.md
@@ -0,0 +1,253 @@
+---
+title: "Pymesh BLE Examples"
+aliases:
+ - tutorials/all/ble_mesh.html
+ - tutorials/all/ble_mesh.md
+ - chapter/tutorials/all/ble_mesh
+---
+
+Pymesh BLE module enables many-to-many device connections, based on the Bluetooth module.
+
+For the API, please check the section [Pymesh BLE API](/firmwareapi/pycom/network/bluetooth/ble_mesh/).
+
+## Generic OnOff Example
+Generic OnOff model is one of the simplest model in BLE Mesh.
+
+This model illustrates the light-switches (OnOff Client) and light-bulbs (OnOff Server). In other words, the Client can send on/off commands to one/all nodes, and the Server is records state changes based on these commands.
+
+### OnOff Server
+
+OnOff Server has one boolean State. Server can Get, Set or send Status about this State to Client(s).
+
+In the example below, during Provisioning, `Output OOB` can be selected. LED is yellow in case of Not-provisioned, and green in case of Provisioned state.
+
+Changing the State of Server, LED's light is green or red.
+
+```python
+from network import Bluetooth
+import pycom
+import time
+
+BLE_Name = "OnOff Server 18"
+
+def blink_led(n):
+ for x in range(n):
+ pycom.rgbled(0xffff00) # yellow on
+ time.sleep(0.3)
+ pycom.rgbled(0x000000) # off
+ time.sleep(0.3)
+
+def server_cb(new_state, event, recv_op):
+ print("SERVER | State: ", new_state)
+
+ # Turn on LED on board based on State
+ if new_state == True:
+ pycom.rgbled(0x007f00) # green
+ else:
+ pycom.rgbled(0x7f0000) # red
+
+def prov_callback(event, oob_pass):
+ if(event == BLE_Mesh.PROV_REGISTER_EVT or event == BLE_Mesh.PROV_RESET_EVT):
+ # Yellow if not Provision yet or Reseted
+ pycom.rgbled(0x555500)
+ if(event == BLE_Mesh.PROV_COMPLETE_EVT):
+ # Green if Provisioned
+ pycom.rgbled(0x007f00)
+ if(event == BLE_Mesh.PROV_OUTPUT_OOB_REQ_EVT):
+ print("Privisioning blink LED num:", oob_pass)
+ blink_led(oob_pass)
+
+# BLE Mesh module
+BLE_Mesh = Bluetooth.BLE_Mesh
+
+# Turn off the heartbeat behavior of the LED
+pycom.heartbeat(False)
+
+# Need to turn ON Bluetooth before using BLE Mesh
+bluetooth = Bluetooth()
+
+# Create a Primary Element with GATT Proxy feature and add a Server model to the Element
+element = BLE_Mesh.create_element(primary=True, feature=BLE_Mesh.GATT_PROXY)
+model_server = element.add_model(BLE_Mesh.GEN_ONOFF, BLE_Mesh.SERVER, callback=server_cb)
+
+# Initialize BLE_Mesh
+BLE_Mesh.init(BLE_Name, auth=BLE_Mesh.OOB_OUTPUT, callback=prov_callback)
+
+# Turn on Provisioning Advertisement
+BLE_Mesh.set_node_prov(BLE_Mesh.PROV_ADV|BLE_Mesh.PROV_GATT)
+
+print("\nBLE Mesh started")
+print(BLE_Name, "waits to be provisioned\n")
+
+"""
+# After this node was provisioned
+# Current state can be read using
+model_server.get_state()
+"""
+```
+
+### OnOff Client
+
+Client can Get or Set State of Server. In case of Get, or Server Status, Client Gets the Status through the Model's callback.
+
+```python
+from network import Bluetooth
+import pycom
+import time
+
+BLE_Name = "OnOff Client 17"
+
+def blink_led(n):
+ for x in range(n):
+ pycom.rgbled(0xffff00) # yellow on
+ time.sleep(0.3)
+ pycom.rgbled(0x000000) # off
+ time.sleep(0.3)
+
+def client_cb(new_state, event, recv_op):
+ print("CLIENT | State: ", new_state)
+
+def prov_callback(event, oob_pass):
+ if(event == BLE_Mesh.PROV_REGISTER_EVT or event == BLE_Mesh.PROV_RESET_EVT):
+ # Yellow if not Provision yet or Reseted
+ pycom.rgbled(0x555500)
+ if(event == BLE_Mesh.PROV_COMPLETE_EVT):
+ # Green if Provisioned
+ pycom.rgbled(0x007f00)
+ if(event == BLE_Mesh.PROV_OUTPUT_OOB_REQ_EVT):
+ print("Privisioning blink LED num:", oob_pass)
+ blink_led(oob_pass)
+
+# BLE Mesh module
+BLE_Mesh = Bluetooth.BLE_Mesh
+
+# Turn off the heartbeat behavior of the LED
+pycom.heartbeat(False)
+
+# Need to turn ON Bluetooth before using BLE Mesh
+bluetooth = Bluetooth()
+
+# Create a Primary Element with GATT Proxy feature and add a Server model to the Element
+element = BLE_Mesh.create_element(primary=True, feature=BLE_Mesh.GATT_PROXY)
+model_client = element.add_model(BLE_Mesh.GEN_ONOFF, BLE_Mesh.CLIENT, callback=client_cb)
+
+# Initialize BLE_Mesh
+BLE_Mesh.init(BLE_Name, auth=BLE_Mesh.OOB_OUTPUT, callback=prov_callback)
+
+# Turn on Provisioning Advertisement
+BLE_Mesh.set_node_prov(BLE_Mesh.PROV_ADV|BLE_Mesh.PROV_GATT)
+
+print("\nBLE Mesh started")
+print(BLE_Name, "waits to be provisioned\n")
+
+"""
+# After this node was provisioned
+# transmit the change of state broadcasting in the Mesh
+
+model_client.set_state(False, 0xFFFF)
+model_client.set_state(True, 0xFFFF)
+
+# or to a unique server
+model_client.set_state(False, 3)
+model_client.set_state(True, 5)
+
+"""
+```
+
+## Sensor Example
+In case of Sensor Models, State of Server can be modified only by Server itself, Client can only Get the State by calling Client's Get, or by Servers Status call, but cannot modify the Server's State.
+
+### Sensor Server
+In this example Server takes a time measurement every 1 seconds, and send a Status message every 5 seconds, after it was provisioned.
+
+```python
+from network import Bluetooth
+import pycom
+import time
+from machine import Timer
+
+def read_sensor(alarm):
+ # In this example sensor reads local seconds
+ if(device_provisioned):
+ model_server.set_state(time.localtime()[5])
+ print("SENSOR | State: ", model_server.get_state())
+
+def status_sensor(alarm):
+ if (device_provisioned):
+ model_server.status_state()
+
+def prov_callback(event, oob_pass):
+ global device_provisioned
+ if(event == BLE_Mesh.PROV_REGISTER_EVT or event == BLE_Mesh.PROV_RESET_EVT):
+ # Yellow if not Provision yet or Reseted
+ pycom.rgbled(0x555500)
+ device_provisioned = False
+ if(event == BLE_Mesh.PROV_COMPLETE_EVT):
+ # Green if Provisioned
+ pycom.rgbled(0x007f00)
+ device_provisioned = True
+
+# BLE Mesh module
+BLE_Mesh = Bluetooth.BLE_Mesh
+
+# Turn off the heartbeat behavior of the LED
+pycom.heartbeat(False)
+
+# Need to turn ON Bluetooth before using BLE Mesh
+bluetooth = Bluetooth()
+
+# Create a Primary Element with GATT Proxy feature and add a Server model to the Element
+element = BLE_Mesh.create_element(primary=True, feature=BLE_Mesh.GATT_PROXY)
+model_server = element.add_model(BLE_Mesh.SENSOR, BLE_Mesh.SERVER, sen_min = 0, sen_max = 59, sen_res = 1)
+
+# Initialize BLE_Mesh
+BLE_Mesh.init("Pycom Sensor Server", callback=prov_callback)
+
+# Turn on Provisioning Advertisement
+BLE_Mesh.set_node_prov(BLE_Mesh.PROV_ADV|BLE_Mesh.PROV_GATT)
+
+# Sensor takes measurement every 1 second
+Timer.Alarm(read_sensor, 1, periodic=True)
+
+# Sensor send status every 5 seconds
+Timer.Alarm(status_sensor, 5, periodic=True)
+```
+
+### Sensor Client
+
+Sensor Client is looking for measurements, as Server sends Status every 5 seconds. Between these calls, Client can Get message any time.
+
+```python
+from network import Bluetooth
+import pycom
+
+def client_cb(new_state, event, recv_op):
+ print("CLIENT | State: ", new_state)
+
+def prov_callback(event, oob_pass):
+ if(event == BLE_Mesh.PROV_REGISTER_EVT or event == BLE_Mesh.PROV_RESET_EVT):
+ # Yellow if not Provision yet or Reseted
+ pycom.rgbled(0x555500)
+ if(event == BLE_Mesh.PROV_COMPLETE_EVT):
+ # Green if Provisioned
+ pycom.rgbled(0x007f00)
+
+# BLE Mesh module
+BLE_Mesh = Bluetooth.BLE_Mesh
+
+# Turn off the heartbeat behavior of the LED
+pycom.heartbeat(False)
+
+# Need to turn ON Bluetooth before using BLE Mesh
+bluetooth = Bluetooth()
+
+# Create a Primary Element with GATT Proxy feature and add a Server model to the Element
+element = BLE_Mesh.create_element(primary=True, feature=BLE_Mesh.GATT_PROXY)
+model_client = element.add_model(BLE_Mesh.SENSOR, BLE_Mesh.CLIENT, callback=client_cb, sen_min = 0, sen_max = 59, sen_res = 1)
+
+# Initialize BLE_Mesh
+BLE_Mesh.init("Pycom Sensor Client", callback=prov_callback)
+
+# Turn on Provisioning Advertisement
+BLE_Mesh.set_node_prov(BLE_Mesh.PROV_ADV|BLE_Mesh.PROV_GATT)
+```
diff --git a/content/tutorials/lte/_index.md b/content/tutorials/lte/_index.md
index a4b2427..6d600e6 100644
--- a/content/tutorials/lte/_index.md
+++ b/content/tutorials/lte/_index.md
@@ -1,9 +1,9 @@
---
title: "LTE Examples"
aliases:
+ - chapter/tutorials/lte
---
The following tutorials demonstrate the use of the LTE CAT-M1 and NB-IoT functionality on cellular enabled Pycom modules.
Our cellular modules support both LTE CAT-M1 and NB-IoT, these are new lower power, long range, cellular protocols. These are not the same as the full version of 2G/3G/LTE supported by cell phones, and require your local carriers to support them. At the time of writing, CAT-M1 and NB-IoT connectivity is not widely available so be sure to check with local carriers if support is available where you are.
-
diff --git a/content/tutorials/lte/power.md b/content/tutorials/lte/power.md
new file mode 100644
index 0000000..913fc42
--- /dev/null
+++ b/content/tutorials/lte/power.md
@@ -0,0 +1,100 @@
+---
+title: "LTE power consumption"
+aliases:
+ - tutorials/lte/power.html
+ - tutorials/lte/power.md
+ - chapter/tutorials/power
+---
+
+There are some trade offs one can do to reduce power consumption of the LTE modem. You can limit connectivity in exchange for saving power consumption.
+
+Let's start with the simplest choice: Turn off or not. It's not very sophisticated, but for completeness, let's start with this:
+
+
+## Turn LTE modem off
+
+```python
+
+from network import LTE
+import time
+import socket
+import machine
+import pycom
+
+def attach():
+ start = time.time()
+ if lte.isattached():
+ print("already attached")
+ else:
+ print("attach")
+ lte.attach(band=20, apn="the.apn.to.be.used.with.your.simcard")
+ while not lte.isattached():
+ time.sleep(1)
+ print("attached after", time.time() - start, "seconds")
+ print(lte.psm())
+
+def connect():
+ print("connect")
+ start = time.time()
+ lte.connect()
+ while not lte.isconnected():
+ time.sleep(0.5)
+ print("connected after", time.time() - start, "seconds")
+
+def http_get(url = 'http://detectportal.firefox.com/'):
+ _, _, host, path = url.split('/', 3)
+ addr = socket.getaddrinfo(host, 80)[0][-1]
+ s = socket.socket()
+ s.connect(addr)
+ s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8'))
+ s.close()
+
+# main
+lte = LTE()
+attach()
+connect()
+http_get()
+print("deinit")
+lte.deinit()
+print("deepsleep")
+machine.deepsleep(55 * 60 * 1000) # 55m
+```
+
+The example above is the simple case where we attach, connect, communicate and then turn the LTE modem off: `lte.deinit()`. This will make sure the LTE modem uses minimal power after the deinit. However, it means that the subsequent attach procedure after waking up will take some seconds. During this attach time the modem already consumes power.
+
+## Leave LTE modem on
+
+Depending on your use case, you may want to save the time (and energy) for reattching that you get after [turning the modem off](#lte-power-off).
+If your device communicates a lot, then you can choose to not turn it off at all, save the time for the reattach. However, you then trade the higher power consumption during any idle time. For this, simply remove the deinit from the example:
+
+
+```python
+# lte.deinit()
+```
+
+## Power Saving Mode
+
+A more sophisticated configuration, is the _Power Saving Mode_. PSM allows you to configure the period how often the device will connect and how long it will stay actively connected. During the sleep
+- the LTE modem will go into a low power state, but
+- it will stay attached to the network, thus no time is spent for `attach()` after waking up.
+
+Note that the network needs to cooperate in this, so first there is a negotiation where you propose timers. Then you attach and the network will decide which timers to actually apply. Afterwards you can query the effective values.
+
+So you see, here you not only need to make the trade off what is best for your application, but you will also need to do some testing to see which values your provider offers you and how this works out in your application in practise.
+
+For the following example, assume you want to wake up once per hour, connect and do some processing, then go to deepsleep for 55 minutes. We would adjust the main part of the example as follows:
+
+```python
+# main
+# period 1h, active 10s
+lte = LTE(psm_period_value=1, psm_period_unit=LTE.PSM_PERIOD_1H,
+ psm_active_value=5, psm_active_unit=LTE.PSM_ACTIVE_2S )
+print(lte.psm())
+attach()
+connect()
+http_get()
+print("deinit")
+lte.deinit(detach=False, reset=False)
+print("deepsleep")
+machine.deepsleep(55 * 60 * 1000) # 55m
+```
diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html
index ebe3b45..a18e023 100644
--- a/layouts/_default/baseof.html
+++ b/layouts/_default/baseof.html
@@ -17,7 +17,6 @@
-
{{ partial "menu.html" . }}
{{- partial "toolbar.html" . -}}
@@ -47,8 +46,8 @@
drawer2: true,
toc: 0,
branches: [
- { value: 'https://docs.pycom.io', text: 'version stable', },
{ value: 'https://development.pycom.io', text: 'version development'},
+ { value: 'https://docs.pycom.io', text: 'version stable', },
],
branch: ""
},
@@ -93,6 +92,5 @@
{{- partial "alexia.html" . -}}
-{{- partial "google_analitycs.html" . -}}