Могу предположить почему это происходит:
ESP8266 использует библиотеку axTLS, которая не умеет в ECC.
No support for Diffie-Hellman (DH) key exchange and Elliptic-curve cryptography (ECC). This means it can’t work with sites which require the use of these features (it works ok with the typical sites that use RSA certificates).
https://docs.micropython.org/en/latest/esp8266/gen...
Сервер OpenWeather разрешает понизить до TLS 1.2 с RSA ключом, что позволяет успешно завершить handshake.
openssl s_client -connect api.openweathermap.org:443 -servername api.openweathermap.org -tls1_2 -cipher RSA
Сервер Telegram более строг, не разрешает RSA-only и требует ECDHE (X25519) ->
sslv3 alert handshake failure
openssl s_client -connect api.telegram.org:443 -servername api.telegram.org -tls1_2 -cipher RSA
Как я понимаю,
SSL alert number 40 в выводе
openssl это и есть ваш
OSError: -40.
1. Переходите на ESP32 там отправка работает корректно.
2. Ну, или, если 8266 принципиально использовать, то прикручивать прокси: 8266 -> прокси -> telegram. Хендшейк будет делать прокси вместо ESP.
Для примера:
Прокси на Flask.from flask import Flask, request
import requests
app = Flask(__name__)
TOKEN = ""
CHAT_ID = ""
@app.route("/send", methods=["GET"])
def send_message():
text = request.args.get("text", "")
print(text)
if not text:
return "No text provided", 400
url = f"https://api.telegram.org/bot{TOKEN}/sendMessage"
try:
r = requests.get(url, params={"chat_id": CHAT_ID, "text": text}, timeout=5)
return r.text
except requests.RequestException as e:
return str(e), 500
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Скрипт для ESP8266.
import urequests
import network
import time
SSID = ""
PASSWORD = ""
PROXY_URL = "http://192.168.0.5:5000/send" # Ваш IP прокси-сервера в локальной сети
# подключение к Wi-Fi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
while not wlan.isconnected():
time.sleep(0.5)
print("Connected, IP:", wlan.ifconfig()[0])
time.sleep(3)
# отправка сообщения через прокси
msg = "Привет_из_ESP8266_5000_142589"
try:
print(f"{PROXY_URL}?text={msg}")
response = urequests.get(f"{PROXY_URL}?text={msg}", timeout=10)
print(response.text)
response.close()
except Exception as e:
print("Error:", e)
З.Ы. Не забыть открыть порт 5000 (ну или какой вы там будете использовать) для входящих в файерволе.
3. Вроде есть mbedTLS с поддержкой TLS 1.3. Сам не пробовал, но встречал на гитхабе где-то что соединение на 8266 занимает 7-8 секунд, ибо мощей не хватает ему.
link.