Browse Source

add more volcano config options

Thomas Buck 6 months ago
parent
commit
47c47672c3
9 changed files with 428 additions and 23 deletions
  1. 1
    0
      CMakeLists.txt
  2. 1
    0
      include/state.h
  3. 30
    0
      include/state_volcano_conf.h
  4. 9
    0
      include/volcano.h
  5. 86
    14
      src/console.c
  6. 6
    0
      src/state.c
  7. 29
    1
      src/state_scan.c
  8. 163
    0
      src/state_volcano_conf.c
  9. 103
    8
      src/volcano.c

+ 1
- 0
CMakeLists.txt View File

94
     src/state_about.c
94
     src/state_about.c
95
     src/state_value.c
95
     src/state_value.c
96
     src/textbox.c
96
     src/textbox.c
97
+    src/state_volcano_conf.c
97
 
98
 
98
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ff.c
99
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ff.c
99
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ffunicode.c
100
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ffunicode.c

+ 1
- 0
include/state.h View File

29
     STATE_SETTINGS,
29
     STATE_SETTINGS,
30
     STATE_ABOUT,
30
     STATE_ABOUT,
31
     STATE_VALUE,
31
     STATE_VALUE,
32
+    STATE_VOLCANO_CONF,
32
 
33
 
33
     STATE_INVALID,
34
     STATE_INVALID,
34
 };
35
 };

+ 30
- 0
include/state_volcano_conf.h View File

