Перейти к содержанию
Материалы раздела

Сеть

Настройка и включение сети

  1. Настройте интерфейс.

    -- Настройка Wi-Fi
    net.wf.setup(...)
    
  2. Запустите интерфейс.

    -- Запуск Wi-Fi
    net.wf.start()
    
  3. Взаимодействуйте с сетью, например, создайте экземпляр клиента MQTT и опубликуйте несколько сообщений.

  4. Остановите интерфейс.

    -- Остановка Wi-Fi
    net.wf.stop()
    

net.connected()

Проверьте доступность сети. Сеть доступна, если один из сетевых интерфейсов включен и имеет IP-адрес.

Аргументы: нет.

Возвращает: true, если сеть доступна, false, если не доступна, или исключение.

net.stat([table])

Получите сетевую информацию для всех доступных интерфейсов.

Аргументы:

  • table: если true, сетевая информация помещается в таблицу Lua, если false — информация выводится на консоль.

Возвращает:

  • если table равно false: ничего или исключение.

  • если table равно true: таблицу Lua с сетевой информацией или исключение. Эта таблица является массивом таблиц. Каждая запись соответствует интерфейсу, и каждый интерфейс имеет следующие поля:

    • interface: имя интерфейса (wf = Wi-Fi, en = Ethernet).
    • ip: IP интерфейса.
    • gw: IP шлюза интерфейса.
    • netmask: маска подсети интерфейса.
    • mac: MAC-адрес интерфейса.
/ > net.stat()
wf: mac address 24:0a:c4:00:c9:5c
   ip address 192.168.1.41 netmask 255.255.255.0
   gw address 192.168.1.1
net.stat(true)

ip = net.packip(ip1, ip2, ip3, ip4)

Возвращает представление IPv4-адреса в пакетной форме, которое можно использовать со всеми функциями модуля net, требующими IP-адрес в качестве аргумента. IP-адрес предоставляется из 4 элементов, составляющих IPv4-адрес: ip1.ip2.ip3.ip4

Аргументы:

  • ip1: первая часть IP-адреса
  • ip2: вторая часть IP-адреса
  • ip3: третья часть IP-адреса
  • ip4: четвертая часть IP-адреса

Возвращает: целое число, кодирующее IP-адрес.

localhost = net.packip(127,0,0,1)
print(localhost)
16777343

ip = net.packip(“ip”)

Возвращает представление IPv4-адреса в пакетной форме, которое можно использовать со всеми функциями модуля net, требующими IP-адрес в качестве аргумента. IP-адрес предоставляется в каноническом представлении IPv4.

Аргументы:

  • ip: строка IP-адреса в каноническом представлении IPv4.

Возвращает: целое число, кодирующее IP-адрес.

localhost = net.packip("127.0.0.1")
print(localhost)
16777343

ip1, ip2, ip3, ip4 = net.unpackip(ip, ‘*n’)

Возвращает распакованное представление IPv4-адреса, упакованного функцией net.packip. Распакованное представление предоставляется 4 элементами, составляющими IPv4-адрес.

Аргументы:

  • ip: упакованный IP-адрес

Возвращает:

  • ip1: первая часть IP-адреса
  • ip2: вторая часть IP-адреса
  • ip3: третья часть IP-адреса
  • ip4: четвертая часть IP-адреса
localhost = net.packip("127.0.0.1")
ip1, ip2, ip3, ip4 = net.unpackip(localhost, '*n')
print(ip1.." "..ip2.." "..ip3.." "..ip4)
127 0 0 1

ip = net.unpackip(ip, ‘*s’)

Возвращает распакованное представление IPv4-адреса, упакованного функцией net.packip. Распакованное представление IP-адреса предоставляется в каноническом представлении IPv4.

Аргументы:

  • ip: упакованный IP-адрес

Возвращает: строку IP-адреса в каноническом представлении IPv4.

localhost = net.packip("127.0.0.1")
ip = net.unpackip(localhost, '*s')
print(ip)
127.0.0.1

ip = net.lookup(hostname)

Выполняет поиск DNS.

Аргументы:

  • hostname: имя хоста, для которого выполняется поиск

Возвращает: упакованный IP-адрес хоста.

ip = net.lookup("whitecatboard.org")
print(net.unpackip(ip, "*s"))
207.148.248.143

Wi-Fi

net.wf.scan([table])

Выполняет сканирование Wi-Fi сетей.

Аргументы:

  • table: если true, результат сканирования возвращается в таблице Lua, если false — результат выводится на консоль.

Возвращает:

  • если table равно false: ничего или исключение.

  • если table равно true: таблицу Lua с результатами сканирования или исключение. Эта таблица представляет собой массив таблиц. Каждая запись соответствует станции. Каждая станция предоставляет следующие поля:

    • ssid: SSID точки доступа.
    • rssi: сила сигнала RSSI.
    • auth: тип авторизации. Может быть net.wf.auth.OPEN, net.wf.auth.WEP, net.wf.auth.WPA_PSK, net.wf.auth.WPA2_PSK или net.wf.auth.WPA_WPA2_PSK.
    • ch1: основной канал точки доступа
    • ch2: второстепенный канал точки доступа
-- Scan wifi, and print to the console
/ > net.wf.scan()


                           SSID  RSSI          AUTH  CH1  CH2
-------------------------------------------------------------
          Xarxa Wi-Fi de JAUME2   -43      WPA2_PSK    6    0
           Xarxa Wi-Fi de JAUME   -85  WPA_WPA2_PSK   11    0
-- Scan wifi, and get result into a table
scan = net.wf.scan(true)

net.wf.setup(net.wf.mode.STA, ssid, password, [ip, mask, gw, dns1, dns2, powersave, channel, hidden])

Настройка интерфейса Wi-Fi в режиме STA (станция / клиент).

