====== Flume ====== ===== What is Flume? ===== Flume is an internet of things smart device intended to measure water usage in your home. It does not require any modifications to your water lines for installation. You can find out more here, [[http://www.flumewater.com|Flume Water]] ===== Flume API ===== Flume has an available API for accessing the data of the device. The official API specifications can be found here: [[https://flumetech.readme.io/reference#introduction|Flume API]] ===== Purpose ===== This document has been created to offer assistance in utilizing the Flume API using PHP server-side programming via cURL calls. ====== Accessing Flume API using PHP ====== ===== Getting Started ===== Before we can do any coding, it is required that you follow the instructions in the Flume API for generating your API Client credentials. Without doing this, you will not be able to get any data from the API. [[https://flumetech.readme.io/reference#introduction|Flume API]] ===== Getting auth token ===== Once we have the authorization credentials, we can obtain the token needed for getting data: $clientSecret = '**#clientSecret from Flume API**#'; $clientID = '**#clientID from Flume API#**'; $userName = '**#Username with Flume#**'; $userPassword = '**#Password with Flume#**'; $authToken = getAuthToken($clientID, $clientSecret, $userName, $userPassword); function getAuthToken($clientID, $clientSecret, $userName, $userPassword) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://api.flumewater.com/oauth/token'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"grant_type\":\"password\",\"client_secret\":\"{$clientSecret}\",\"client_id\":\"{$clientID}\",\"username\":\"{$userName}\",\"password\":\"{$userPassword}\"}"); $headers = array(); $headers[] = 'Content-Type: application/json'; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); if (curl_errno($ch)) { echo 'Error:' . curl_error($ch); } $data = json_decode( $result, true); curl_close($ch); return $data['data'][0]['access_token']; } ===== Obtaining User ===== Next, we must obtain the user information. It is possible to skip this step by changing any URLs in the below functions by replacing //users/{$userID}// with ///me//, thus making $userID unnecessary. I have included this function in-case it is needed. $userID = getUserID($authToken); function getUserID($authToken) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://api.flumewater.com/me'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET'); $headers = array(); $headers[] = "Authorization: Bearer {$authToken}"; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); if (curl_errno($ch)) { echo 'Error:' . curl_error($ch); } $userData = json_decode( $result, true); curl_close($ch); return $userData['data'][0]['id']; } ===== Getting Device Data ===== Within Flume, each user can have many devices. Each device then has one or many budgets. Budgets are set up by the user for the purpose of setting up alerts when getting near or over the specified limits. With the API, we are able to obtain all the devices that a user owns as follows: $devices = getUserDevices($authToken, $userID); function getUserDevices($authToken, $userID) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://api.flumewater.com/users/{$userID}/devices?user=false&location=false"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET'); $headers = array(); $headers[] = "Authorization: Bearer {$authToken}"; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); if (curl_errno($ch)) { echo 'Error:' . curl_error($ch); } curl_close($ch); $deviceData = json_decode( $result, true); $output = array(); foreach ($deviceData['data'] as $device) { if ($device['bridge_id'] != null) { $output[] = $device['id']; } } return $output; } ===== Decoding device data ===== Lastly, we iterate each device the user owns, then query once more to get the device flow data in the form of each budget, as below: foreach ($devices as $device) { $flowData = getDeviceData($authToken, $userID, $device); $flowCount = 0; foreach ($flowData as $flow): $flow['value']; // Budget Total Value $flow['actual']; // Budget Current Value $flow['name']; // Budget name $flowCount++; endforeach; } function getDeviceData($authToken, $userID, $deviceID) { // Generated by curl-to-PHP: http://incarnate.github.io/curl-to-php/ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://api.flumewater.com/users/{$userID}/devices/{$deviceID}/budgets?limit=50&offset=0&sort_field=id&sort_direction=ASC"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET'); $headers = array(); $headers[] = "Authorization: Bearer {$authToken}"; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); if (curl_errno($ch)) { echo 'Error:' . curl_error($ch); } curl_close($ch); $flowData = json_decode( $result, true); $output = array(); foreach ($flowData['data'] as $flow) { $flow['name'] = ucwords(strtolower($flow['type'])) . " Water Budget"; $output[] = $flow; } return $output; }