Introduction to Raspberry Pi
Artisan’s Asylum
Making HTTP Requests with Python-Requests
Python includes a built-in HTTP client, urllib2, but its interface is clunky and hard to use. There exists a much better and easier to use HTTP client interface called Python Requests. Requests is not included with Python by default, so we must install it.
Installing Requests
Making a GET request
The simplest use of this library is making an HTTP GET Request. More flexibility can be added in the form of query parameters, authentication, custom request headers, cookies, and more. Requests also provides a nicely formatted response object, complete with HTTP Status code (that error 404 everyone loves).
At its simplest, Requests is used as:
To add on a query parameter, include a ‘params’ object in the request
To add on a header, include a ‘headers’ object in the request
If you are accessing a website that needs authentication (Basic, Digest, OAuth1), Requests can handle it as well. To use authentication, include an ‘auth’ object in the request. The authentication defaults to HTTP Basic (username/password in the clear) if one is not specified.
Creating a Forecast.IO account
This service is free up to 10k requests per day. No billing info is needed to sign up.
- Go to http://https://developer.forecast.io/ and click the «Register» button in the top right corner.
- Make note of your API Key on the bottom of the screen
Requesting forecast.io data
Use Python-requests to get forecast data for a given location and then print out tomorrow’s weather
5 способов сделать Python-сервер на Raspberry Pi. Часть 2
Сегодня мы продолжим изучать сетевые возможности Raspberry Pi, а точнее их реализацию на языке Python. В первой части мы рассмотрели базовые функции простейшего веб-сервера, работающего на Raspberry Pi. Сейчас мы пойдем дальше, и рассмотрим несколько способов, как сделать наш сервер интерактивным.
Статья рассчитана для начинающих.
Перед началом пара примечаний.
Во-первых, я и сам сомневался, стоит ли делать продолжение и ожидал больший поток критики и низких оценок, но как показал опрос в первой части, 85% читателей нашли приведенную там информацию полезной. Понимаю, что некоторых профи статьи «для чайников» раздражают, но все когда-то начинали, так что придется потерпеть.
Во-вторых, я буду писать про программирование, а не про администрирование. Так что вопросы настройки Raspbian, конфигов, VPN, безопасности и прочего, здесь рассматриваться не будут. Хотя это тоже важно, но нельзя объять необъятное. Здесь будет только про Python, и как сделать сервер на нем.
Кому все это неинтересно, могут нажать кнопку back в браузере прямо сейчас и не тратить свое ценное время ;)
Напомню, в предыдущей части мы закончили на том, что запустили на Raspberry Pi простой веб-сервер, показывающий статическую страницу:
Сейчас мы пойдем дальше, и сделаем наш сервер интерактивным, добавим на веб-страницу управление светодиодом. Разумеется, вместо светодиода может быть любое другое устройство, способное управляться от GPIO, но со светодиодом провести опыт проще всего.
Подготовка
Я не буду расписывать, как подключить светодиод к Raspberry Pi, желающие могут найти это в гугле за 5 минут. Напишем сразу несколько функций для использования GPIO, которые мы потом вставим в наш сервер.
Как можно видеть, каждая функция обращения к GPIO «обернута» в блок try-catch. Зачем это сделано? Это позволяет отлаживать сервер на любом ПК, включая Windows, что достаточно удобно. Теперь мы можем вставить эти функции в код веб-сервера.
Наша задача — добавить на веб-страницу кнопки, позволяющие из браузера управлять светодиодом. Будут рассмотрены 3 способа реализации.
Способ 1: Неправильный
Этот способ нельзя назвать красивым, зато он короткий и наиболее простой для понимания.
Создадим строку с HTML-страницей.
Здесь можно отметить 3 момента:
- Мы используем CSS для указания стиля кнопок. Это можно было бы и не делать и обойтись всего 4 строчками HTML-кода, но тогда наша страница выглядела бы как «привет из 90х»:
Сам сервер мы уже рассматривали в предыдущей части, осталось добавить в него обработку строк ‘/led/on’ и ‘/led/off’. Обновленный код целиком:
Запускаем, и если все было сделано правильно, то мы можем управлять светодиодом через наш веб-сервер:
Тестировать сервер можно не только на Raspberry Pi, но и на Windows или OSX, в консоли будут сообщения LED ON, LED OFF при нажатии на соответствующую кнопку:
Теперь выясним, чем же этот способ плох, и почему он «неправильный». Этот пример вполне рабочий, и довольно часто копируется в разных туториалах. Но проблем тут две — во-первых, это неправильно перезагружать страницу целиком, когда мы лишь хотим зажечь светодиод. Но это еще полпроблемы. Вторая, и более серьезная, проблема в том, что когда мы нажимаем кнопку включения светодиода, адрес страницы становится http://192.168.1.106:8000/led/on. Браузеры обычно запоминают последнюю открытую страницу, и при последующем открытии браузера команда включения светодиода сработает еще раз, даже если мы этого не хотели. Поэтому мы перейдем к следующему, более правильному способу.
Способ 2: Правильный
Чтобы сделать все правильно, вынесем функции включения и выключения светодиода в отдельные запросы, а вызывать их будем асинхронно с помощью Javascript. Код HTML страницы теперь будет выглядеть так:
Как можно видеть, мы отказались от href, и вызываем функции ledOn и ledOff, которые в свою очередь, асинхронно вызывают соответствующие методы сервера (асинхронные методы нужны для того, чтобы страница не блокировалась, пока ответ от сервера не пришел).
Теперь осталось добавить на сервер обработку get-запросов:
Теперь, как можно видеть, страница уже не перезагружается при попытке зажечь светодиод, каждый метод делает только то, что и должен делать.
Способ 3: Более правильный
Вроде бы все уже работает. Но разумеется, приведенный код можно (и нужно) улучшить. Дело в том, что для управления светодиодом мы используем GET-запросы. Это экономит нам место в коде, но методологически это не совсем правильно — GET-запросы предназначены для чтения данных с сервера, они могут кешироваться браузером, и вообще говоря, не должны использоваться для изменения данных. Правильный способ — это использовать POST (для тех, кому интересны детали, подробнее тут).
Поменяем вызовы в HTML с get на post, ну а заодно, раз уж код у нас асинхронный, выведем статус ожидания ответа сервера и отображения результатов работы. Для локальной сети это заметно не будет, но для медленного соединения весьма удобно. Чтобы было интереснее, для передачи параметров будем использовать JSON.
Окончательный вариант выглядит так:
Добавим в сервер поддержку GET и POST запросов:
Как можно видеть, мы теперь используем одну функцию led, в которую с помощью json передается параметр «on», принимающий True или False (при вызове в HTML передается соответственно json-строка вида < «on»: true >). Также стоит обратить внимание на try-catch — это блокирует сервер от «падения», например, если кто-то пошлет строку с невалидным json на сервер.
Если все было сделано правильно, мы получаем сервер с обратной связью, который должен выглядеть примерно так:
Обратная связь, в нашем случае сообщение «ОК», позволяет увидеть подтверждение от сервера, что код действительно был обработан.
Можно ли этот сервер еще улучшить? Можно, например имеет смысл заменить использование функции print на использование logging, это более правильно, и позволяет выводить логи сервера не только на экран, но и при желании писать их в файл с автоматической ротацией. Желающие могут заняться этим самостоятельно.
Заключение
Если все было сделано правильно, мы получим мини-сервер, позволяющий управлять светодиодом или любым другим устройством через браузер с любого устройства сети.
Важно: Меры безопасности
Еще раз отмечу, что никакой защиты или аутентификации тут нет, так что не стоит «выкладывать» такую страницу в Интернет, если планируется управлять какой-то более-менее ответственной нагрузкой. Хотя случаи атак на подобные серверы мне неизвестны, но все же не стоит давать любому желающему возможность удаленно открыть дверь гаража или включить киловаттный обогреватель. При желании удаленного управления через такую страницу, стоит настроить VPN или что-то аналогичное.
В завершение повторюсь, что материал расчитан для начинающих, и надеюсь, это было более-менее полезно. Понятно, что не все на Хабре довольны наличием статей «для чайников», так что будет или нет следующая часть, будет зависеть от итоговых оценок. Если будет, то в ней будут рассмотрены фреймворки Flask и WSGI, так же будут рассмотрены базовые методы аутентификации.
Raspberry Pi 3 Flask Tutorial: Receiving HTTP POST Request from ESP32
Introduction
In this tutorial we will check how to setup a simple Flask server on the Raspberry Pi and send HTTP POST requests to it from the ESP32. Then, we will access the body of the request on the Raspberry Pi.
The Python version used on this tutorial was 3.5.3 and it was tested on a Raspberry Pi 3 model B+, running version 4.9 of Raspbian, installed using NOOBS. Additionally, a DFRobot’s ESP32 module integrated in a ESP32 development board was used.
The Python code
The Python code for this tutorial is very similar to what we have been covering before. As usual, we start by importing the Flask class from the flask module, to setup the whole HTTP server.
Additionally, we will need to import the request object from the flask module, so we can later access the body of the request sent by the client.
After the imports, we need to create an instance of the Flask class.
Now that we have our app object, we can proceed with the configuration of the routes of the server. We will have a single route called “/post”, since we are going to test it against POST requests. Naturally, you can call it what you want, as long as you use the endpoint you defined in the client code.
Additionally, we will also limit the actual HTTP methods that this route accepts. You can check a more detailed guide on how to do it on this previous post.
This will ensure that the route handling function will only be executed when the client makes a POST request.
The route handling function will be very simple. We will just access the body of the request to print it and then return an empty answer to the client. Note that it is common that the answer of a POST request does not contain any content, since a success HTTP response code is, in many cases, enough for the client to know the operation was executed.
So, to get the actual request body, we simple need to access the data member of the request object. We will simply print the result so we can later confirm it matches the content sent by the client.
After that, as already mentioned, we return the response to the client, with an empty body.
To finalize and to start listening to incoming requests, we need to call the run method on our app object. As first input we pass the ‘0.0.0.0’ IP, to indicate the server should be listening in all the available IPs of the Raspberry Pi, and as second input we pass the port where the server will be listening.
The full Python code for the Raspberry Pi is shown below.
The Arduino code
We start with the includes of the libraries we will need to both connect the ESP32 to a wireless network and also to make the HTTP POST requests. These are the Wifi.h and the HTTPClient.h libraries, respectively.
We will also need to declare the credentials to connect to the WiFi network, more precisely the network name and the password.
Then, in the Arduino setup function, we take care of connecting the ESP32 to the WiFi network.
The HTTP POST requests will be performed on the Arduino main loop function. To be able to perform the requests, we will need an object of class HTTPClient.
Testing the code
Figure 1 – HTTP status code returned by the server to the ESP32.
If you go back to the Python prompt where the Flask server is running, you should get a result similar to figure 2, where it shows the messages sent by the ESP32 getting printed.
Figure 2 – ESP32 messages printed on the Flask server, running on the Raspberry Pi.
Leave a Reply Cancel reply
Why create an article??
Why? Well exposure… get seen by 50,000 followers. Hello I am RichardS from ESP8266.com and this is my new site. Hoping to bring EverythingESP into one location for News, Tutorials, and user Projects. Please create an account and create your first article. Once the article is published I then post links to it on all my Social Media (twitter/fb/g+) which currently reaches about 50K followers.
Raspberry Pi Flask: Receiving HTTP GET Request from ESP32
In this tutorial we will check how to setup a very simple Flask server on the Raspberry Pi and send HTTP GET requests to it from an ESP32 running the Arduino core. This tutorial was tested on a Raspberry Pi 3 model B+, running version 4.9 of Raspbian, and on a DFRobot’s ESP32 module integrated in a ESP32 development board.
Introduction
In this tutorial we will check how to setup a very simple Flask server on the Raspberry Pi and send HTTP GET requests to it from an ESP32 running the Arduino core.
Although the code we need to develop for both devices is pretty simple, we are already creating a fairly complex system. Also, this tutorial is built on top of some previous ones which I recommend you to read before proceeding.
All the code needed to send HTTP GET requests from an ESP32 running the Arduino core is explained in detail in this previous post.
For a guide on how to setup a Flask server on the Raspberry Pi, please check here. The tutorial also explains how to install Flask.
Also note that, in order for the Flask server to be reachable by the ESP32 client, both devices need to be connected to the same network and we need to expose the Flask server to that network, as explained here.
The Python version used on this tutorial was 3.5.3 and it was tested on a Raspberry Pi 3 model B+, running version 4.9 of Raspbian, installed using NOOBS. Additionally, a DFRobot’s ESP32 module integrated in a ESP32 development board was used.
The Python code
We will start our code by importing the Flask class from the flask module.
Then, we need to create an object of this previously imported class, which will be used to configure our HTTP server.
Now, we simply need to declare a route where the server will be listening to incoming HTTP requests. We will call our route “/hello” and its handling function will simply consist on returning a “Hello World” message to the client.
Remember from the previous posts that Flask is built on top of the concept of routes, which we use to specify the endpoints available on our server, for the clients to contact.
To finalize, we will call the run method on our Flask object, so the server starts listening to incoming HTTP requests.
As first argument, we will pass the IP where the server should be listening. Since we want to expose the server to the local network, in order for the ESP32 to be able to reach it, then we need to use the ‘0.0.0.0’ IP, which basically means that the server should be listening on all the available IPs.
As second argument, we will pass to the run method the port where the server will be listening. This is another information that the client needs to know in order to reach the server.
The final Python code can be seen below. As can be seen, it is really easy to setup a server with Flask.
The Arduino code
We start our Arduino code by importing all the libraries needed. First, we need the WiFi.h library to be able to connect the device to a WiFi network, and then we need the HTTPClient library, so we can make the GET requests.
Since we will connect the ESP32 to a network, we need to declare the network credentials, for later using them in the connection procedure.
Moving on to the Arduino setup, we will use this function to open a serial connection and to connect the ESP32 to the WiFi network.
The HTTP GET Requests will be periodically done in the Arduino loop function. To get started, we need an object of class HTTPClient. This will have all the methods we need to reach the server.
Now, we need to initialize the request by calling the begin method on this previously created object. As input, the begin method receives the address of destination of the request.
For this, we will need to know both the IP and the port of the server. The port is 8090, as we have previously configured on the Python code.
Regarding the IP, we need to get the IP address of the Raspberry Pi on the local network. This is very easy to get by simply typing the ifconfig on a command line, on the Raspberry Pi. For a detailed explanation on how to do it, please check here.
So, after getting the IP of your Raspberry Pi, you simply need to use it in the line of code below and substitute the 192.168.1.92 (the IP address of my Raspberry) by yours. Note that the rest corresponds to the port and to the route we defined in the Flask code.
To send the actual request, we simply need to call the GET method on our HTTPClient object.
Note that, as output, this method will return the HTTP response code from the server, in case the request was successful sent, or a number lesser than zero in case an internal error occurred on the ESP32. We should store it for error checking.
So, in case of success, we will now want to access the response payload. To do it, we simply call the getString method on our HTTPClient object, which should return a string with the response. We will print its value, and also the HTTP response code.
To finalize, we should call the end method on our HTTPClient object, to free the resources.
The final ESP32 Arduino code can be seen below. Note that it contains some additional error checking to make sure we are still connected to the WiFi network before trying to perform the request, and also verifies the output code of the GET method, to check if some internal error occurred or everything was successful in the ESP32 side.
Testing the code
To test the whole system, start by running the Flask server on the Raspberry Pi, using the environment of your choice. I will be using the IDLE IDE.
To make debugging easier, my recommendation is to first test if the server is responding by making a request using a web browser. To do it, simply open a web browser of your choice and send and type the address below in the address bar, changing the IP there by the IP you got for your Raspberry Pi.
Upon clicking enter, your browser should send a HTTP GET request to that endpoint, which allows to test if it is responding properly, as shown in figure 1. This way, if we get any problems, we know that we need to solve them in the Flask server, whereas if we tested the whole system right away, we wouldn’t be sure where the problem would be.
Testing each component of a system properly before testing the whole end-to-end system is of extreme importance to make debugging easier.
Figure 1 – Sending a request to the Flask server using a web browser.
Moving on, we need to compile and upload the ESP32 code, using the Arduino IDE. When the procedure finishes, simply open the IDE serial monitor.
When the connection to the WiFi network is established, the ESP32 should start sending the HTTP requests periodically and printing the results, as illustrated in figure 2. Note that we are obtaining exactly the same message we defined in the Flask code and a HTTP code of 200, which indicates success.
Figure 2 – Sending the requests and receiving the answers with the ESP32.
Note that if at this point something fails, we now know that the problem is most likely on the ESP32 side, since we already tested the Flask server with success using a web browser. Of course that we cannot exclude an integration problem between the two systems, but the most reasonable approach would be re-checking the ESP32 code first.
Just to finish, you can go back to the Python environment and check that Flask is indeed receiving the requests, as shown in figure 3.
Figure 3 – Flask server receiving the requests from the ESP32.