Аргументы:

  • ssid: SSID сети для подключения.
  • password: пароль сети.
  • ip: IP-адрес в упакованном представлении. Используйте функцию net.packip для этого.
  • mask: сетевая маска в упакованном представлении. Используйте функцию net.packip для этого.
  • gw: IP-адрес шлюза в упакованном представлении. Используйте функцию net.packip для этого.
  • dns1 (необязательно): IP основного DNS-сервера для разрешения имен, в упакованном представлении. Используйте функцию net.packip для этого. Если этот аргумент не предоставлен, dns1 устанавливается на 8.8.8.8.
  • dns2 (необязательно): IP вторичного DNS-сервера для разрешения имен, в упакованном представлении. Используйте функцию net.packip для этого. Если этот аргумент не предоставлен, dns2 устанавливается на 8.8.4.4.
  • powersave (необязательно): энергосбережение. Может быть net.wf.powersave.NONE (не устанавливать энергосбережение) или net.wf.powersave.MODEM. Значение по умолчанию - net.wf.powersave.NONE.
  • channel (необязательно):
    • Начальный номер канала для подключения к точке доступа. Это натуральное число от 1 до 13. Установите значение 0, если канал точки доступа неизвестен.
    • Значение по умолчанию - 0.

Возвращает: ничего или исключение.

-- Setup a wifi connection using a dynamic IP
net.wf.setup(net.wf.mode.STA, "ssid", "password")
-- Setup a wifi connection using a static IP
-- ip: 172.16.209.224
-- net mask: 255.255.0.0
-- gw: 172.16.0.1
-- dns1: 8.8.8.8
-- dns2: 8.8.4.4
net.wf.setup(
   net.wf.mode.STA,
   "ssid",
   "password",
   net.packip(172,16,209,224), net.packip(255,255,255,0),
   net.packip(172,16,0,1),
   net.packip(8,8,8,8), net.packip(8,8,4,4)
)

net.wf.setup(net.wf.mode.AP, ssid, password, [powersave, channel, hidden])

Настройка интерфейса Wi-Fi в режиме AP (точка доступа).

Аргументы:

  • ssid: SSID сети для подключения.
  • password: пароль сети.
  • powersave (необязательно): энергосбережение. Может быть либо net.wf.powersave.NONE (не устанавливать энергосбережение) или net.wf.powersave.MODEM. Значение по умолчанию - net.wf.powersave.NONE.
  • channel (необязательно): номер канала, используемого точкой доступа Soft-AP. Это натуральное число от 1 до 13. Значение по умолчанию - 0.
  • hidden (необязательно): если true, SSID скрыт, если false, видим.

Возвращает: ничего или исключение.

net.wf.setup(net.wf.mode.STAENT, ssid [, identity, username, password, ca, cert, key, keypwd, timecheck, powersave, channel, hidden])

Настройка интерфейса Wi-Fi в режиме STA (станция/клиент), где точка доступа требует аутентификации WPA2 enterprise.

Аргументы:

  • ssid: SSID сети для подключения.
  • identity (необязательно): nil, пустая строка или требуемый идентификатор WPA2 enterprise.
  • username (необязательно): nil, пустая строка или требуемое имя пользователя WPA2 enterprise.
  • password (необязательно): nil, пустая строка или требуемый пароль WPA2 enterprise.
  • ca (необязательно): nil, пустая строка или /path/to/my-ca.pem.
  • cert (необязательно): nil, пустая строка или /path/to/my-client.crt.
  • key (необязательно): nil, пустая строка или /path/to/my-client.key.
  • keypwd (необязательно): nil, пустая строка или пароль для my-client.key.
  • timecheck (необязательно): одно из net.wf.timecheck.DEFAULT, net.wf.timecheck.ENABLE, net.wf.timecheck.DISABLE.
  • powersave (необязательно): энергосбережение. Может быть либо net.wf.powersave.NONE (не устанавливать энергосбережение) или net.wf.powersave.MODEM. Значение по умолчанию - net.wf.powersave.NONE.
  • channel (необязательно): номер канала, используемого точкой доступа Soft-AP. Это натуральное число от 1 до 13. Значение по умолчанию - 0.
  • hidden (необязательно): если true, SSID скрыт, если false, видим.

Возвращает: ничего или исключение.

net.wf.start([async])

Запуск интерфейса Wi-Fi.

Аргументы:

  • async (необязательно): если true, интерфейс запускается асинхронно (без ожидания получения IP), если false, интерфейс запускается синхронно. Если не указано, значение по умолчанию для этого аргумента - true.

Возвращает: ничего или исключение.

net.wf.stop()

Остановка интерфейса Wi-Fi.

Аргументы: нет.

Возвращает: ничего или исключение.

net.wf.wps(type [, callback])

Подключает устройство к Wi-Fi с помощью WPS вместо ручного ввода имени сети и пароля. Функция доступна не во всех прошивках; проверить её наличие можно непосредственно на устройстве.

Аргументы:

  • type: тип WPS. Может быть либо net.wf.wpstype.PBC или net.wf.wpstype.PIN.
  • callback (необязательно): обработчик, который получает PIN при type = net.wf.wpstype.PIN.

Ethernet

-- Setup an ethernet connection using a dynamic IP
net.en.setup()
-- Setup an ethernet connection using a static IP
-- ip: 192.168.1.200
-- net mask: 255.255.255.0
-- gw: 192.168.1.1
-- dns1: 8.8.8.8
-- dns2: 8.8.4.4
net.en.setup(
   net.packip(192,168,1,200), net.packip(255,255,255,0),
   net.packip(192,168,1,1),
   net.packip(8,8,8,8), net.packip(8,8,4,4)
)

net.en.setup()

Настройка Ethernet-соединения с динамическим IP. Настройки соединения получаются от сервера DHCP.

Аргументы: нет.

Возвращает: ничего или исключение.

-- Настройка Ethernet-соединения
net.en.setup()

net.en.start([async])

Запуск Ethernet-интерфейса.

Аргументы:

  • async (необязательно): если true, интерфейс запускается асинхронно (без ожидания получения IP), если false, интерфейс запускается синхронно. Если не указано, значение по умолчанию для этого аргумента - true.

Возвращает: ничего или исключение.

-- Настройка Ethernet-соединения
net.en.setup()

-- Запуск
net.en.start()

net.en.stop()

Остановка Ethernet-интерфейса.

Аргументы: нет.

Возвращает: ничего или исключение.

-- Setup an ethernet connection
net.en.setup()

-- Start
net.en.start()

-- ...

-- Stop
net.en.stop()

Утилиты

net.ping(host, count, interval, size, timeout)

Утилита net.ping используется для проверки доступности хоста в сети с использованием протокола IP (Internet Protocol). Аргументы:

  • host: это строка с именем хоста или его IP-адресом
  • count: количество посылок
  • interval: интервал между посылками
  • size: размер посылки
  • timeout: тайм-аут

