[graphicport]

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, Flume Water

Flume API

Flume has an available API for accessing the data of the device. The official API specifications can be found here: 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. 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;
}