REST API: Difference between revisions

From Aquarium-Control
Jump to navigation Jump to search
Line 943: Line 943:
=== Overview collection ===
=== Overview collection ===
The collection executes the following requests:
The collection executes the following requests:
* Reset database (GET)
* Load overview signals (GET)
* Load overview signals (GET)



Revision as of 10:39, 5 December 2025

Requirements

General requirements

The API shall communicate with mobile apps and dynamic webpage.

For each request, the API shall validate the credentials (user, password).

The credentials of authorised individuals are stored in the table 'users'.

  • The name is stored as clear text.
  • A hash value of the password is stored in the table.

The API shall compute the hash function of the password when validating the credentials.

For testing purposes, the API shall provide an endpoint which calculates the hash function of a string given as parameter.

The API shall provide the data for all subsequent queries in JSON format.

Timestamps shall have the format: YYYY-MM-DD hh:mm:ss

Placeholders in subsequent SQL queries are described in brackets: [placeholder]

Coding conventions

The URL action keys shall use snake_case.

The URL parameters sent by the client shall use camelCase.

The JSON keys (responses from the API) shall use camelCase.

The database columns shall use snake_case.

The php variables shall use camelCase.

Filenames shall use all minor letters or kebab-case.

  • Exception: Executables may use snake_case.

Requirements for overview feature

The API shall provide an endpoint for informing the client about the validity of the credentials.

The API shall provide an endpoint communicating from the server to the client a set of floating point data read from a set of files:

Signal name Signal format Signal source
timestamp string /var/local/aquarium-ctrl/aquarium-ctrl-ts
water temperature floating point number /var/local/aquarium-ctrl/atlsscntfc-temp
filtered water temperature floating point number /var/local/aquarium-ctrl/atlsscntfc-tempfltrd
pH value floating point number /var/local/aquarium-ctrl/atlsscntfc-ph
filtered pH value floating point number /var/local/aquarium-ctrl/atlsscntfc-phfltrd
conductivity floating point number /var/local/aquarium-ctrl/atlsscntfc-conduc
filtered water temperature floating point number /var/local/aquarium-ctrl/atlsscntfc-conducfltrd
tank level switch position floating point number /var/local/aquarium-ctrl/tnklvlsswtch
surface ventilation status string /var/local/aquarium-ctrl/srfcvntltn
ambient temperature floating point number /var/local/aquarium-ctrl/ambtemp
ambient humidity floating point number /var/local/aquarium-ctrl/ambhum
heating status string /var/local/aquarium-ctrl/htng

Requirements for Balling feature

Balling dosing log

The API shall provide an endpoint communicating from the server to the client the Balling dosing events read from the tables balling_log and balling_set_vals of either the last 24 hours or the last 7 days depending on parameter provided by the client. The corresponding SQL query (for a period of one day) is:

SELECT balling_log.Timestamp, balling_log.pumpid, balling_log.dosingvolume, balling_set_vals.label FROM balling_log LEFT JOIN balling_set_vals ON balling_log.pumpid=balling_set_vals.pumpid WHERE Timestamp > (NOW() - INTERVAL 1 DAY) ORDER BY Timestamp

Signal name Signal format Database column name
timestamp string balling_log.Timestamp
pump id integer number balling_log.pumpid
dosing volume floating point number balling_log.dosingvolume
label string balling_set_vals.label

Balling set values

The API shall provide an endpoint communicating from the server to the client the Balling dosing set values read from the table balling_set_vals.

The corresponding SQL query is:

SELECT pumpid, dosingvolume, label FROM balling_set_vals;

Signal name Signal format Database column name
pump id integer number balling_set_vals.pumpid
dosing volume floating point number balling_set_vals.dosing_volume
label string balling_set_vals.label

The API shall provide an endpoint which allows the client to update the dosing volume of an existing dosing set value identified by the pump id. The corresponding SQL query is:

UPDATE balling_set_vals SET dosing_volume="[dosingVolume]" WHERE pump_id="[pumpId]";

Requirements for feed feature

Feed log

The API shall provide an endpoint communicating from the server to the client the feed events read from the tables feed_log and feed_profiles of either the last 24 hours or the last 7 days depending on parameter provided by the client. The corresponding SQL query (for a period of one day) is:

SELECT fl.timestamp, fl.feeder_on_time, fp.profile_name, fl.profile_id FROM feed_log AS fl LEFT JOIN feed_profiles AS fp ON fl.profile_id = fp.profile_id WHERE timestamp > (NOW() - INTERVAL 1 DAY) ORDER BY timestamp;

Signal name Signal format Database column name
timestamp string feed_log.timestamp
feeder on time floating point number feed_log.feeder_on_time
feed profile name string feed_profiles.profile_name
feed profile id integer numer feed_log.profile_id

Feed profiles

A feed profile consists of general information (ID, name) and 10 groups of repetitive data where each group contains a pause section and a feed section.

The API shall provide an endpoint communicating from the server to the client the feed profiles read from the table feedprofiles.

Signal name Signal format Database column name
profile id integer number feed_profiles.profile_id
profile name string feed_profiles.profile_name
pause 01 duration integer feed_profiles.pause_01_duration
pause 01 skimmer target state boolean feed_profiles.pause_01_skimmer
pause 01 main pump #1 target state boolean feed_profiles.pause_01_main_pump1
pause 01 main pump #2 target state boolean feed_profiles.pause_01_main_pump2
pause 01 aux. pump #1 target state boolean feed_profiles.pause_01_aux_pump1
pause 01 aux. pump #2 target state boolean feed_profiles.pause_01_aux_pump2
feed 01 duration integer feed_profiles.feed_01_duration
feed 01 skimmer target state boolean feed_profiles.feed_01_skimmer
feed 01 main pump #1 target state boolean feed_profiles.feed_01_main_pump1
feed 01 main pump #2 target state boolean feed_profiles.feed_01_main_pump2
feed 01 aux. pump #1 target state boolean feed_profiles.feed_01_aux_pump1
feed 01 aux. pump #2 target state boolean feed_profiles.feed_01_aux_pump2
... ... ...
pause 10 duration integer feed_profiles.pause_10_duration
pause 10 skimmer target state boolean feed_profiles.pause_10_skimmer
pause 10 main pump #1 target state boolean feed_profiles.pause_10_main_pump1
pause 10 main pump #2 target state boolean feed_profiles.pause_10_main_pump2
pause 10 aux. pump #1 target state boolean feed_profiles.pause_10_aux_pump1
pause 10 aux. pump #2 target state boolean feed_profiles.pause_10_aux_pump2
feed 10 duration integer feed_profiles.feed_10_duration
feed 10 skimmer target state boolean feed_profiles.feed_10_skimmer
feed 10 main pump #1 target state boolean feed_profiles.feed_10_main_pump1
feed 10 main pump #2 target state boolean feed_profiles.feed_10_main_pump2
feed 10 aux. pump #1 target state boolean feed_profiles.feed_10_aux_pump1
feed 10 aux. pump #2 target state boolean feed_profiles.feed_10_aux_pump2

The API shall provide an endpoint which allows the client to update an existing feed profile identified by the profile id.

The API shall provide an endpoint which allows the client to create a new profile.

The client shall only specify the name of the new profile.

If the feed profile already exists, the endpoint shall provide an error code and not overwrite any existing data in the database.

The related SQL query is:

INSERT INTO feed_profiles(profile_name) VALUES("[profileName]");

The API shall provide an endpoint which allows the client to execute an existing profile.

The client shall only specify the ID of the feed profile.

  • The API shall check if the profile identified by the ID exists in the database and output an error if the profile already exists.

If the profile exists, then the API shall execute a shell script: shell_exec("/usr/local/bin/aquarium_client feed execute [profileId]");

The API shall provide an endpoint which allows the client to remove an existing profile.

The client shall only specify the ID of the feed profile.

The related SQL query is:

DELETE FROM feed_profiles WHERE profile_id="[profileId]";

Feed schedules

The API shall provide an endpoint communicating from the server to the client the feed schedule entries read from the tables feed_schedule and feed_profiles.

The related SQL query is:

SELECT fs.timestamp, fs.profile_id, fp.profile_name, fs.is_weekly, fs.is_daily FROM feed_schedule AS fs LEFT JOIN feed_profiles AS fp ON fs.profile_id = fp.profile_id;

Signal name Signal format Database column name
timestamp string feed_schedule.timestamp
profile id integer number feed_profiles.profile_id
profile name string feed_profiles.profile_name
weekly repetition indicator boolean feed_schedule.is_weekly
daily repetition indicator boolean feed_schedule.is_daily

The API shall provide an endpoint which allows the client to update an existing feed schedule entry identified by the timestamp.

Note: Depending on the database layout, an UPDATE operation may not be applicable. In this case, a combined transaction of DELETE and INSERT using rollback in case of failure shall be applied.

The API shall provide an endpoint which allows the client to insert a feed schedule entry.

  • If the profile id of the feed schedule entry requested from the client does not exist, the API shall output an error message.
  • If the feed schedule already contains an entry with a timestamp identical to the one requested from the client, the API shall output an error message.

The related SQL query is:

INSERT INTO feed_schedule(timestamp, profile_id, is_weekly, is_daily) VALUES("[scheduleTimestamp]", "[profileId]", [scheduleRepeatWeekly], [scheduleRepeatDaily]);

The API shall provide an endpoint which allows the client to delete an existing feed schedule entry identified by its timestamp.

The related SQL query is:

DELETE FROM feed_schedule WHERE timestamp="[scheduleTimestamp]";

Requirements for heating feature

Heating set values

The API shall provide an endpoint communicating from the server to the client the heating set values read from the table heating_set_vals.

The corresponding SQL query is:

SELECT heating_switch_off_temp, heating_switch_on_temp FROM heating_set_vals;"

Signal name Signal format Database column name
heating switch off temperature floating point number heating_set_vals.heating_switch_off_temp
heating switch on temperature floating point number heating_set_vals.heating_switch_on_temp

The API shall provide an endpoint which allows the client to update both heating set values. The corresponding SQL query is:

UPDATE heating_set_vals SET heating_switch_on_temp=[heatingSwitchOnTemp], heating_switch_off_temp=[heatingSwitchOffTemp];

Note: The database shall contain only one entry in the table. In case there are multiple entries, then the query will overwrite the data of all entries. This is intentional.

Heating statistical data

The API shall provide an endpoint communicating from the server to the client the heating statistical data read from the table heating_stats.

The corresponding SQL query is:

SELECT date, energy, ambient_temp_average, water_temp_average, heating_control_runtime FROM heating_stats;

Signal name Signal format Database column name
date string heating_stats.date
daily energy consumption floating point number heating_stats.energy
daily average of ambient temperature floating point number heating_stats.ambient_temp_average
daily average of water temperature floating point number heating_stats.water_temp_average
heating control runtime integer number heating_stats.heating_control_runtime

Requirements for refill feature

Refill log

The API shall provide an endpoint communicating from the server to the client the refill events read from the table refill_log of either the last 24 hours or the last 7 days depending on parameter provided by the client.

The corresponding SQL query (for a period of one day) is:

SELECT timestamp, duration, volume, error_code FROM refill_log WHERE timestamp > (NOW() - INTERVAL 1 DAY)

Signal name Signal format Database column name
timestamp string refill_log.timestamp
duration floating point number refill_log.duration
volume floating point number refill_log.volume
error code integer refill_log.error_code

Refill controller state

The API shall provide an endpoint communicating from the server to the client the state of the refill control read from a file:

Signal name Signal format Signal source
refill control state string /var/local/aquarium-ctrl/refillctrl

The API shall provide an endpoint which allows the client to change the refill control state by executing:

/usr/local/bin/aquarium_client refill [command]

operation command
reset error state reset
(re-)start start
stop stop

Requirements for actuator schedule feature

The API shall provide an endpoint communicating from the server to the client the actuator schedule read from the table schedule.

The corresponding SQL query is:

SELECT schedule_type, start_time, stop_time, is_active FROM schedule;

Signal name Signal format Database column name
schedule type string schedule.schedule_type
start time string schedule.start_time
stop time string schedule.stop_time
active indicator boolean schedule.is_active