Возвращает: ничего или исключение.

/ > net.ping("whitecatboard.org")
PING whitecatboard.org (5.196.211.36): 32 data bytes
60 bytes from 0.0.0.0: icmp_seq=1 time=37.567 ms
...
60 bytes from 0.0.0.0: icmp_seq=10 time=36.858 ms
10 packets transmitted, 10 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 36.479/36.897/37.567/0.251 ms
/ > net.ping("8.8.8.8")
PING 8.8.8.8 (8.8.8.8): 32 data bytes
60 bytes from 8.0.0.0: icmp_seq=1 time=27.440 ms
...
60 bytes from 8.0.0.0: icmp_seq=10 time=27.847 ms
10 packets transmitted, 10 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 27.440/27.762/27.853/0.140 ms

Пинг прерывается нажатием Ctrl-С.

ms = net.mping(host)

Выполняет одну проверку доступности хоста и возвращает время ответа. Аргументы:

  • host: имя хоста или IP-адрес.

Возвращает время отклика в миллисекундах, 0 при отсутствии ответа или вызывает исключение, если сеть недоступна.

/ > net.mping("whitecatboard.org")
202.892

host, resource, ssl, port = net.parseUrl(hostname)

Анализирует hostname и разбивает его на составные части.

Аргументы:

  • hostname: строка; имя хоста, который может быть представлен в виде ip, либо в виде url.

ip разбирается на host и port
url на host, resource, ssl, port

Возвращает:

  • host: строка; доменное имя или ip, в зависимости от того, что было задано в hostname
  • resource: строка; путь.
  • ssl: bool; true - для https.
  • port: число; если порт не указан явно, используется 80 для HTTP и 443 для HTTPS.

Пример:

/ > net.parseUrl("192.168.68.110")
192.168.68.110 /  nil   80
/ > net.parseUrl("https://192.168.68.110")
192.168.68.110 /  true  443
/ > net.parseUrl("http://google.com:5000/hello")
google.com  /hello   false 5000
/ > net.parseUrl("192.168.68.110:8000")
192.168.68.110 /  nil   8000
/ > net.parseUrl("http://google.com:5000")
google.com  /  false 5000
/ > net.parseUrl("https://google.com/")
google.com  /  true  443
/ > net.parseUrl("http://google.com")
google.com  /  false 80
/ > net.parseUrl("https://192.168.68.110:2000/hello/world")
192.168.68.110 /hello/world   true  2000

net.ota([server], [path], [project], [reboot], [check], [ssl], [ask])

Выполняет OTA (Over-The-Air) обновление прошивки устройства.

Аргументы:

  • server (опционально): строка; адрес сервера обновлений.
  • path (опционально): строка; путь к файлу прошивки на сервере.
  • project (опционально): строка; имя проекта.
  • reboot (опционально): boolean; true - перезагрузить устройство после обновления. По умолчанию: true.
  • check (опционально): boolean; true - проверить наличие обновления. По умолчанию: true.
  • ssl (опционально): boolean; true - использовать HTTPS. По умолчанию: true.
  • ask (опционально): boolean; true - только проверить наличие обновления и вернуть код ответа. По умолчанию: false.

Возвращает:

  • Если ask=true: число; код ответа сервера.
  • Иначе: ничего или исключение.
-- Проверить и установить обновление
net.ota("update.example.com", "/firmware", "myproject")

-- Только проверить наличие обновления
local code = net.ota("update.example.com", "/firmware", "myproject", false, true, true, true)

net.callback(func)

Устанавливает обработчик событий сетевых интерфейсов.

Аргументы:

  • func: функция, вызываемая при изменении состояния сети.

Обработчик получает таблицу с полями:

  • interface: строка; тип интерфейса (“wf” - Wi-Fi, “en” - Ethernet).
  • type: строка; тип события (“up” - сеть доступна, “down” - сеть недоступна).

Возвращает: ничего или исключение.

net.callback(function(event)
    print("Interface:", event.interface, "Event:", event.type)
    if event.type == "up" then
        print("Сеть доступна!")
    else
        print("Сеть недоступна!")
    end
end)

client = net.http.client(host, [ssl_en], [port], [timeout], [connect_timeout], [ca_cert])

Создать HTTP-клиент с постоянным соединением. Для HTTPS TLS-handshake выполняется при создании клиента, а последующие запросы к тому же host:port используют уже установленное соединение. Это основной способ уменьшить задержку при серии запросов.

Аргументы:

  • host: строка с именем хоста или его IP-адресом.
  • ssl_en (опционально): boolean; true — использовать HTTPS, false — HTTP. По умолчанию false.
  • port (опционально): порт. По умолчанию 443 при ssl_en = true, иначе 80.
  • timeout (опционально): тайм-аут операций чтения и отправки в миллисекундах. По умолчанию 3000.
  • connect_timeout (опционально): тайм-аут установки TCP- и TLS-соединения в секундах. По умолчанию 7.
  • ca_cert (опционально): путь к PEM-файлу доверенного CA или сам PEM-сертификат. Для HTTPS по умолчанию /certs/ca-certificates.crt.

Методы клиента:

  • code, ret = client:get(resource, [content_type], [custom_headers]) — выполнить GET.
  • code, ret = client:post(resource, [content_type], [custom_headers], [body]) — выполнить POST.
  • connected = client:connected() — проверить, открыт ли локальный сокет. Удалённое закрытие может обнаружиться только при следующем запросе.
  • client:close() — закрыть соединение и освободить TLS-ресурсы.

ret содержит таблицу частей ответа по 1024 байта и возвращается при непустом теле для любого HTTP-кода. Клиент поддерживает ответы с Content-Length, Transfer-Encoding: chunked и тело до закрытия соединения. Ответ всегда дочитывается полностью, чтобы соединение можно было безопасно использовать повторно.

Если сервер закрыл неактивное keep-alive-соединение без уведомления, GET автоматически переподключается и повторяется один раз. POST автоматически не повторяется: сервер мог успеть обработать запрос, поэтому скрытый повтор мог бы выполнить операцию дважды.

local client = net.http.client(
    "api.example.com", true, 443, 5000, 10,
    "/certs/ca-certificates.crt"
)

