temperature: add phase-A monitor params and timestamps

This commit is contained in:
Xiaofeng Meng 2026-02-09 07:34:21 +01:00
parent 257c9fac69
commit 6e2156994c

View file

@ -14,6 +14,7 @@
#include <linux/limits.h>
#include <unistd.h>
#include <sys/stat.h>
#include <time.h>
#define HWMON_PATH "/sys/class/hwmon"
#define THERMAL_PATH "/sys/class/thermal"
@ -451,6 +452,97 @@ static int browseTemperatureSensor(struct dmctx *dmctx, DMNODE *parent_node, voi
return 0;
}
static struct uci_section *get_temperature_dmmap_section(const char *instance, bool create)
{
struct uci_section *s = NULL, *dmmap = NULL;
uci_path_foreach_option_eq(bbfdm, "dmmap", "temperature", "temperature_instance", instance, s)
return s;
if (!create)
return NULL;
dmuci_add_section_bbfdm("dmmap", "temperature", &dmmap);
dmuci_set_value_by_section(dmmap, "temperature_instance", instance);
return dmmap;
}
static int get_temperature_monitor_enable(const char *instance)
{
char *enable = NULL;
struct uci_section *s = get_temperature_dmmap_section(instance, false);
if (!s)
return 1; /* default enabled */
dmuci_get_value_by_section_string(s, "enable", &enable);
if (!enable || enable[0] == '\0')
return 1;
return (DM_STRTOL(enable) != 0);
}
static int get_temperature_sensor_int(json_object *obj, int *temperature)
{
const char *val;
char *endptr;
long n;
if (!obj || !temperature)
return -1;
val = dmjson_get_value(obj, 1, "temperature");
if (!val || val[0] == '\0')
return -1;
n = strtol(val, &endptr, 10);
if (endptr == val || n < INT_MIN || n > INT_MAX)
return -1;
*temperature = (int)n;
return 0;
}
static void update_temperature_monitor_runtime(struct dm_data *sensor_data, const char *instance)
{
struct uci_section *s;
json_object *obj;
int temp, low_alarm = -274, high_alarm = -274;
int now = (int)time(NULL);
char *low_alarm_time = NULL, *high_alarm_time = NULL;
char buf[32];
if (!sensor_data || !sensor_data->json_object || !instance)
return;
if (!get_temperature_monitor_enable(instance))
return;
obj = sensor_data->json_object;
if (get_temperature_sensor_int(obj, &temp) != 0)
return;
s = get_temperature_dmmap_section(instance, true);
if (!s)
return;
snprintf(buf, sizeof(buf), "%d", now);
dmuci_set_value_by_section(s, "last_update", buf);
/* Low alarm timestamp: set once when threshold is crossed until explicitly reset */
if (read_alarm_value(dmjson_get_value(obj, 1, "sysfs_path"), 1, "crit", &low_alarm) == 0 && low_alarm != -274000) {
dmuci_get_value_by_section_string(s, "low_alarm_time", &low_alarm_time);
if (temp <= (low_alarm / 1000) && (!low_alarm_time || DM_STRTOL(low_alarm_time) <= 0))
dmuci_set_value_by_section(s, "low_alarm_time", buf);
}
/* High alarm timestamp: set once when threshold is crossed until explicitly reset */
if (read_alarm_value(dmjson_get_value(obj, 1, "sysfs_path"), 0, "max", &high_alarm) == 0 && high_alarm != -274000) {
dmuci_get_value_by_section_string(s, "high_alarm_time", &high_alarm_time);
if (temp >= (high_alarm / 1000) && (!high_alarm_time || DM_STRTOL(high_alarm_time) <= 0))
dmuci_set_value_by_section(s, "high_alarm_time", buf);
}
}
/*************************************************************
* GET/SET PARAMETER FUNCTIONS
*************************************************************/
@ -496,6 +588,50 @@ static int set_TemperatureSensor_alias(char *refparam, struct dmctx *ctx, void *
return 0;
}
static int get_TemperatureSensor_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
dmasprintf(value, "%d", get_temperature_monitor_enable(instance));
return 0;
}
static int set_TemperatureSensor_enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
bool b;
struct uci_section *s;
switch (action) {
case VALUECHECK:
if (bbfdm_validate_boolean(ctx, value))
return FAULT_9007;
break;
case VALUESET:
s = get_temperature_dmmap_section(instance, true);
if (!s)
return FAULT_9002;
string_to_bool(value, &b);
dmuci_set_value_by_section(s, "enable", b ? "1" : "0");
break;
}
return 0;
}
static int get_TemperatureSensor_status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
json_object *obj = ((struct dm_data *)data)->json_object;
int temp;
if (!get_temperature_monitor_enable(instance)) {
*value = "Disabled";
return 0;
}
if (get_temperature_sensor_int(obj, &temp) == 0)
*value = "Enabled";
else
*value = "Error";
return 0;
}
static int get_TemperatureSensor_name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
json_object *obj = ((struct dm_data *)data)->json_object;
@ -506,7 +642,58 @@ static int get_TemperatureSensor_name(char *refparam, struct dmctx *ctx, void *d
static int get_TemperatureSensor_value(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
json_object *obj = ((struct dm_data *)data)->json_object;
*value = dmjson_get_value(obj, 1, "temperature");
update_temperature_monitor_runtime((struct dm_data *)data, instance);
return 0;
}
static int get_TemperatureSensor_last_update(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *last_update = NULL;
struct uci_section *s = get_temperature_dmmap_section(instance, false);
if (!s)
return dm_time_utc_format(0, value);
dmuci_get_value_by_section_string(s, "last_update", &last_update);
return dm_time_utc_format(DM_STRTOL(last_update), value);
}
static int get_TemperatureSensor_polling_interval(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *interval = NULL;
struct uci_section *s = get_temperature_dmmap_section(instance, false);
if (!s) {
*value = "0";
return 0;
}
dmuci_get_value_by_section_string(s, "polling_interval", &interval);
if (!interval || interval[0] == '\0')
*value = "0";
else
*value = interval;
return 0;
}
static int set_TemperatureSensor_polling_interval(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
struct uci_section *s;
switch (action) {
case VALUECHECK:
if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{NULL,NULL}}, 1))
return FAULT_9007;
break;
case VALUESET:
s = get_temperature_dmmap_section(instance, true);
if (!s)
return FAULT_9002;
dmuci_set_value_by_section(s, "polling_interval", value);
break;
}
return 0;
}
@ -573,8 +760,32 @@ static int get_TemperatureSensor_low_alarm_value(char *refparam, struct dmctx *c
static int set_TemperatureSensor_low_alarm_value(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
int ret;
struct uci_section *s;
/* trip_point_1_temp for thermal zones, temp*_crit for hwmon */
return set_alarm_value_common(ctx, data, value, action, 1, "crit");
ret = set_alarm_value_common(ctx, data, value, action, 1, "crit");
if (ret != 0)
return ret;
if (action == VALUESET) {
s = get_temperature_dmmap_section(instance, true);
if (s)
dmuci_set_value_by_section(s, "low_alarm_time", "0");
}
return 0;
}
static int get_TemperatureSensor_low_alarm_time(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *low_alarm_time = NULL;
struct uci_section *s = get_temperature_dmmap_section(instance, false);
if (!s)
return dm_time_utc_format(0, value);
dmuci_get_value_by_section_string(s, "low_alarm_time", &low_alarm_time);
return dm_time_utc_format(DM_STRTOL(low_alarm_time), value);
}
static int get_TemperatureSensor_high_alarm_value(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
@ -598,8 +809,32 @@ static int get_TemperatureSensor_high_alarm_value(char *refparam, struct dmctx *
static int set_TemperatureSensor_high_alarm_value(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
int ret;
struct uci_section *s;
/* trip_point_0_temp for thermal zones, temp*_max for hwmon */
return set_alarm_value_common(ctx, data, value, action, 0, "max");
ret = set_alarm_value_common(ctx, data, value, action, 0, "max");
if (ret != 0)
return ret;
if (action == VALUESET) {
s = get_temperature_dmmap_section(instance, true);
if (s)
dmuci_set_value_by_section(s, "high_alarm_time", "0");
}
return 0;
}
static int get_TemperatureSensor_high_alarm_time(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *high_alarm_time = NULL;
struct uci_section *s = get_temperature_dmmap_section(instance, false);
if (!s)
return dm_time_utc_format(0, value);
dmuci_get_value_by_section_string(s, "high_alarm_time", &high_alarm_time);
return dm_time_utc_format(DM_STRTOL(high_alarm_time), value);
}
/******************************************************************************************************************************
@ -608,10 +843,16 @@ static int set_TemperatureSensor_high_alarm_value(char *refparam, struct dmctx *
static DMLEAF tTemperatureStatusTemperatureSensorParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"Alias", &DMWRITE, DMT_STRING, get_TemperatureSensor_alias, set_TemperatureSensor_alias, BBFDM_BOTH, DM_FLAG_UNIQUE},
{"Enable", &DMWRITE, DMT_BOOL, get_TemperatureSensor_enable, set_TemperatureSensor_enable, BBFDM_BOTH},
{"Status", &DMREAD, DMT_STRING, get_TemperatureSensor_status, NULL, BBFDM_BOTH},
{"Name", &DMREAD, DMT_STRING, get_TemperatureSensor_name, NULL, BBFDM_BOTH, DM_FLAG_UNIQUE},
{"Value", &DMREAD, DMT_INT, get_TemperatureSensor_value, NULL, BBFDM_BOTH},
{"LastUpdate", &DMREAD, DMT_TIME, get_TemperatureSensor_last_update, NULL, BBFDM_BOTH},
{"LowAlarmValue", &DMWRITE, DMT_INT, get_TemperatureSensor_low_alarm_value, set_TemperatureSensor_low_alarm_value, BBFDM_BOTH},
{"LowAlarmTime", &DMREAD, DMT_TIME, get_TemperatureSensor_low_alarm_time, NULL, BBFDM_BOTH},
{"HighAlarmValue", &DMWRITE, DMT_INT, get_TemperatureSensor_high_alarm_value, set_TemperatureSensor_high_alarm_value, BBFDM_BOTH},
{"PollingInterval", &DMWRITE, DMT_UNINT, get_TemperatureSensor_polling_interval, set_TemperatureSensor_polling_interval, BBFDM_BOTH},
{"HighAlarmTime", &DMREAD, DMT_TIME, get_TemperatureSensor_high_alarm_time, NULL, BBFDM_BOTH},
{0}
};