Skip to content

API Reference

Source code in fairwater_api_client.py
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
class FairwaterAPIClient:
    def __init__(self, base_url, api_key):
        self.base_url = base_url.rstrip('/')
        self.headers = {"X-API-Key": api_key}

    def _get(self, endpoint, params):
        url = f"{self.base_url}{endpoint}"
        response = requests.get(url, headers=self.headers, params=params)

        if response.status_code == 403:
            raise PermissionError("Invalid API Key or unauthorized access.")
        elif response.status_code == 404:
            raise ValueError("Endpoint not found.")
        elif response.status_code != 200:
            response.raise_for_status()

        return response.json()

    def _format_datetime(self, dt):
        if isinstance(dt, datetime):
            return dt.isoformat()
        return dt

    def _fetch_paginated(self, endpoint, starttime, endtime, limit=5000, house_name=None, extra_params=None):
        offset = 0
        all_results = []
        is_sensor_map = False

        while True:
            params = {
                "starttime": self._format_datetime(starttime),
                "endtime": self._format_datetime(endtime),
                "limit": limit,
                "offset": offset
            }

            if extra_params:
                params.update(extra_params)

            path = endpoint.format(house_name=house_name) if house_name else endpoint
            response = self._get(path, params)

            if "sensors" in response:
                is_sensor_map = True
                all_results.extend(response["sensors"])
                if len(response["sensors"]) < limit:
                    break
            elif "data" in response:
                all_results.extend(response["data"])
                if len(response["data"]) < limit:
                    break
            else:
                break

            offset += limit

        return all_results if not is_sensor_map else {"sensors": all_results}

    def get_houses(self):
        return self._get("/houses", {})["houses"]

    def get_house(self, house_name):
        return self._get(f"/houses/{house_name}", {})

    def get_house_sensors(self, house_name):
        return self._get(f"/houses/{house_name}/sensors", {})


    def get_smartmeter_data(self, starttime, endtime, limit=5000):
        return self._fetch_paginated("/smartmeter-data", starttime, endtime, limit)

    def get_shower_data(self, starttime, endtime, limit=5000):
        return self._fetch_paginated("/shower-data", starttime, endtime, limit)

    def get_droople_data(self, starttime, endtime, limit=5000, include_heartbeat=False):
        return self._fetch_paginated(
            "/droople-data", starttime, endtime, limit,
            extra_params={"include_heartbeat": str(include_heartbeat).lower()}
        )

    def get_droople_data_for_house(self, house_name, starttime, endtime, limit=5000, include_heartbeat=False):
        return self._fetch_paginated(
            "/houses/{house_name}/droople-data", starttime, endtime, limit, house_name,
            extra_params={"include_heartbeat": str(include_heartbeat).lower()}
        )

    def get_smartmeter_data_for_house(self, house_name, starttime, endtime, limit=5000):
        return self._fetch_paginated("/houses/{house_name}/smartmeter-data", starttime, endtime, limit, house_name)

    def get_shower_data_for_house(self, house_name, starttime, endtime, limit=5000):
        return self._fetch_paginated("/houses/{house_name}/shower-data", starttime, endtime, limit, house_name)

base_url = base_url.rstrip('/') instance-attribute

headers = {'X-API-Key': api_key} instance-attribute

get_droople_data(starttime, endtime, limit=5000, include_heartbeat=False)

Source code in fairwater_api_client.py
82
83
84
85
86
def get_droople_data(self, starttime, endtime, limit=5000, include_heartbeat=False):
    return self._fetch_paginated(
        "/droople-data", starttime, endtime, limit,
        extra_params={"include_heartbeat": str(include_heartbeat).lower()}
    )

get_droople_data_for_house(house_name, starttime, endtime, limit=5000, include_heartbeat=False)

Source code in fairwater_api_client.py
88
89
90
91
92
def get_droople_data_for_house(self, house_name, starttime, endtime, limit=5000, include_heartbeat=False):
    return self._fetch_paginated(
        "/houses/{house_name}/droople-data", starttime, endtime, limit, house_name,
        extra_params={"include_heartbeat": str(include_heartbeat).lower()}
    )

get_house(house_name)

Source code in fairwater_api_client.py
69
70
def get_house(self, house_name):
    return self._get(f"/houses/{house_name}", {})

get_house_sensors(house_name)

Source code in fairwater_api_client.py
72
73
def get_house_sensors(self, house_name):
    return self._get(f"/houses/{house_name}/sensors", {})

get_houses()

Source code in fairwater_api_client.py
66
67
def get_houses(self):
    return self._get("/houses", {})["houses"]

get_shower_data(starttime, endtime, limit=5000)

Source code in fairwater_api_client.py
79
80
def get_shower_data(self, starttime, endtime, limit=5000):
    return self._fetch_paginated("/shower-data", starttime, endtime, limit)

get_shower_data_for_house(house_name, starttime, endtime, limit=5000)

Source code in fairwater_api_client.py
97
98
def get_shower_data_for_house(self, house_name, starttime, endtime, limit=5000):
    return self._fetch_paginated("/houses/{house_name}/shower-data", starttime, endtime, limit, house_name)

get_smartmeter_data(starttime, endtime, limit=5000)

Source code in fairwater_api_client.py
76
77
def get_smartmeter_data(self, starttime, endtime, limit=5000):
    return self._fetch_paginated("/smartmeter-data", starttime, endtime, limit)

get_smartmeter_data_for_house(house_name, starttime, endtime, limit=5000)

Source code in fairwater_api_client.py
94
95
def get_smartmeter_data_for_house(self, house_name, starttime, endtime, limit=5000):
    return self._fetch_paginated("/houses/{house_name}/smartmeter-data", starttime, endtime, limit, house_name)