local ok, err = pcall(function()
    for id = 1, 10 do
        local code, chunks = client:get("/device/" .. id, "application/json")
        assert(code == 200, "HTTP " .. tostring(code))
        print(table.concat(chunks or {}))
    end
end)

client:close()
assert(ok, err)

Один объект клиента выполняет запросы последовательно. Не используйте один объект одновременно из нескольких Lua-задач.

code, ret = net.http.get(host, resource, content_type, [custom_headers], [ssl_en], [port], [timeout], [connect_timeout], [ca_cert])

Облегчённая версия HTTP GET. Функция создаёт и закрывает соединение на каждый вызов; для серии запросов используйте net.http.client.

Аргументы:

  • host: строка с именем хоста или его IP-адресом
  • resource: строка пути к ресурсу.
  • content_type: ожидаемый заголовок Content-Type. При nil заголовок не проверяется.
  • custom_headers (опционально): строка; дополнительные заголовки. Разделитель между заголовками: “\r\n”.
  • ssl_en (опционально): boolean; true — запрашивать по HTTPS, false — HTTP. По умолчанию false. Поддерживается TLS до версии 1.2.
  • port (опционально): порт. По умолчанию 443 при ssl_en = true, иначе 80.
  • timeout (опционально): тайм-аут операций чтения и отправки в миллисекундах. По умолчанию 3000.
  • connect_timeout (опционально): тайм-аут установки TCP- и TLS-соединения в секундах. По умолчанию 7.
  • ca_cert (опционально): путь к PEM-файлу доверенного CA или сам PEM-сертификат. Для HTTPS по умолчанию /certs/ca-certificates.crt.

Возвращает:

  • code: код ответа
  • ret: таблица со скаченным ответом, разбитым на части по 1024 байта. Возвращается только при коде ответа 200 и непустом теле. Либо исключение.
code, ret = net.http.get("192.168.0.1", "/index.html", "text/html")
print(table.concat(ret))

code = net.http.download(host, resource, content_type, custom_headers, filename, [overwrite], [ssl_en], [port], [timeout], [connect_timeout], [ca_cert])

Выполняет HTTP GET и сохраняет ответ в файл. Аргументы:

  • host: строка с именем хоста или его IP-адресом
  • resource: строка пути к ресурсу
  • content_type: ожидаемый заголовок Content-Type. При nil заголовок не проверяется.
  • custom_headers: строка либо nil; дополнительные заголовки. Разделитель между заголовками: “\r\n”.
  • filename: имя файла для сохранения
  • overwrite (опционально): boolean; true - перезаписывать файл, false - вызвать исключение, если файл существует. По умолчанию false.
  • ssl_en (опционально): boolean; true — запрашивать по HTTPS, false — HTTP. По умолчанию false. Поддерживается TLS до версии 1.2.
  • port (опционально): порт. По умолчанию 443 при ssl_en = true, иначе 80.
  • timeout (опционально): тайм-аут операций чтения и отправки в миллисекундах. По умолчанию 3000.
  • connect_timeout (опционально): тайм-аут установки TCP- и TLS-соединения в секундах. По умолчанию 5.
  • ca_cert (опционально): путь к PEM-файлу доверенного CA или сам PEM-сертификат. Для HTTPS по умолчанию /certs/ca-certificates.crt.

Возвращает:

  • code: код ответа Либо исключение.

Файл создается (перезаписывается) только при коде ответа 200 и непустом теле. При ошибке записи частично скачанный файл удаляется, если до вызова функции файла не существовало.

code = net.http.download("192.168.0.1", "/index.html", "text/html", nil, "index.html", false, false)

code, ret = net.http.post(host, resource, content_type, [custom_headers], [body], [ssl_en], [port], [timeout], [connect_timeout], [ca_cert])

Выполняет HTTP POST и возвращает ответ частями.

Аргументы:

  • host: строка с именем хоста или его IP-адресом
  • resource: строка пути к ресурсу
  • content_type: значение заголовка Content-Type
  • custom_headers (опционально): строка; дополнительные заголовки
  • body (опционально): строка; содержимое body запроса.
  • ssl_en (опционально): boolean; true — запрашивать по HTTPS, false — HTTP. По умолчанию false. Поддерживается TLS до версии 1.2.
  • port (опционально): порт. По умолчанию 443 при ssl_en = true, иначе 80.
  • timeout (опционально): тайм-аут операций чтения и отправки в миллисекундах. По умолчанию 3000.
  • connect_timeout (опционально): тайм-аут установки TCP- и TLS-соединения в секундах. По умолчанию 5.
  • ca_cert (опционально): путь к PEM-файлу доверенного CA или сам PEM-сертификат. Для HTTPS по умолчанию /certs/ca-certificates.crt.

Возвращает:

  • code: код ответа
  • ret: таблица со скаченным ответом, разбитым на части по 1024 байта. Возвращается только при коде ответа 200 и непустом теле. Либо исключение.
code, ret = net.http.post("192.168.0.101", "/", "application/json", "id: 12345\r\ntype:7", "body", false)

conn = net.udp.bind(port)

Создать UDP-сокет, привязанный к заданному порту.

Аргументы:

  • port: число; порт.

Возвращает объект соединения или вызывает исключение.

net.udp.sendto(host, port, data)

Отправить посылку по UDP (без создания объекта соединения).

Аргументы:

  • host: строка; адрес получателя.
  • port: число; порт.
  • data: строка; данные в строковом виде (строка допускает нули).

Возвращает: ничего или исключение.

res = conn:sendto(host, port, data)

Отправить посылку по UDP через объект соединения.

Аргументы:

  • host: строка; адрес получателя.
  • port: число; порт.
  • data: строка; данные в строковом виде (строка допускает нули).

Возвращает:

  • res: boolean; true в случае успеха, false в случае неудачи.

from_ip, from_port, data = conn:readfrom([maxlen])

Принять данные.

Аргументы:

  • maxlen (необязательно): число; максимальный ожидаемый размер данных. По умолчанию: 1024.

Возвращает:

  • from_ip: строка; ip-отправителя или nil, если данных нет.
  • from_port: число; порт-отправителя или nil, если данных нет.
  • data: строка; данные или nil. или исключение.

conn:close()

Закрыть UDP сокет.

Возвращает: ничего.

Пример:

local conn = net.udp.bind(5555)

