Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 126 additions & 66 deletions src/monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,102 +30,180 @@
#include "../include/coolercontrol.h"

/**
* @brief Extract temperature from device status history
* @details Helper function to get temperature from the latest status entry
* @brief Validate temperature sensor name for device type
* @details Helper function to check if sensor name matches device type
*/
static float extract_device_temperature(json_t *device, const char *device_type)
static int is_valid_sensor_for_device(const char *sensor_name, const char *device_type)
{
if (strcmp(device_type, "CPU") == 0 && strcmp(sensor_name, "temp1") == 0)
{
return 1;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.5 rule Note

MISRA 15.5 rule
}

if (strcmp(device_type, "GPU") == 0 &&

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.1 rule Note

MISRA 12.1 rule
(strstr(sensor_name, "GPU") || strstr(sensor_name, "gpu")))
{
return 1;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.5 rule Note

MISRA 15.5 rule
}

return 0;
}

/**
* @brief Validate temperature value is within acceptable range
* @details Helper function to check temperature bounds
*/
static int is_temperature_valid(float temperature)
{
return temperature >= -50.0f && temperature <= 150.0f;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.1 rule Note

MISRA 12.1 rule
}

/**
* @brief Extract temperature from single sensor entry
* @details Helper function to process one temperature sensor entry
*/
static float extract_temperature_from_sensor(json_t *temp_entry, const char *device_type)
{
json_t *name_val = json_object_get(temp_entry, "name");
json_t *temp_val = json_object_get(temp_entry, "temp");

if (!name_val || !json_is_string(name_val) || !temp_val || !json_is_number(temp_val))
return 0.0f;

const char *sensor_name = json_string_value(name_val);
float temperature = (float)json_number_value(temp_val);

if (!is_temperature_valid(temperature))

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.6 rule Note

MISRA 15.6 rule
return 0.0f;

if (is_valid_sensor_for_device(sensor_name, device_type))

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.6 rule Note

MISRA 15.6 rule

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
return temperature;

return 0.0f;
}

/**
* @brief Get latest status from device history
* @details Helper function to extract the most recent status entry
*/
static json_t *get_latest_device_status(json_t *device)
{
// Get status history
json_t *status_history = json_object_get(device, "status_history");
if (!status_history || !json_is_array(status_history))
return 0.0f;
return NULL;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.5 rule Note

MISRA 15.5 rule

size_t history_count = json_array_size(status_history);
if (history_count == 0)
return 0.0f;
return NULL;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.5 rule Note

MISRA 15.5 rule

// Get latest status
json_t *last_status = json_array_get(status_history, history_count - 1);
return json_array_get(status_history, history_count - 1);

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 10.4 rule Note

MISRA 10.4 rule
}

/**
* @brief Extract temperature from device status history
* @details Helper function to get temperature from the latest status entry
*/
static float extract_device_temperature(json_t *device, const char *device_type)
{
json_t *last_status = get_latest_device_status(device);
if (!last_status)
return 0.0f;

// Get temperatures array
json_t *temps = json_object_get(last_status, "temps");
if (!temps || !json_is_array(temps))
return 0.0f;

// Search for appropriate temperature sensor
size_t temp_count = json_array_size(temps);
for (size_t i = 0; i < temp_count; i++)
{
json_t *temp_entry = json_array_get(temps, i);
if (!temp_entry)
continue;

json_t *name_val = json_object_get(temp_entry, "name");
json_t *temp_val = json_object_get(temp_entry, "temp");

if (!name_val || !json_is_string(name_val) || !temp_val || !json_is_number(temp_val))
continue;

const char *sensor_name = json_string_value(name_val);
float temperature = (float)json_number_value(temp_val);

// Validate temperature range
if (temperature < -50.0f || temperature > 150.0f)
continue;

// Check sensor name based on device type
if (strcmp(device_type, "CPU") == 0 && strcmp(sensor_name, "temp1") == 0)
{
return temperature;
}
else if (strcmp(device_type, "GPU") == 0 &&
(strstr(sensor_name, "GPU") || strstr(sensor_name, "gpu")))
{
float temperature = extract_temperature_from_sensor(temp_entry, device_type);
if (temperature > 0.0f)

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.6 rule Note

MISRA 15.6 rule
return temperature;
}
}

return 0.0f;
}

