It is common need to send data read from sensor or states of device to some remote location, like web site or database. ESPHome allows doing that, and it works pretty well, once you find out how to do it.
For sending data, you can use HTTP GET or POST method. As data usually has some complexity, I prefer using POST and send all info as JSON structure. That is universal way.
First thing you have to use is to include http_request component into code:
http_request: id: http_request_data useragent: esphome/device timeout: 10s
You have to set id for component so you can access it later. useragent is optional, but it is nice to present to remote site who is sending request. timeout sets for how long component waits for response from remote site before it considers it failed connection.
If you are tight with memory on device you may opt not to use SSL. Add esp8266_disable_ssl_support: yes to disable using SSL code, thus reducing memory usage.
When this is set up you are ready to make HTTP connections.
Although it can be done using plain yaml, in real life you will end up having to use lambdas to get all info you need, so I switched to using lambda by default. It is at least more readable than mixed yaml and lambda expressions.
- http_request.post: url: http://your_url/ verify_ssl: false json: |- root["id"] = "my_device"); root["sensor1"] = id(sensor1).state; root["sensor2"] = id(sensor2).state ? "ON" : "OFF"; on_response: then: - logger.log: level: INFO tag: http_post format: 'HTTP POST Response status: %d' args: [status_code] - lambda: |- if (status_code == 200) { ESP_LOGI ("http_post", "HTTP POST sucessfull"); } else { ESP_LOGI ("http_post", "HTTP POST failed"); }
This code may be used in Action or Script. It uses http_request to make HTTP POST connection to remote site specified in url. At the url there should be some kind of API or simple script that would accept and process incoming data.
Main part is creating JSON structure. Example shows how to do it all in lambda expression. root is special designator that indicates root of JSON structure, so you can simply add content to it.
on_reponse is executed after HTTP request is sent. There you can check if connection is successfully established or not. Example shows how to use status_code both in yaml and lambda.
This is simple example. You can download my_device.yaml (343 downloads) with complete configured yaml as full example.
For more details check HTTP Request Component .
Server side
When data is sent at some url there should be something to accept and process it. Here is simple PHP script that would accept data and save it in CSV file. You, of course, can do more complex processing.
<?php $input = file_get_contents('php://input'); $data = json_decode ($input); $output_file = $data->device . '_' . str_replace(":", "-", $data->MAC) . '.csv'; $first_write = ! file_exists ($output_file); $fp = fopen($output_file, 'a'); if ($first_write) { fputcsv($fp, array_keys (get_object_vars($data))); } fputcsv($fp, get_object_vars($data)); fclose($fp); ?>
What is missing
When you are collecting data on public network like this it is necessary to assure that you get data from valid sources. This example does not cover that.
I coudnot5 find how to make some simple hashed checksum for sent data within ESPHome. Any simple hashing method would do, MD5, SHA or so. This seems to go beyond my comprehension of ESPHome platform.
If someone can show example how to accomplish that, it would be more than welcome and appreciated.