forked from AVSystem/Anjay-mbedos-client
-
Notifications
You must be signed in to change notification settings - Fork 1
/
humidity.cpp
334 lines (279 loc) · 9.61 KB
/
humidity.cpp
1
2
3
4
5
6
7
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
/*
* Copyright 2020-2021 AVSystem <[email protected]>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Generated by anjay_codegen.py on 2019-10-23 13:56:35
*
* LwM2M Object: Humidity
* ID: 3304, URN: urn:oma:lwm2m:ext:3304, Optional, Multiple
*
* Description: This IPSO object should be used with a humidity sensor to
* report a humidity measurement. It also provides resources for
* minimum/maximum measured values and the minimum/maximum range that can
* be measured by the humidity sensor. An example measurement unit is
* relative humidity as a percentage (ucum:%).
*/
#include <assert.h>
#include <stdbool.h>
#include <anjay/anjay.h>
#include <avsystem/commons/avs_defs.h>
#include <avsystem/commons/avs_list.h>
#include <avsystem/commons/avs_log.h>
#include <avsystem/commons/avs_memory.h>
#include <mbed.h>
#ifdef TARGET_DISCO_L496AG
# include <XNucleoIKS01A2.h>
# include "humidity.h"
# define HUMIDITY_OBJ_LOG(...) avs_log(humidity_obj, __VA_ARGS__)
# define SENSOR_ID 0xBC
/**
* Min Measured Value: R, Single, Optional
* type: float, range: N/A, unit: N/A
* The minimum value measured by the sensor since power ON or reset
*/
# define RID_MIN_MEASURED_VALUE 5601
/**
* Max Measured Value: R, Single, Optional
* type: float, range: N/A, unit: N/A
* The maximum value measured by the sensor since power ON or reset
*/
# define RID_MAX_MEASURED_VALUE 5602
/**
* Min Range Value: R, Single, Optional
* type: float, range: N/A, unit: N/A
* The minimum value that can be measured by the sensor
*/
# define RID_MIN_RANGE_VALUE 5603
/**
* Max Range Value: R, Single, Optional
* type: float, range: N/A, unit: N/A
* The maximum value that can be measured by the sensor
*/
# define RID_MAX_RANGE_VALUE 5604
/**
* Reset Min and Max Measured Values: E, Single, Optional
* type: N/A, range: N/A, unit: N/A
* Reset the Min and Max Measured Values to Current Value
*/
# define RID_RESET_MIN_AND_MAX_MEASURED_VALUES 5605
/**
* Sensor Value: R, Single, Mandatory
* type: float, range: N/A, unit: N/A
* Last or Current Measured Value from the Sensor
*/
# define RID_SENSOR_VALUE 5700
/**
* Sensor Units: R, Single, Optional
* type: string, range: N/A, unit: N/A
* Measurement Units Definition e.g. “Cel” for Temperature in Celsius.
*/
# define RID_SENSOR_UNITS 5701
# define MIN_RANGE_VALUE 0.0 // % rH
# define MAX_RANGE_VALUE 100.0 // % rH
typedef struct humidity_struct {
const anjay_dm_object_def_t *def;
HTS221Sensor *sensor;
float min_value;
float max_value;
float curr_value;
} humidity_t;
static inline humidity_t *get_obj(const anjay_dm_object_def_t *const *obj_ptr) {
assert(obj_ptr);
return AVS_CONTAINER_OF(obj_ptr, humidity_t, def);
}
static void reset_min_max_values(humidity_t *obj) {
obj->max_value = obj->curr_value;
obj->min_value = obj->curr_value;
}
static int instance_reset(anjay_t *anjay,
const anjay_dm_object_def_t *const *obj_ptr,
anjay_iid_t iid) {
(void) anjay;
(void) iid;
assert(iid == 0);
humidity_t *obj = get_obj(obj_ptr);
assert(obj);
reset_min_max_values(obj);
return 0;
}
static int list_resources(anjay_t *anjay,
const anjay_dm_object_def_t *const *obj_ptr,
anjay_iid_t iid,
anjay_dm_resource_list_ctx_t *ctx) {
(void) anjay;
(void) obj_ptr;
(void) iid;
assert(iid == 0);
anjay_dm_emit_res(ctx, RID_MIN_MEASURED_VALUE, ANJAY_DM_RES_R,
ANJAY_DM_RES_PRESENT);
anjay_dm_emit_res(ctx, RID_MAX_MEASURED_VALUE, ANJAY_DM_RES_R,
ANJAY_DM_RES_PRESENT);
anjay_dm_emit_res(ctx, RID_MIN_RANGE_VALUE, ANJAY_DM_RES_R,
ANJAY_DM_RES_PRESENT);
anjay_dm_emit_res(ctx, RID_MAX_RANGE_VALUE, ANJAY_DM_RES_R,
ANJAY_DM_RES_PRESENT);
anjay_dm_emit_res(ctx, RID_RESET_MIN_AND_MAX_MEASURED_VALUES,
ANJAY_DM_RES_E, ANJAY_DM_RES_PRESENT);
anjay_dm_emit_res(ctx, RID_SENSOR_VALUE, ANJAY_DM_RES_R,
ANJAY_DM_RES_PRESENT);
anjay_dm_emit_res(ctx, RID_SENSOR_UNITS, ANJAY_DM_RES_R,
ANJAY_DM_RES_PRESENT);
return 0;
}
static int resource_read(anjay_t *anjay,
const anjay_dm_object_def_t *const *obj_ptr,
anjay_iid_t iid,
anjay_rid_t rid,
anjay_riid_t riid,
anjay_output_ctx_t *ctx) {
(void) anjay;
(void) iid;
(void) riid;
assert(iid == 0);
humidity_t *obj = get_obj(obj_ptr);
assert(obj);
switch (rid) {
case RID_MIN_MEASURED_VALUE:
assert(riid == ANJAY_ID_INVALID);
return anjay_ret_float(ctx, obj->min_value);
case RID_MAX_MEASURED_VALUE:
assert(riid == ANJAY_ID_INVALID);
return anjay_ret_float(ctx, obj->max_value);
case RID_MIN_RANGE_VALUE:
assert(riid == ANJAY_ID_INVALID);
return anjay_ret_float(ctx, MIN_RANGE_VALUE);
case RID_MAX_RANGE_VALUE:
assert(riid == ANJAY_ID_INVALID);
return anjay_ret_float(ctx, MAX_RANGE_VALUE);
case RID_SENSOR_VALUE:
assert(riid == ANJAY_ID_INVALID);
return anjay_ret_float(ctx, obj->curr_value);
case RID_SENSOR_UNITS:
assert(riid == ANJAY_ID_INVALID);
return anjay_ret_string(ctx, "% rH");
default:
return ANJAY_ERR_METHOD_NOT_ALLOWED;
}
}
static int resource_execute(anjay_t *anjay,
const anjay_dm_object_def_t *const *obj_ptr,
anjay_iid_t iid,
anjay_rid_t rid,
anjay_execute_ctx_t *arg_ctx) {
(void) anjay;
(void) arg_ctx;
(void) iid;
assert(iid == 0);
humidity_t *obj = get_obj(obj_ptr);
assert(obj);
switch (rid) {
case RID_RESET_MIN_AND_MAX_MEASURED_VALUES:
reset_min_max_values(obj);
humidity_object_update(anjay);
return 0;
default:
return ANJAY_ERR_METHOD_NOT_ALLOWED;
}
}
namespace {
struct ObjDef : public anjay_dm_object_def_t {
ObjDef() : anjay_dm_object_def_t() {
oid = HUMIDITY_OID;
handlers.list_instances = anjay_dm_list_instances_SINGLE;
handlers.instance_reset = instance_reset;
handlers.list_resources = list_resources;
handlers.resource_read = resource_read;
handlers.resource_execute = resource_execute;
handlers.transaction_begin = anjay_dm_transaction_NOOP;
handlers.transaction_validate = anjay_dm_transaction_NOOP;
handlers.transaction_commit = anjay_dm_transaction_NOOP;
handlers.transaction_rollback = anjay_dm_transaction_NOOP;
}
} const OBJ_DEF;
const anjay_dm_object_def_t **humidity_object_create(void) {
HTS221Sensor *sensor = XNucleoIKS01A2::instance(D14, D15)->ht_sensor;
uint8_t id = 0;
float sensor_value;
if (sensor->read_id(&id) || id != SENSOR_ID || sensor->enable()
|| sensor->get_humidity(&sensor_value)) {
HUMIDITY_OBJ_LOG(WARNING, "Failed to initialize humidity sensor");
return NULL;
}
humidity_t *obj = (humidity_t *) avs_calloc(1, sizeof(humidity_t));
if (!obj) {
(void) sensor->disable();
return NULL;
}
obj->def = &OBJ_DEF;
obj->sensor = sensor;
obj->curr_value = sensor_value;
reset_min_max_values(obj);
return &obj->def;
}
void humidity_object_release(const anjay_dm_object_def_t **def) {
if (def) {
humidity_t *obj = get_obj(def);
avs_free(obj);
}
}
const anjay_dm_object_def_t **OBJ_DEF_PTR;
} // namespace
int humidity_object_install(anjay_t *anjay) {
if (OBJ_DEF_PTR) {
HUMIDITY_OBJ_LOG(ERROR, "Humidity Object has been already installed");
return -1;
}
OBJ_DEF_PTR = humidity_object_create();
if (!OBJ_DEF_PTR) {
return 0;
}
return anjay_register_object(anjay, OBJ_DEF_PTR);
}
void humidity_object_uninstall(anjay_t *anjay) {
if (OBJ_DEF_PTR) {
if (anjay_unregister_object(anjay, OBJ_DEF_PTR)) {
HUMIDITY_OBJ_LOG(ERROR,
"Error during unregistering Humidity Object");
}
humidity_object_release(OBJ_DEF_PTR);
OBJ_DEF_PTR = nullptr;
}
}
void humidity_object_update(anjay_t *anjay) {
if (!OBJ_DEF_PTR) {
return;
}
humidity_t *obj = get_obj(OBJ_DEF_PTR);
float value;
if (obj->sensor->get_humidity(&value)) {
HUMIDITY_OBJ_LOG(ERROR, "Failed to get humidity");
return;
}
if (value != obj->curr_value) {
obj->curr_value = value;
(void) anjay_notify_changed(anjay, HUMIDITY_OID, 0, RID_SENSOR_VALUE);
}
if (value > obj->max_value) {
obj->max_value = value;
(void) anjay_notify_changed(anjay, HUMIDITY_OID, 0,
RID_MAX_MEASURED_VALUE);
}
if (value < obj->min_value) {
obj->min_value = value;
(void) anjay_notify_changed(anjay, HUMIDITY_OID, 0,
RID_MIN_MEASURED_VALUE);
}
}
#endif // TARGET_DISCO_L496AG