while true do
    local from_ip, from_port, data = conn:readfrom(100)
    if from_ip then
        print(from_ip, from_port, data)
        -- Отправить ответ
        conn:sendto(from_ip, from_port, "ACK")
    end
end

conn:close()

res = net.tcp.sendto(host, port, data, [timeout_s], [ssl], [ca_cert])

Функция для однократной передачи данных: открывает tcp-подключение, передает данные, закрывает tcp-подключение.

Аргументы:

  • host: строка; адрес получателя.
  • port: число; порт.
  • data: строка; данные в строковом виде (строка допускает нули).
  • timeout_s (опционально): число в секундах; тайм-аут подключения. По умолчанию: 10.
  • ssl (опционально): boolean; true - использовать SSL/TLS шифрование.
  • ca_cert (опционально): путь к PEM-файлу доверенного CA или сам PEM-сертификат. Для TLS по умолчанию /certs/ca-certificates.crt.

Возвращает:

  • res: boolean; true - в случае успеха, false - иначе. или исключение.

Пример:

-- Обычное TCP-подключение
net.tcp.sendto("192.168.68.110", 5555, "hello")

-- SSL/TLS подключение
net.tcp.sendto("example.com", 443, "GET / HTTP/1.1\r\n\r\n", 10, true)

conn = net.tcp.connect(host, port, [timeout_s], [ssl], [ca_cert])

Подключение в роли tcp-клиента.

Аргументы:

  • host: строка; адрес получателя.
  • port: число; порт.
  • timeout_s (опционально): число в секундах; тайм-аут подключения. По умолчанию: 10.
  • ssl (опционально): boolean; true - использовать SSL/TLS шифрование.
  • ca_cert (опционально): путь к PEM-файлу доверенного CA или сам PEM-сертификат. Для TLS по умолчанию /certs/ca-certificates.crt.

Возвращает:

  • conn: объект соединения или исключение.

res = conn:send(data)

Отправить посылку по открытому TCP-соединению.

Аргументы:

  • data: строка; данные в строковом виде (строка допускает нули).

Возвращает:

  • res: boolean; true в случае успеха, false в случае неудачи.

data = conn:read([maxlen])

Принять данные. При получении используется таймаут из net.tcp.connect.

Аргументы:

  • maxlen (необязательно): число; ожидаемый размер данных. По умолчанию: 1024.

Возвращает:

  • data: строка; данные или nil. или исключение.

data = conn:readline([maxlen])

Принять строку до символа ‘\n’. При получении используется таймаут из net.tcp.connect.

Аргументы:

  • maxlen (необязательно): число; ожидаемый размер данных. По умолчанию: 1024.

Возвращает:

  • data: строка; данные или nil. или исключение.

conn:close()

Закрыть TCP-соединение. При SSL-соединении корректно завершает SSL-сессию.

Возвращает: ничего.

Пример:

-- Обычное TCP-подключение
local conn = net.tcp.connect("192.168.8.101", 5555)
conn:send("Hello")
print(conn:read())
conn:close()