The API shall provide an endpoint that allows the client to update all actuator schedule entries. The client provides the following time values as string using the format "hh:mm":

  • ballingRangeStartTime
  • ballingRangeFinishTime
  • refillRangeStartTime
  • refillRangeFinishTime
  • ventilationRangeStartTime
  • ventilationRangeFinishTime
  • heatingRangeStartTime
  • heatingRangeFinishTime

The client provides the following values as integer:

  • ballingRangeIsActive
  • refillRangeIsActive
  • ventilationRangeIsActive
  • heatingRangeIsActive

The API shall check if all values were provided by the client. If all values are provided, by the client, the API shall execute a set of database commands in one transaction:

UPDATE schedule SET start_time="[ballingRangeStartTime]", stop_time="[ballingRangeFinishTime]", is_active=[ballingRangeIsActive] WHERE schedule_type="balling";

UPDATE schedule SET start_time="[refillRangeStartTime]", stop_time="[refillRangeFinishTime]", is_active=[refillRangeIsActive] WHERE schedule_type="refill";

UPDATE schedule SET start_time="[ventilationRangeStartTime]", stop_time="[ventilationRangeFinishTime]", is_active=[ventilationRangeIsActive] WHERE schedule_type="ventilation";

UPDATE schedule SET start_time="[heatingRangeStartTime]", stop_time="[heatingRangeFinishTime]", is_active=[heatingRangeIsActive] WHERE schedule_type="heating";

Requirements for time data feature

The API shall provide an endpoint communicating from the server to the client the time data of the last 24 hours read from the table data.

The related SQL query is:

SELECT timestamp, water_temperature, water_temperature_filtered, ph_value, pH_value_filtered, conductivity, conductivity_filtered, refill_in_progress, tank_level_switch_position, tank_level_switch_invalid, tank_level_switch_position_stabilized, surface_ventilation_status, ambient_temperature, ambient_humidity, heater_status FROM data WHERE (timestamp > (CURRENT_TIMESTAMP() - INTERVAL 1 DAY));

Signal name Signal format Database column name
timestamp string data.timestamp
water temperature floating point number data.water_temperature
filtered water temperature floating point number data.water_temperature_filtered
pH value floating point number data.ph_value
filtered pH value floating point number data.ph_value_filtered
conductivity floating point number data.conductivity
filtered conductivity floating point number data.conductivity_filtered
refill in progress boolean data.refill_in_progress
tank level switch position boolean data.tank_level_switch_position
tank level switch validity indicator boolean data.tank_level_switch_invalid
tank level switch position stabilized boolean data.tank_level_switch_position_stabilized
surface ventilation status boolean data.surface_ventilation_status
ambient temperature floating point number data.ambient_temperature
ambient humidity floating point number data.ambient_humidity
heater status boolean data.heater_status

Requirements for ventilation feature

Ventilation set values

The API shall provide an endpoint communicating from the server to the client the ventilation set values read from the table ventilation_set_vals.

The corresponding SQL query is:

SELECT ventilation_switch_off_temp, ventilation_switch_on_temp FROM ventilation_set_vals;"

Signal name Signal format Database column name
ventilation switch off temperature floating point number ventilation_set_vals.ventilation_switch_off_temp
ventilation switch on temperature floating point number ventilation_set_vals.ventilation_switch_on_temp

The API shall provide an endpoint which allows the client to update both ventilation set values. The corresponding SQL query is:

UPDATE ventilation_set_vals SET ventilation_switch_on_temp=[ventilationSwitchOnTemp], ventilation_switch_off_temp=[ventilationSwitchOffTemp];

Note: The database shall contain only one entry in the table. In case there are multiple entries, then the query will overwrite the data of all entries. This is intentional.

Architecture

The API is distributed over the following files:

File name Content description
api.php Main API functionality
db.php Adapter for connecting to SQL database
functions.php helper functionality repeatedly used throughout the API
test_reset_db.php functionality to reset and initialise the database with mock data: Do not deploy this file in productive environment!
test.php functionality to test access to database for development purposed. Do not deploy this file in productive environment!

Implementation

The behaviour of the api.php is controlled by the first action argument provided via GET method which can assume the following values:

check_auth