1
+/*
2
+ * state_volcano_conf.h
3
+ *
4
+ * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#ifndef __STATE_VOLCANO_CONF_H__
20
+#define __STATE_VOLCANO_CONF_H__
21
+
22
+#include <ble.h>
23
+
24
+void state_volcano_conf_target(bd_addr_t addr, bd_addr_type_t type);
25
+
26
+void state_volcano_conf_enter(void);
27
+void state_volcano_conf_exit(void);
28
+void state_volcano_conf_run(void);
29
+
30
+#endif // __STATE_VOLCANO_CONF_H__

+ 9
- 0
include/volcano.h View File

25
 #include "models.h"
25
 #include "models.h"
26
 
26
 
27
 enum volcano_state {
27
 enum volcano_state {
28
+    VOLCANO_STATE_NONE = 0,
28
     VOLCANO_STATE_HEATER = (1 << 0),
29
     VOLCANO_STATE_HEATER = (1 << 0),
29
     VOLCANO_STATE_PUMP = (1 << 1),
30
     VOLCANO_STATE_PUMP = (1 << 1),
31
+    VOLCANO_STATE_INVALID = 0xFF,
30
 };
32
 };
31
 
33
 
32
 // returns < 0 on error
34
 // returns < 0 on error
42
 // returns < 0 on error
44
 // returns < 0 on error
43
 int8_t volcano_set_heater_state(bool value);
45
 int8_t volcano_set_heater_state(bool value);
44
 int8_t volcano_set_pump_state(bool value);
46
 int8_t volcano_set_pump_state(bool value);
47
+int8_t volcano_set_unit(enum unit unit);
48
+int8_t volcano_set_vibration(bool value);
49
+int8_t volcano_set_display_cooling(bool value);
45
 
50
 
46
 enum unit volcano_get_unit(void);
51
 enum unit volcano_get_unit(void);
47
 enum volcano_state volcano_get_state(void);
52
 enum volcano_state volcano_get_state(void);
48
 
53
 
54
+// returns bool, or < 0 on error
55
+int8_t volcano_get_vibration(void);
56
+int8_t volcano_get_display_cooling(void);
57
+
49
 #endif // __VOLCANO_H__
58
 #endif // __VOLCANO_H__

+ 86
- 14
src/console.c View File

113
         println("   text - draw text on screen");
113
         println("   text - draw text on screen");
114
         println("    bat - draw battery indicator");
114
         println("    bat - draw battery indicator");
115
         println("");
115
         println("");
116
-        println("   vrct - Volcano read current temperature");
117
-        println("   vrtt - Volcano read target temperature");
116
+        println("     vr - Volcano read values");
118
         println(" vwtt X - Volcano write target temperature");
117
         println(" vwtt X - Volcano write target temperature");
119
         println("  vwh X - Set heater to 1 or 0");
118
         println("  vwh X - Set heater to 1 or 0");
120
         println("  vwp X - Set pump to 1 or 0");
119
         println("  vwp X - Set pump to 1 or 0");
120
+        println("  vwu X - Set unit to C or F");
121
+        println("  vwv X - Set vibration to 1 or 0");
122
+        println(" vwdc X - Set display cooling to 1 or 0");
121
         println("");
123
         println("");
122
         println("    wfl - List available workflows");
124
         println("    wfl - List available workflows");
123
         println("   wf X - Run workflow");
125
         println("   wf X - Run workflow");
252
         }
254
         }
253
     } else if (strcmp(line, "bat") == 0) {
255
     } else if (strcmp(line, "bat") == 0) {
254
         draw_battery_indicator();
256
         draw_battery_indicator();
255
-    } else if (strcmp(line, "vrct") == 0) {
257
+    } else if (strcmp(line, "vr") == 0) {
256
 #ifdef TEST_VOLCANO_AUTO_CONNECT
258
 #ifdef TEST_VOLCANO_AUTO_CONNECT
257
         DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
259
         DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
258
 #endif // TEST_VOLCANO_AUTO_CONNECT
260
 #endif // TEST_VOLCANO_AUTO_CONNECT
259
 
261
 
260
-        int16_t r = volcano_get_current_temp();
261
-        println("volcano current temp: %.1f", r / 10.0);
262
+        int16_t temp = volcano_get_current_temp();
263
+        println("volcano current temp: %.1f", temp / 10.0);
262
 
264
 
263
-#ifdef TEST_VOLCANO_AUTO_CONNECT
264
-        ble_disconnect();
265
-#endif // TEST_VOLCANO_AUTO_CONNECT
266
-    } else if (strcmp(line, "vrtt") == 0) {
267
-#ifdef TEST_VOLCANO_AUTO_CONNECT
268
-        DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
269
-#endif // TEST_VOLCANO_AUTO_CONNECT
265
+        temp = volcano_get_target_temp();
266
+        println("volcano target temp: %.1f", temp / 10.0);
267
+
268
+        enum unit unit = volcano_get_unit();
269
+        println("volcano unit: %s", (unit == UNIT_C) ? "C" : "F");
270
+
271
+        enum volcano_state state = volcano_get_state();
272
+        println("volcano state: 0x%02X", state);
270
 
273
 
271
-        int16_t r = volcano_get_target_temp();
272
-        println("volcano target temp: %.1f", r / 10.0);
274
+        int8_t r = volcano_get_vibration();
275
+        println("volcano vibration: %d", r);
276
+
277
+        r = volcano_get_display_cooling();
278
+        println("volcano display cooling: %d", r);
273
 
279
 
274
 #ifdef TEST_VOLCANO_AUTO_CONNECT
280
 #ifdef TEST_VOLCANO_AUTO_CONNECT
275
         ble_disconnect();
281
         ble_disconnect();
342
                 println("success");
348
                 println("success");
343
             }
349
             }
344
         }
350
         }
351
+    } else if (str_startswith(line, "vwu ")) {
352
+        char val;
353
+        int r = sscanf(line, "vwu %c", &val);
354
+        if ((r != 1) || ((val != 'C') && (val != 'F'))) {
355
+            println("invalid input (%d %c)", r, val);
356
+        } else {
357
+#ifdef TEST_VOLCANO_AUTO_CONNECT
358
+            DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
359
+#endif // TEST_VOLCANO_AUTO_CONNECT
360
+
361
+            int8_t r = volcano_set_unit((val == 'C') ? UNIT_C : UNIT_F);
362
+
363
+#ifdef TEST_VOLCANO_AUTO_CONNECT
364
+            ble_disconnect();
365
+#endif // TEST_VOLCANO_AUTO_CONNECT
366
+
367
+            if (r < 0) {
368
+                println("error writing value %d", r);
369
+            } else {
370
+                println("success");
371
+            }
372
+        }
373
+    } else if (str_startswith(line, "vwv ")) {
374
+        int val;
375
+        int r = sscanf(line, "vwv %d", &val);
376
+        if ((r != 1) || ((val != 0) && (val != 1))) {
377
+            println("invalid input (%d %d)", r, val);
378
+        } else {
379
+#ifdef TEST_VOLCANO_AUTO_CONNECT
380
+            DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
381
+#endif // TEST_VOLCANO_AUTO_CONNECT
382
+
383
+            int8_t r = volcano_set_vibration(val == 1);
384
+
385
+#ifdef TEST_VOLCANO_AUTO_CONNECT
386
+            ble_disconnect();
387
+#endif // TEST_VOLCANO_AUTO_CONNECT
388
+
389
+            if (r < 0) {
390
+                println("error writing value %d", r);
391
+            } else {
392
+                println("success");
393
+            }
394
+        }
395
+    } else if (str_startswith(line, "vwdc ")) {
396
+        int val;
397
+        int r = sscanf(line, "vwdc %d", &val);
398
+        if ((r != 1) || ((val != 0) && (val != 1))) {
399
+            println("invalid input (%d %d)", r, val);
400
+        } else {
401
+#ifdef TEST_VOLCANO_AUTO_CONNECT
402
+            DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
403
+#endif // TEST_VOLCANO_AUTO_CONNECT
404
+
405
+            int8_t r = volcano_set_display_cooling(val == 1);
406
+
407
+#ifdef TEST_VOLCANO_AUTO_CONNECT
408
+            ble_disconnect();
409
+#endif // TEST_VOLCANO_AUTO_CONNECT
410
+
411
+            if (r < 0) {
412
+                println("error writing value %d", r);
413
+            } else {
414
+                println("success");
415
+            }
416
+        }
345
     } else if (strcmp(line, "wfl") == 0) {
417
     } else if (strcmp(line, "wfl") == 0) {
346
         println("%d workflows", wf_count());
418
         println("%d workflows", wf_count());
347
         for (int i = 0; i < wf_count(); i++) {
419
         for (int i = 0; i < wf_count(); i++) {

+ 6
- 0
src/state.c View File

26
 #include "state_settings.h"
26
 #include "state_settings.h"
27
 #include "state_about.h"
27
 #include "state_about.h"
28
 #include "state_value.h"
28
 #include "state_value.h"
29
+#include "state_volcano_conf.h"
29
 #include "state.h"
30
 #include "state.h"
30
 
31
 
31
 #define stringify(name) # name
32
 #define stringify(name) # name
84
         .exit = state_value_exit,
85
         .exit = state_value_exit,
85
         .run = state_value_run,
86
         .run = state_value_run,
86
     }, {
87
     }, {
88
+        .name = stringify(STATE_VOLCANO_CONF),
89
+        .enter = state_volcano_conf_enter,
90
+        .exit = state_volcano_conf_exit,
91
+        .run = state_volcano_conf_run,
92
+    }, {
87
         .name = stringify(STATE_INVALID),
93
         .name = stringify(STATE_INVALID),
88
         .enter = NULL,
94
         .enter = NULL,
89
         .exit = NULL,
95
         .exit = NULL,

+ 29
- 1
src/state_scan.c View File

29
 #include "state.h"
29
 #include "state.h"
30
 #include "state_workflow.h"
30
 #include "state_workflow.h"
31
 #include "state_volcano_run.h"
31
 #include "state_volcano_run.h"
32
+#include "state_volcano_conf.h"
32
 #include "state_crafty.h"
33
 #include "state_crafty.h"
33
 #include "state_scan.h"
34
 #include "state_scan.h"
34
 
35
 
65
     }
66
     }
66
 }
67
 }
67
 
68
 
69
+static void edit_cb(int selection) {
70
+    int devs = 0;
71
+    for (int i = 0; i < result_count; i++) {
72
+        enum known_devices dev = models_filter_name(results[i].name);
73
+        if (dev == DEV_UNKNOWN) {
74
+            continue;
75
+        }
76
+
77
+        if (devs++ == selection) {
78
+            if (dev == DEV_VOLCANO) {
79
+                state_volcano_conf_target(results[i].addr, results[i].type);
80
+                state_switch(STATE_VOLCANO_CONF);
81
+            } else if (dev == DEV_CRAFTY) {
82
+                state_crafty_target(results[i].addr, results[i].type);
83
+                state_switch(STATE_CRAFTY);
84
+            }
85
+            return;
86
+        }
87
+    }
88
+
89
+    if (selection == devs) {
90
+        state_switch(STATE_SETTINGS);
91
+    } else if (selection == (devs + 1)) {
92
+        state_switch(STATE_ABOUT);
93
+    }
94
+}
95
+
68
 void state_scan_enter(void) {
96
 void state_scan_enter(void) {
69
-    menu_init(enter_cb, NULL, NULL, NULL);
97
+    menu_init(enter_cb, edit_cb, NULL, NULL);
70
     ble_scan(BLE_SCAN_ON);
98
     ble_scan(BLE_SCAN_ON);
71
 }
99
 }
72
 
100
 

+ 163
- 0
src/state_volcano_conf.c View File

1
+/*
2
+ * state_volcano_conf.c
3
+ *
4
+ * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#include <stdio.h>
20
+
21
+#include "config.h"
22
+#include "log.h"
23
+#include "menu.h"
24
+#include "volcano.h"
25
+#include "state.h"
26
+#include "state_value.h"
27
+#include "state_volcano_conf.h"
28
+
29
+static bd_addr_t ble_addr = {0};
30
+static bd_addr_type_t ble_type = 0;
31
+static bool wait_for_connect = false;
32
+static bool wait_for_disconnect = false;
33
+static bool connected = false;
34
+
35
+static bool val_celsius = false;
36
+static bool val_vibrate = false;
37
+static bool val_disp_cool = false;
38
+
39
+void state_volcano_conf_target(bd_addr_t addr, bd_addr_type_t type) {
40
+    debug("%s %d", bd_addr_to_str(addr), type);
41
+    memcpy(ble_addr, addr, sizeof(bd_addr_t));
42
+    ble_type = type;
43
+
44
+    connected = false;
45
+}
46
+
47
+static void enter_cb(int selection) {
48
+    switch (selection) {
49
+    case 0:
50
+        // Celsius
51
+        state_value_set(&val_celsius,
52
+                        sizeof(val_celsius),
53
+                        0, 1, VAL_STEP_INCREMENT, 1,
54
+                        "Celsius");
55
+        state_value_return(STATE_VOLCANO_CONF);
56
+        state_switch(STATE_VALUE);
57
+        break;
58
+
59
+    case 1:
60
+        // Vibrate
61
+        state_value_set(&val_vibrate,
62
+                        sizeof(val_vibrate),
63
+                        0, 1, VAL_STEP_INCREMENT, 1,
64
+                        "Vibrate");
65
+        state_value_return(STATE_VOLCANO_CONF);
66
+        state_switch(STATE_VALUE);
67
+        break;
68
+
69
+    case 2:
70
+        // Disp. Cool
71
+        state_value_set(&val_disp_cool,
72
+                        sizeof(val_disp_cool),
73
+                        0, 1, VAL_STEP_INCREMENT, 1,
74
+                        "Disp. Cool");
75
+        state_value_return(STATE_VOLCANO_CONF);
76
+        state_switch(STATE_VALUE);
77
+        break;
78
+    }
79
+}
80
+
81
+static void send_values(void) {
82
+    volcano_set_unit(val_celsius ? UNIT_C : UNIT_F);
83
+    sleep_ms(100);
84
+    volcano_set_vibration(val_vibrate);
85
+    sleep_ms(100);
86
+    volcano_set_display_cooling(val_disp_cool);
87
+}
88
+
89
+static void fetch_values(void) {
90
+    enum unit unit = volcano_get_unit();
91
+    val_celsius = (unit == UNIT_C);
92
+
93
+    int8_t r = volcano_get_vibration();
94
+    val_vibrate = (r == 1);
95
+
96
+    r = volcano_get_display_cooling();
97
+    val_disp_cool = (r == 1);
98
+}
99
+
100
+static void exit_cb(void) {
101
+    debug("volcano disconnect");
102
+    ble_disconnect();
103
+    wait_for_disconnect = true;
104
+}
105
+
106
+void state_volcano_conf_enter(void) {
107
+    menu_init(enter_cb, NULL, NULL, exit_cb);
108
+
109
+    if (!connected) {
110
+        debug("volcano connect");
111
+        ble_connect(ble_addr, ble_type);
112
+        wait_for_connect = true;
113
+    } else {
114
+        debug("volcano write");
115
+        send_values();
116
+    }
117
+}
118
+
119
+void state_volcano_conf_exit(void) {
120
+    menu_deinit();
121
+}
122
+
123
+static void draw(struct menu_state *menu) {
124
+    if (wait_for_connect) {
125
+        snprintf(menu->buff, MENU_MAX_LEN,
126
+                 "Connecting\nand\nDiscovering");
127
+        return;
128
+    } else if (wait_for_disconnect) {
129
+        snprintf(menu->buff, MENU_MAX_LEN,
130
+                 "\nDisconnecting");
131
+        return;
132
+    }
133
+
134
+    int pos = 0;
135
+    menu->length = 0;
136
+
137
+    ADD_STATIC_ELEMENT("Celsius");
138
+    ADD_STATIC_ELEMENT("Vibrate");
139
+    ADD_STATIC_ELEMENT("Disp. Cool");
140
+
141
+    if (menu->selection < 0) {
142
+        menu->selection = 0;
143
+    }
144
+}
145
+
146
+void state_volcano_conf_run(void) {
147
+    if (wait_for_connect && ble_is_connected()) {
148
+        wait_for_connect = false;
149
+        connected = true;
150
+        debug("volcano start");
151
+        fetch_values();
152
+    }
153
+
154
+    menu_run(draw, true);
155
+
156
+    // back to main menu when disconnected
157
+    if (wait_for_disconnect && !ble_is_connected()) {
158
+        wait_for_disconnect = false;
159
+        connected = false;
160
+        debug("volcano done");
161
+        state_switch(STATE_SCAN);
162
+    }
163
+}

+ 103
- 8
src/volcano.c View File

22
 #include "volcano.h"
22
 #include "volcano.h"
23
 
23
 
24
 #define UUID_SRVC_1       0x10
24
 #define UUID_SRVC_1       0x10
25
-#define UUID_GET_STATE    0x0C
26
-#define UUID_GET_UNIT     0x0D
25
+#define UUID_PRJSTAT1     0x0C
26
+#define UUID_PRJSTAT2     0x0D
27
+#define UUID_PRJSTAT3     0x0E
27
 
28
 
28
 #define UUID_SRVC_2       0x11
29
 #define UUID_SRVC_2       0x11
29
 #define UUID_WRITE_SRVC   0x00
30
 #define UUID_WRITE_SRVC   0x00
34
 #define UUID_PUMP_ON      0x13
35
 #define UUID_PUMP_ON      0x13
35
 #define UUID_PUMP_OFF     0x14
36
 #define UUID_PUMP_OFF     0x14
36
 
37
 
38
+#define MASK_PRJSTAT1_HEIZUNG_ENA        0x0020
39
+#define MASK_PRJSTAT1_AUTOBLESHUTDOWN    0x0200
40
+#define MASK_PRJSTAT1_PUMPE_FET_ENABLE   0x2000
41
+
42
+#define MASK_PRJSTAT2_FAHRENHEIT_ENA     0x0200
43
+#define MASK_PRJSTAT2_DISPLAY_ON_COOLING 0x1000
44
+
45
+#define MASK_PRJSTAT3_VIBRATION          0x0400
46
+
37
 // "10xx00xx-5354-4f52-5a26-4249434b454c"
47
 // "10xx00xx-5354-4f52-5a26-4249434b454c"
38
 static uint8_t uuid_base[16] = {
48
 static uint8_t uuid_base[16] = {
39
     0x10, 0xFF, 0x00, 0xFF, 0x53, 0x54, 0x4f, 0x52,
49
     0x10, 0xFF, 0x00, 0xFF, 0x53, 0x54, 0x4f, 0x52,
170
 
180
 
171
 enum unit volcano_get_unit(void) {
181
 enum unit volcano_get_unit(void) {
172
     uuid_base[1] = UUID_SRVC_1;
182
     uuid_base[1] = UUID_SRVC_1;
173
-    uuid_base[3] = UUID_GET_UNIT;
183
+    uuid_base[3] = UUID_PRJSTAT2;
174
 
184
 
175
     uint8_t buff[4];
185
     uint8_t buff[4];
176
     int32_t r = ble_read(uuid_base, buff, sizeof(buff));
186
     int32_t r = ble_read(uuid_base, buff, sizeof(buff));
180
     }
190
     }
181
 
191
 
182
     uint32_t *v = (uint32_t *)buff;
192
     uint32_t *v = (uint32_t *)buff;
183
-    return (*v & 0x200) ? UNIT_F : UNIT_C;
193
+    return (*v & MASK_PRJSTAT2_FAHRENHEIT_ENA) ? UNIT_F : UNIT_C;
184
 }
194
 }
185
 
195
 
186
 enum volcano_state volcano_get_state(void) {
196
 enum volcano_state volcano_get_state(void) {
187
     uuid_base[1] = UUID_SRVC_1;
197
     uuid_base[1] = UUID_SRVC_1;
188
-    uuid_base[3] = UUID_GET_STATE;
198
+    uuid_base[3] = UUID_PRJSTAT1;
189
 
199
 
190
     uint8_t buff[4];
200
     uint8_t buff[4];
191
     int32_t r = ble_read(uuid_base, buff, sizeof(buff));
201
     int32_t r = ble_read(uuid_base, buff, sizeof(buff));
192
     if (r != sizeof(buff)) {
202
     if (r != sizeof(buff)) {
193
         debug("ble_read unexpected value %ld", r);
203
         debug("ble_read unexpected value %ld", r);
194
-        return 0xFF;
204
+        return VOLCANO_STATE_INVALID;
195
     }
205
     }
196
 
206
 
197
     uint32_t *v = (uint32_t *)buff;
207
     uint32_t *v = (uint32_t *)buff;
198
-    uint32_t heater = (*v & 0x0020);
199
-    uint32_t pump = (*v & 0x2000);
208
+    uint32_t heater = (*v & MASK_PRJSTAT1_HEIZUNG_ENA);
209
+    uint32_t pump = (*v & MASK_PRJSTAT1_PUMPE_FET_ENABLE);
200
     return (heater ? VOLCANO_STATE_HEATER : 0) | (pump ? VOLCANO_STATE_PUMP : 0);
210
     return (heater ? VOLCANO_STATE_HEATER : 0) | (pump ? VOLCANO_STATE_PUMP : 0);
201
 }
211
 }
212
+
213
+int8_t volcano_set_unit(enum unit unit) {
214
+    uuid_base[1] = UUID_SRVC_1;
215
+    uuid_base2[1] = UUID_SRVC_1;
216
+    uuid_base[3] = UUID_WRITE_SRVC;
217
+    uuid_base2[3] = UUID_PRJSTAT2;
218
+
219
+    uint32_t v = MASK_PRJSTAT2_FAHRENHEIT_ENA;
220
+    if (unit == UNIT_F) {
221
+        v |= 0x10000;
222
+    }
223
+
224
+    int8_t r = ble_write(uuid_base, uuid_base2, (uint8_t *)&v, sizeof(v));
225
+    if (r != 0) {
226
+        debug("ble_write unexpected value %d", r);
227
+    }
228
+    return r;
229
+}
230
+
231
+int8_t volcano_set_vibration(bool value) {
232
+    uuid_base[1] = UUID_SRVC_1;
233
+    uuid_base2[1] = UUID_SRVC_1;
234
+    uuid_base[3] = UUID_WRITE_SRVC;
235
+    uuid_base2[3] = UUID_PRJSTAT3;
236
+
237
+    uint32_t v = MASK_PRJSTAT3_VIBRATION;
238
+    if (!value) {
239
+        v |= 0x10000;
240
+    }
241
+
242
+    int8_t r = ble_write(uuid_base, uuid_base2, (uint8_t *)&v, sizeof(v));
243
+    if (r != 0) {
244
+        debug("ble_write unexpected value %d", r);
245
+    }
246
+    return r;
247
+}
248
+
249
+int8_t volcano_get_vibration(void) {
250
+    uuid_base[1] = UUID_SRVC_1;
251
+    uuid_base[3] = UUID_PRJSTAT3;
252
+
253
+    uint8_t buff[4];
254
+    int32_t r = ble_read(uuid_base, buff, sizeof(buff));
255
+    if (r != sizeof(buff)) {
256
+        debug("ble_read unexpected value %ld", r);
257
+        return -1;
258
+    }
259
+
260
+    uint32_t *v = (uint32_t *)buff;
261
+    return (*v & MASK_PRJSTAT3_VIBRATION) ? 0 : 1;
262
+}
263
+
264
+int8_t volcano_set_display_cooling(bool value) {
265
+    uuid_base[1] = UUID_SRVC_1;
266
+    uuid_base2[1] = UUID_SRVC_1;
267
+    uuid_base[3] = UUID_WRITE_SRVC;
268
+    uuid_base2[3] = UUID_PRJSTAT2;
269
+
270
+    uint32_t v = MASK_PRJSTAT2_DISPLAY_ON_COOLING;
271
+    if (!value) {
272
+        v |= 0x10000;
273
+    }
274
+
275
+    int8_t r = ble_write(uuid_base, uuid_base2, (uint8_t *)&v, sizeof(v));
276
+    if (r != 0) {
277
+        debug("ble_write unexpected value %d", r);
278
+    }
279
+    return r;
280
+
281
+}
282
+
283
+int8_t volcano_get_display_cooling(void) {
284
+    uuid_base[1] = UUID_SRVC_1;
285
+    uuid_base[3] = UUID_PRJSTAT2;
286
+
287
+    uint8_t buff[4];
288
+    int32_t r = ble_read(uuid_base, buff, sizeof(buff));
289
+    if (r != sizeof(buff)) {
290
+        debug("ble_read unexpected value %ld", r);
291
+        return -1;
292
+    }
293
+
294
+    uint32_t *v = (uint32_t *)buff;
295
+    return (*v & MASK_PRJSTAT2_DISPLAY_ON_COOLING) ? 0 : 1;
296
+}

Loading…
Cancel
Save