-- SSL/TLS подключение
local conn = net.tcp.connect("example.com", 443, 10, true)
conn:send("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
print(conn:read(4096))
conn:close()

net.skip_ssl_verify([skip])

Управление проверкой TLS-сертификатов для всех защищённых соединений (net.http, net.tcp, umqtt и др.). По умолчанию проверка включена.

Аргументы:

  • skip (опционально): boolean; true - пропускать проверку сертификатов, false - проверять.

Возвращает:

  • boolean; текущее состояние настройки.

Пример:

-- Только для краткой диагностики в доверенной сети
net.skip_ssl_verify(true)

-- Подключиться по SSL без проверки сертификата
local conn = net.tcp.connect("192.168.1.100", 8883, 10, true)

Не оставляйте net.skip_ssl_verify(true) в рабочей конфигурации: шифрование без проверки сертификата не защищает от подмены сервера. Для собственного или самоподписанного CA передайте его сертификат через ca_cert и оставьте проверку включённой.

Рекомендации по работе с защищёнными соединениями

  • Для нескольких HTTPS-запросов к одному host:port создавайте один net.http.client. Создание клиента включает DNS, TCP и TLS-handshake; последующие запросы используют то же соединение и обычно устраняют основную задержку handshake.
  • Всегда вызывайте client:close() после серии запросов, чтобы сразу освободить сокет, TLS-контекст и память.
  • Не передавайте заголовок Connection: close, если хотите повторно использовать соединение. Сервер или reverse proxy также должен поддерживать HTTP/1.1 keep-alive и иметь достаточный idle timeout.
  • Используйте DNS-имя, указанное в SAN сертификата. Подключение по IP завершится ошибкой, если этот IP не присутствует в сертификате.
  • Перед первым TLS-подключением синхронизируйте часы, например через SNTP: проверка срока действия сертификата зависит от корректного времени устройства.
  • Храните доверенный CA в защищённой файловой системе и обновляйте его до истечения срока действия. ca_cert принимает путь к PEM-файлу или сам PEM-текст; не передавайте туда приватный ключ.
  • Если устройство работает только с одним сервисом, используйте небольшой набор необходимых доверенных CA вместо полного системного bundle. Это сокращает чтение и разбор сертификатов при создании клиента, но заранее предусмотрите обновление CA при ротации серверного сертификата.
  • Не отключайте проверку через net.skip_ssl_verify(true) ради ускорения. Это почти не устраняет вычислительную стоимость handshake, но отключает аутентификацию сервера.
  • Один объект net.http.client предназначен для последовательных запросов. Для параллельных задач создавайте отдельные клиенты и учитывайте расход памяти каждой TLS-сессии.
  • Если сервер закрыл keep-alive-сокет, следующий GET переподключится и повторится один раз. POST не повторяется автоматически; повторяйте его в прикладном коде только при наличии idempotency key или другой защиты от двойной обработки.
  • Закрывайте долго неиспользуемые клиенты. После смены сети или длительного простоя разумнее создать новое соединение, чем удерживать старый сокет.

Пример с гарантированным закрытием клиента:

local client = net.http.client("api.example.com", true)
local ok, err = xpcall(function()
    local code, chunks = client:post(
        "/telemetry",
        "application/json",
        "Idempotency-Key: measurement-123",
        '{"temperature": 24.1}'
    )
    assert(code >= 200 and code < 300, "HTTP " .. tostring(code))
    return table.concat(chunks or {})
end, function(message)
    return tostring(message)
end)
client:close()

assert(ok, err)

net.tcpserv.start([port], [callback], [autoclose], [redirectio])

Запустить TCP-сервер. Одновременно может работать один сервер, принимающий несколько подключений.

Аргументы:

  • port (опционально): порт.
  • callback: функция, которая будет выполняться при получении посылки. функция получает два параметра: строка с ip отправителя и данные в строковом виде (строка допускает нули).
  • autoclose (опционально): время бездействия до закрытия соединения, в секундах; 0 — не закрывать автоматически.
  • redirectio (опционально): boolean; если true - то весь вывод выполненных функций будет перенаправляться в ответ tcp клиенту.

Пример:

net.tcpserv.start(60, function (src, data) print(src, data) end, 60, false)

net.tcpserv.stop()

Остановить TCP-сервер.

net.tcpserv.running()

Вернуть состояние TCP-сервера: true - запущен, false - нет.

net.curl

Утилита net.curl обладает более широкими возможностями, чем net.http, но требует больше ресурсов. Работа по HTTPS доступна только на устройствах с внешней памятью.

Утилита net.curl поддерживает следующие функции:

res, header, body = net.curl.get(url [, filename])

Отправка GET-запроса.

Аргументы:

  • url: строка; URL сервера. Для адресов, начинающихся с https://, используется SSL.
  • filename (опционально): строка; имя локального файла для сохранения ответа.

Возвращает:

  • res: boolean; true при успехе, false при ошибке.
  • hdr: заголовки ответа или сообщение об ошибке.
  • body: тело ответа или сообщение об ошибке.

res, header, body = net.curl.post(url, tparams)

Отправка POST-запроса. Аргументы:

  • url: строка; URL сервера. Для адресов, начинающихся с https://, используется SSL.
  • tparams: Lua-таблица с парами key=value. Специальные ключи:
    • _FILE_key: файл для отправки. Если задан только _FILE_, используется ключ file. Можно отправить несколько файлов.
    • _JSON_key: JSON-значение. Если задан только _JSON_, используется ключ json.

Возвращает:

  • res: boolean; true при успехе, false при ошибке.
  • hdr: заголовки ответа или сообщение об ошибке.
  • body: тело ответа или сообщение об ошибке.

Пример:

     res, hdr, bdy = net.curl.post("http://loboris.eu/ESP32/test.php", {temp=24, user="esp32"})
 
     postreq = {
              temp=24,
              _FILE_file="test.jpg",
              _FILE_file2="data.txt",
              _JSON_jsondata="{\"name\":\"John\", \"age\":31}"
               }
     res, hdr, bdy = net.curl.post("http://loboris.eu/ESP32/test.php", postreq)

servername, serverport = net.curl.mailserver([servername, serverport])

Задаёт адрес и порт сервера для отправки почты. Аргументы:

  • servername: строка; URL сервера.
  • serverport: число; порт сервера.

Возвращает: установленные servername, serverport.

Пример:

net.curl.mailserver("smtp.адрес.сервера", 465)

ret, msg = net.curl.sendmail(options)

Отправка почтового сообщения.

Аргументы:

  • options: таблица со следующими полями:
    • user: строка; имя пользователя отправителя.
    • pass: строка; пароль отправителя.
    • to: таблица с адресами получателей.
    • subj: строка; тема письма.
    • msg: строка; текст письма.
    • secure: boolean; true, чтобы использовать SSL.
    • attach: таблица с именами прикреплённых файлов.

Возвращает: код статуса и сообщение.

Пример:

options = {
user = "логин",
pass = "пароль",
to = {"получатель1", "получатель2"},
subj = "Тема",
msg = "Тестовая посылка",
secure = true,
attach = {"picture.jpg"}
}

ret, msg = net.curl.sendmail(options)

net.curl.cleanup()

Освобождает память, использованную curl.

Аргументы: ничего. Возвращает: ничего.

version, versionnum = net.curl.info([showdetails])

Возвращает версию и дополнительную информацию.

Аргументы:

  • showdetails (опционально): boolean; если true, выводит в консоль дополнительную информацию. Возвращает:
  • version: строка; информация о версии.
  • versionnum: целое число; числовой номер версии.
/ > net.curl.info(true)
Curl version info
  version: 7.54.1-DEV - 472577
Host: LUA-RTOS-ESP32
- IP V6 supported
- SSL supported
- LIBZ supported
- NTLM supported
- DEBUG NOT supported
- UNIX sockets NOT supported
Protocols:
- dict
- file
- ftp
- ftps
- gopher
- http
- https
- imap
- imaps
- pop3
- pop3s
- rtsp
- smtp
- smtps
- telnet
- tftp
7.54.1-DEV  472577

verbose = net.curl.verbose([verbose])

Устанавливает уровень вывода информации в ходе работы функций curl.

Аргументы:

  • verbose(необязательно): число; 0 - не выводить доп. информацию; 1 - выводить доп. информацию.

Возвращает:

  • verbose: число; текущий уровень.

progress_seconds = net.curl.progress([progress_seconds])

Показывать прогресс работы.

Аргументы:

  • progress_seconds (необязательно): число; вывод прогресса каждые progress_seconds секунд. 0 - не показывать.

Возвращает:

  • progress_seconds: число; текущий уровень.

timeout_seconds = net.curl.timeout([timeout_seconds])

Устанавливает таймаут.

Аргументы:

  • timeout_seconds (необязательно): тайм-аут в секундах; по умолчанию 60.

Возвращает:

  • timeout_seconds: число; текущий уровень.

maxbytes = net.curl.reclimit([maxbytes])

Устанавливает предельный размер для получаемых файлов в байтах.

Аргументы:

  • maxbytes(необязательно); число; Размер в байтах.

Возвращает:

  • maxbytes: число; текущий уровень.

net.scp

Утилиты для отправки и получения данных по ssh.

net.scp.get(host, port, src, dst, user, password)

Переносит файл src с удаленного хоста в файловую систему устройства Lua под именем dst.

-- Получить файл с именем src-filename.lua
net.scp.get("remotehost",22,"~/lua/src-filename.lua","/examples/lua/dst-filename.lua","username","secretpass")

net.scp.put(host, port, src, dst, user, password)

Переносит файл src из файловой системы устройства Lua на удаленный хост в файл с именем dst.

-- Поместить локальный файл с именем logfile.txt на удаленный хост
net.scp.get("remotehost",22,"/examples/lua/logfile.txt","~/logs/logfile.txt","username","secretpass")

res, header, resp = net.curl.ftp(upload, url, user, pass [, filename])

Взаимодействие с FTP-сервером.
Возможные FTP-операции: LIST, GET file, PUT file.
Если сервер поддерживает SSL/TLS, взаимодействие будет происходить в защищенном режиме.

Аргументы: нет.

  • upload: 0 для LIST и GET операций; 1 для file upload
  • url: строка ftp - url, должен начинаться с ‘ftp://’ или с ‘ftps://’
    • user: строка; имя пользователя
    • pass: строка; пароль
  • fname: опционально; строка:
    • если upload=0 LIST (список) или имя файла, который будет записан
    • если upload=1 имя файла, который будет отправлен на сервер

Возвращает:

  • res: boolean, true в случае успеха, false если ошибка
  • hdr: header ответа в случае успеха или сообщение об ошибке
  • resp: полученный LIST (список) или файл

Примеры:

-- list files in root directory
res, hdr, resp = net.curl.ftp(0, "ftp://speedtest.tele2.net", "anonymous", "lua.esp32@gmail.com")
 
-- send file to upload directory (file name MUST be given in URL)
res, hdr, resp = net.curl.ftp(1, "ftp://speedtest.tele2.net/upload/image77.jpg", "anonymous", "lua.esp32@gmail.com", "images/myimage.jpg")
 
-- list files in upload directory to check if file is uploaded (trailing slash MUST be given)
res, hdr, resp = net.curl.ftp(0, "ftp://speedtest.tele2.net/upload", "anonymous", "lua.esp32@gmail.com")
 
-- get file back under new name
res, hdr, resp = net.curl.ftp(0, "ftp://speedtest.tele2.net/upload/image77.jpg", "anonymous", "lua.esp32@gmail.com", "images/newimage.jpg")

net.ssh.exec(host, port, command line, user, password)

-- Выполнить команду на удаленном хосте
net.ssh.exec("remotehost",22,"cat /foo/bar/secret.txt","username","secretpass")

Сервисы

SNTP

SNTP-клиент для синхронизации времени с NTP-серверами. Поддерживает до 3 серверов с автоматическим переключением при недоступности основного.

net.service.sntp.start([server1], [server2], [server3])

Запуск SNTP-клиента.

Аргументы:

  • server1 (опционально): строка; основной NTP-сервер. По умолчанию “pool.ntp.org”.
  • server2 (опционально): строка; резервный NTP-сервер.
  • server3 (опционально): строка; дополнительный резервный NTP-сервер.

Возвращает: ничего или исключение.

-- Базовый запуск
net.service.sntp.start()

-- С одним сервером
net.service.sntp.start("time.google.com")

-- С несколькими серверами для надёжности
net.service.sntp.start("time.google.com", "pool.ntp.org", "time.cloudflare.com")

net.service.sntp.stop()

Остановка SNTP-клиента.

Возвращает: ничего или исключение.

net.service.sntp.stop()

net.service.sntp.running()

Проверка, запущен ли SNTP-клиент.

Возвращает: boolean; true если запущен.

if net.service.sntp.running() then
    print("SNTP активен")
end

net.service.sntp.synced()

Проверка, было ли время синхронизировано с NTP-сервером.

Возвращает: boolean; true если синхронизация прошла успешно.

if net.service.sntp.synced() then
    print("Время синхронизировано")
end

net.service.sntp.status()

Получение детального статуса SNTP-клиента.

Возвращает: таблица с полями:

  • running: boolean; запущен ли клиент
  • synced: boolean; синхронизировано ли время
  • time: number; текущий unix timestamp
local s = net.service.sntp.status()
print("Запущен:", s.running)
print("Синхронизирован:", s.synced)
print("Текущее время:", os.date("%c", s.time))

net.service.sntp.wait([timeout_ms])

Блокирующее ожидание синхронизации времени.

Аргументы:

  • timeout_ms (опционально): число; максимальное время ожидания в миллисекундах. По умолчанию 10000.

Возвращает: boolean; true если синхронизация успешна, false если таймаут.

net.service.sntp.start("time.google.com")

if net.service.sntp.wait(15000) then
    print("Время синхронизировано!")
else
    print("Таймаут синхронизации")
end

net.service.sntp.server([index])

Получение имени настроенного NTP-сервера.

Аргументы:

  • index (опционально): число; индекс сервера 0-2. По умолчанию 0.

Возвращает: строка; имя сервера или nil.

print("Основной сервер:", net.service.sntp.server(0))
print("Резервный сервер:", net.service.sntp.server(1))

Полный пример

-- Настройка сети
net.en.setup()
net.en.start()

-- Запуск SNTP с несколькими серверами
net.service.sntp.start("time.google.com", "pool.ntp.org")

-- Ожидание синхронизации
if net.service.sntp.wait(10000) then
    print("Текущее время:", os.date())

    local status = net.service.sntp.status()
    print("Синхронизирован:", status.synced)
else
    print("Не удалось синхронизировать время")
end

TINYWEB

Встроенный HTTP/HTTPS/WebSocket сервер с поддержкой статических файлов, REST API, SSL/TLS и WebSocket REPL.

net.service.tinyweb.start(port, root, pwd, logObj, path, callback, repl, cert_path, key_path)

Запуск web-сервера. Поддерживает одновременную работу HTTP и HTTPS.

Аргументы:

  • port (необязательно): число; порт HTTP-сервера. По умолчанию 80. Если 0 — HTTP-сервер не запускается.
  • root (необязательно): строка; корневая директория сайта. По умолчанию “/”.
  • pwd (необязательно): строка; пароль для Basic Auth (пользователь “admin”).
  • logObj (необязательно): объект журнала из библиотеки Cacheutils.
  • path (необязательно): строка; путь для HTTP callback. По умолчанию “backend”.
  • callback (необязательно): функция; обработчик HTTP запросов к path.
  • repl (необязательно): boolean; включить WebSocket REPL на /repl.
  • cert_path (необязательно): строка; путь к файлу сертификата (DER). Если указан вместе с key_path — запускается HTTPS на порту 443.
  • key_path (необязательно): строка; путь к файлу приватного ключа (DER).

Файлы, загружаемые через PUT, сохраняются в /public.

Режимы работы

Только HTTP:

-- HTTP на порту 80
net.service.tinyweb.start(80, "/web")

-- HTTP на порту 8080
net.service.tinyweb.start(8080, "/web")

Только HTTPS:

-- HTTPS на порту 443, HTTP отключён
net.service.tinyweb.start(0, "/web", nil, nil, nil, nil, nil, "/cert.der", "/key.der")

HTTP + HTTPS одновременно:

-- HTTP на 80, HTTPS на 443
net.service.tinyweb.start(80, "/web", nil, nil, nil, nil, nil, "/cert.der", "/key.der")

С HTTP callback:

net.service.tinyweb.start(80, "/web", nil, nil, "api", function(method, uri, query, body)
    return '{"status":"ok"}'
end)

С WebSocket REPL:

net.service.tinyweb.start(80, "/web", nil, nil, "api", nil, true)

Полный пример с HTTPS и REPL:

-- Генерация самоподписанного сертификата (один раз)
local cert_size, key_size = net.service.tinyweb.generate_cert("/cert.der", "/key.der")
print("Сертификат:", cert_size, "байт, Ключ:", key_size, "байт")

-- Запуск HTTP + HTTPS с REPL
net.service.tinyweb.start(80, "/web", "password", nil, "api", myCallback, true, "/cert.der", "/key.der")

net.service.tinyweb.stop()

Остановка web-сервера и всех WebSocket соединений.

net.service.tinyweb.running()

Возвращает: boolean; true если сервер запущен.

net.service.tinyweb.ws_clients()

Возвращает количество подключённых WebSocket клиентов.

Возвращает: число; 0-4.

print("WS клиентов:", net.service.tinyweb.ws_clients())

net.service.tinyweb.ws_send(client_id, text)

Отправка сообщения конкретному WebSocket клиенту.

Аргументы:

  • client_id: число; идентификатор клиента (0-3).
  • text: строка; текст сообщения.

Возвращает: boolean; true если успешно.

net.service.tinyweb.ws_send(0, '{"temp":25.5}')

net.service.tinyweb.ws_broadcast(text)

Отправка сообщения всем подключённым WebSocket клиентам.

Аргументы:

  • text: строка; текст сообщения.

Возвращает: число; количество клиентов, которым отправлено сообщение.

-- Отправить всем клиентам
local sent = net.service.tinyweb.ws_broadcast('{"event":"update"}')
print("Отправлено клиентам:", sent)

net.service.tinyweb.generate_cert(cert_path, key_path, cn, days, bits)

Генерация самоподписанного SSL-сертификата и приватного ключа на устройстве.

Эта функция позволяет ESP32 самостоятельно создавать SSL-сертификаты без внешних инструментов. Сертификаты сохраняются в формате DER.

Аргументы:

  • cert_path: строка; путь для сохранения сертификата (например, “/cert.der”).
  • key_path: строка; путь для сохранения приватного ключа (например, “/key.der”).
  • cn (необязательно): строка; Common Name сертификата. По умолчанию “esp32.local”.
  • days (необязательно): число; срок действия сертификата в днях. По умолчанию 3650 (10 лет).
  • bits (необязательно): число; размер ключа. Если значение 256/384/521 — генерируется ECDSA P‑256/P‑384/P‑521. Если значение >= 1024 — генерируется RSA указанной длины. По умолчанию 256 (ECDSA P‑256). Для RSA рекомендуется не ниже 2048.

Возвращает:

  • cert_size: число; размер сертификата в байтах.
  • key_size: число; размер приватного ключа в байтах.

Или исключение в случае ошибки.

-- Базовая генерация с параметрами по умолчанию
local cert_size, key_size = net.service.tinyweb.generate_cert("/cert.der", "/key.der")
print("Сертификат:", cert_size, "байт")
print("Ключ:", key_size, "байт")

-- С указанием CN и срока действия (ECDSA P-256)
local cert_size, key_size = net.service.tinyweb.generate_cert(
    "/cert.der",
    "/key.der",
    "mydevice.local",
    7300,  -- 20 лет
    256    -- ECDSA P-256
)

-- Явно с RSA 2048
local cert_size, key_size = net.service.tinyweb.generate_cert(
    "/cert.der",
    "/key.der",
    "mydevice.local",
    7300,
    2048   -- RSA 2048
)

-- Проверка существования и генерация при необходимости
if not file.exists("/cert.der") then
    print("Генерация сертификата...")
    net.service.tinyweb.generate_cert("/cert.der", "/key.der")
    print("Готово!")
end

-- Запуск HTTPS с сгенерированным сертификатом
net.service.tinyweb.start(443, "/web", nil, nil, nil, nil, nil, "/cert.der", "/key.der")

Примечание: Самоподписанные сертификаты вызывают предупреждение в браузерах (“Self signed certificate”). Это нормальное поведение. Для продакшена рекомендуется использовать сертификаты от корпоративного CA или Let’s Encrypt.

WebSocket REPL

При включении repl=true, сервер принимает WebSocket соединения на /repl для удалённого выполнения Lua команд. Поддерживается до 4 одновременных подключений.

-- Запуск с REPL
net.service.tinyweb.start(80, "/web", nil, nil, nil, nil, true)

Подключение из браузера:

const ws = new WebSocket('ws://192.168.1.100/repl');
ws.onmessage = (e) => console.log(e.data);
ws.send('print("Hello from browser!")');

Примеры использования WebSocket

Push-уведомления от устройства

-- Запуск сервера с WebSocket
net.service.tinyweb.start(80, "/web", nil, nil, nil, nil, true)

-- Отправка данных датчика всем клиентам
function on_sensor_update(temp, hum)
    local json = string.format('{"temp":%.1f,"hum":%.1f}', temp, hum)
    net.service.tinyweb.ws_broadcast(json)
end

-- Периодическая отправка статуса
tmr.create():alarm(1000, tmr.ALARM_AUTO, function()
    local json = string.format('{"heap":%d,"uptime":%d}', node.heap(), tmr.uptime())
    net.service.tinyweb.ws_broadcast(json)
end)