The API responds with a JSON object containing the following data:

Label Value
status message
authorized Credentials valid

test_hash

The API responds with a JSON object containing the following data:

Label Value
input hash
[Input value provided] [Hash calculated from the input value]

load_overview_signals

When using this parameter value, the API provides the overview data in JSON format as per above requirement.

load_balling_long

When using this parameter value, the API provides the balling dosing log as per above requirements.

The second parameter period determines the period: 7d for the last 7 days, otherwise only the last 24 hours.

load_balling_set_vals

When using this parameter value, the API provides the Balling mineral dosing set values of all configured pumps in JSON format as per above requirement.

update_balling_set_vals

When using this parameter value, the API checks if the required POST parameters were provided:

  • dosingVolume
  • pumpId

If the parameters are provided, the API will issue the SQL statement to update the dosing volume for the dedicated pump as per above requirements.

load_feed_log

When using this parameter value, the API provides the balling dosing log as per above requirements.

The second parameter period determines the period: 7d for the last 7 days, otherwise only the last 24 hours.

load_feed_profiles

When using this parameter value, the API provides all existing feed profile in JSON format as per above requirement.

update_feed_profile

When using this parameter value, the API will check if the profileId is provided as POST parameter.

All other parameters provided will be type checked if they are integer or string types.

The API will issue the SQL statement to update the specific feed profile identified by profileId as per above requirement.

create_feed_profile

When using this parameter value, the query will do the following steps as per above requirement:

  • check if the parameter profileName is provided via POST method.
  • issue an SQL statement to check if a profile with that name already exists in the database, issue an error response and abort further execution if indeed there already is such a profile
  • issue and SQL statement to insert an empty feed profile into the data base using profileName

execute_feed_profile

When using this parameter value, the API will check for the additional parameter profileId provided via GET method. If the parameter is provided, the API will issue an SQL statement to check if the database contains a matching feed profile, issue an error message and abort execution if there is no such profile. If the profile exists, the API will execute the external program aquarium_client using the keywords feed and execute and the feed profile ID as parameter as per above requirement.

delete_feed_profile

When using this parameter value, the API checks if the parameter profileId is provided via GET method. If the parameter is provided, the API will issue an SQL statement to delete the matching feed profile from the database as per above requirements.

load_feed_schedule

When using this parameter value, the API will load the feed schedule entries as per above requirement.

The SQL query uses a LEFT JOIN where the profile name is read from the feed_profile table identified by the profile_id.

create_feed_schedule_entry

When using this parameter value, the API will check if the following parameters were provided via POST method:

  • profileId
  • timestamp
  • scheduleIsWeekly
  • scheduleIsDaily

Note: Functionality for scheduleIsWeekly is not implemented as of December 2025.

When the additional parameters are provided, the API will issue an SQL statement to check if a matching feed schedule entry already exists and abort further execution if that is the case.

Otherwise, the API will issue a further SQL statement to insert the feed schedule entry into the database as per above requirement.

update_feed_schedule_entry

When using this parameter value, the API will check if the following parameters were provided via POST method and abort execution if this is not the case:

  • timestamp
  • profileId
  • isWeekly
  • isDaily

When the parameters are provided, the API will execute one SQL transaction containing two statements:

  • The first statement will delete the feed schedule entry identified by the timestamp.
  • The second statement will insert a new feed schedule entry using the additionally provided parameter.

This will effectively update an existing feed schedule entry as per above requirement.

If the transaction throws an exception (when one of the SQL statements fails), the API will trigger the rollback of the transaction.

delete_feed_schedule_entry

When using this parameter value, the API will check if the timestamp was provided using POST method and abort execution if this is not the case.

When the additional timestamp parameter is provided, the API will issue an SQL statement to delete the corresponding feed schedule entry as per above requirement.

load_heating_set_vals

When using this parameter value, the API will load the heating control set values as per above requirement.

update_heating_set_vals

When using this parameter value, the API will check if the following parameters were provided via POST method and will abort execution if this is not the case:

  • heatingSwitchOnTemp
  • heatingSwitchOffTemp

When the parameters are provided, the API will issue an SQL statement update the heating control set values as per above requirement.