/**
* @brief Parse sensor JSON and extract temperatures from CPU and GPU devices.
* @details Simplified JSON parsing to extract CPU and GPU temperature values.
* @brief Initialize temperature output values
* @details Helper function to set initial temperature values
*/
static int parse_temperature_data(const char *json, float *temp_cpu, float *temp_gpu)
static void initialize_temperature_outputs(float *temp_cpu, float *temp_gpu)
{
if (!json || json[0] == '\0')
{
log_message(LOG_ERROR, "Invalid JSON input");
return 0;
}

// Initialize outputs
if (temp_cpu)
*temp_cpu = 0.0f;
if (temp_gpu)
*temp_gpu = 0.0f;
}

// Parse JSON
/**
* @brief Parse JSON root and get devices array
* @details Helper function to parse JSON and extract devices array
*/
static json_t *parse_json_and_get_devices(const char *json)
{
json_error_t json_error;
json_t *root = json_loads(json, 0, &json_error);
if (!root)
{
log_message(LOG_ERROR, "JSON parse error: %s", json_error.text);
return 0;
return NULL;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.5 rule Note

MISRA 15.5 rule
}

// Get devices array
json_t *devices = json_object_get(root, "devices");
if (!devices || !json_is_array(devices))
{
json_decref(root);
return NULL;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.5 rule Note

MISRA 15.5 rule
}

return root;
}

/**
* @brief Process device and extract temperature if matching type
* @details Helper function to check device type and extract temperature
*/
static void process_device_temperature(json_t *device, const char *target_type,
float *temperature, int *found_flag)
{
const char *device_type = extract_device_type_from_json(device);
if (!device_type || *found_flag)

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.6 rule Note

MISRA 15.6 rule
return;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.5 rule Note

MISRA 15.5 rule

if (strcmp(device_type, target_type) == 0)
{
if (temperature)

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
{
*temperature = extract_device_temperature(device, target_type);
*found_flag = 1;
}
}
}

/**
* @brief Parse sensor JSON and extract temperatures from CPU and GPU devices.
* @details Simplified JSON parsing to extract CPU and GPU temperature values.
*/
static int parse_temperature_data(const char *json, float *temp_cpu, float *temp_gpu)
{
if (!json || json[0] == '\0')
{
log_message(LOG_ERROR, "Invalid JSON input");
return 0;
}

// Search for CPU and GPU devices
initialize_temperature_outputs(temp_cpu, temp_gpu);

json_t *root = parse_json_and_get_devices(json);
if (!root)

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.6 rule Note

MISRA 15.6 rule
return 0;

json_t *devices = json_object_get(root, "devices");
size_t device_count = json_array_size(devices);
int cpu_found = 0, gpu_found = 0;

Expand All @@ -135,26 +213,8 @@
if (!device)
continue;

const char *device_type = extract_device_type_from_json(device);
if (!device_type)
continue;

if (!cpu_found && strcmp(device_type, "CPU") == 0)
{
if (temp_cpu)
{
*temp_cpu = extract_device_temperature(device, "CPU");
cpu_found = 1;
}
}
else if (!gpu_found && strcmp(device_type, "GPU") == 0)
{
if (temp_gpu)
{
*temp_gpu = extract_device_temperature(device, "GPU");
gpu_found = 1;
}
}
process_device_temperature(device, "CPU", temp_cpu, &cpu_found);
process_device_temperature(device, "GPU", temp_gpu, &gpu_found);
}

json_decref(root);
Expand Down