load_heating_stats

When using this parameter value, the API will load the heating statistical data as per above requirement.

load_refill_log

When using this parameter value, the API provides the refill log as per above requirements.

The second parameter period determines the period: 7d for the last 7 days, otherwise only the last 24 hours.

load_refill_state

When this parameter value is provided, the API will load the refill control state information from /var/local/aquarium-ctrl/refillctrl as per above requirement.

set_refill_state

When using this parameter value, the API will check if an additional parameter named command was provided via GET method.

The API will check if the parameter has a valid value. Valid values are:

  • reset
  • start
  • stop

When the additional parameter is provided with a valid value, the API will execute the command /usr/local/bin/aquarium_client refill [command]. This will update the refill control state as per REST_API#Refill_controller_state above requirement.

When no valid value is provided, the API will abort execution.

load_actuator_schedule

When using this parameter value, the API will load the actuator schedule as per above requirement.

For testing purposes, the schedule entries are provided in alphabetical order.

update_actuator_schedule

When using this parameter value, the API will check if the following parameters were provided via POST method and abort execution if this is not the case:

  • ballingRangeFinishTime
  • ballingRangeIsActive
  • refillRangeFinishTime
  • refillRangeIsActive',
  • ventilationRangeStartTime
  • ventilationRangeFinishTime
  • ventilationRangeIsActive',
  • heatingRangeStartTime
  • heatingRangeFinishTime
  • heatingRangeIsActive

When all parameters are provided, the API will initiate a transaction consisting of four SQL statements for each actuator schedule.

The SQL statement will update the actuator schedule as per above requirement.

load_time_data

When using this parameter value, the API will load the time data as per above requirement.

load_ventilation_set_vals

When using this parameter value, the API will load the ventilation control set values as per above requirement.

update_ventilation_set_vals

When using this parameter value, the API will check if the following parameters were provided via POST method and will abort execution if this is not the case:

  • ventilationSwitchOnTemp
  • ventilationSwitchOffTemp

When the parameters are provided, the API will issue an SQL statement update the ventilation control set values as per above requirement.

Testing

Postman is used for testing of the API.

The requests aggregated in collections.

Each collection (except for the General collection) starts with a request to reset the database (truncating all tables and adding mock data).

The server-based script for resetting the database cannot be run in parallel - limiting the ability to run all tests in parallel.

Test execution is manual per collection.

Feed collection

The collection executes the following requests:

  • Reset database (GET)
  • Load feed log (GET)
  • Initial Load feed profiles (GET)
  • Update feed profile (POST)
  • Secondary Load feed profiles (GET): This request will verify if the previous request could modify the database successfully.
  • Initial Create feed profile (POST)
  • Secondary Create feed profile (POST): This request will verify if trying to create a new feed profile with an already existing name is rejected.
  • Execute feed profile (GET)
  • Create feed schedule entry (POST)
  • Load feed schedule (GET)
  • Update feed schedule entry (POST)
  • Delete feed schedule entry (POST)
  • Delete feed profile (GET)

General collection

The collection executes the following requests:

  • Hash test (GET)
  • Check authorisation (GET)

Balling collection

The collection executes the following requests:

  • Reset database (GET)
  • Load Balling log (GET)
  • Initial Load Balling set values (GET)
  • Update Balling set values (POST)
  • Secondary Load Balling set values (GET): This request will verify if the previous request could successfully modify the database.

Overview collection

The collection executes the following requests:

  • Reset database (GET)
  • Load overview signals (GET)

Refill collection

The collection executes the following requests:

  • Load refill log (GET)
  • Load refill control state (GET)
  • Set refill control state (GET)

Actuator schedule collection

The collection executes the following requests:

  • Load actuator schedule (GET)
  • Update actuator schedule (POST)

Time data collection

The collection executes the following requests:

  • Load time data (GET)

Ventilation collection

The collection executes the following requests:

  • Load ventilation set values (GET)
  • Update ventilation set values (POST)

Heating collection

The collection executes the following requests:

  • Reset database
  • Initial Load heating set values (GET)
  • Update heating set values (POST)
  • Secondary Load heating set values (GET)
  • Load heating statistics (GET)