sensor_shell.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Copyright (c) 2018 Diego Sueiro
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <shell/shell.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <device.h>
  11. #include <drivers/sensor.h>
  12. #define SENSOR_GET_HELP \
  13. "Get sensor data. Channel names are optional. All channels are read " \
  14. "when no channels are provided. Syntax:\n" \
  15. "<device_name> <channel name 0> .. <channel name N>"
  16. const char *sensor_channel_name[SENSOR_CHAN_ALL] = {
  17. [SENSOR_CHAN_ACCEL_X] = "accel_x",
  18. [SENSOR_CHAN_ACCEL_Y] = "accel_y",
  19. [SENSOR_CHAN_ACCEL_Z] = "accel_z",
  20. [SENSOR_CHAN_ACCEL_XYZ] = "accel_xyz",
  21. [SENSOR_CHAN_GYRO_X] = "gyro_x",
  22. [SENSOR_CHAN_GYRO_Y] = "gyro_y",
  23. [SENSOR_CHAN_GYRO_Z] = "gyro_z",
  24. [SENSOR_CHAN_GYRO_XYZ] = "gyro_xyz",
  25. [SENSOR_CHAN_MAGN_X] = "magn_x",
  26. [SENSOR_CHAN_MAGN_Y] = "magn_y",
  27. [SENSOR_CHAN_MAGN_Z] = "magn_z",
  28. [SENSOR_CHAN_MAGN_XYZ] = "magn_xyz",
  29. [SENSOR_CHAN_DIE_TEMP] = "die_temp",
  30. [SENSOR_CHAN_AMBIENT_TEMP] = "ambient_temp",
  31. [SENSOR_CHAN_PRESS] = "press",
  32. [SENSOR_CHAN_PROX] = "prox",
  33. [SENSOR_CHAN_HUMIDITY] = "humidity",
  34. [SENSOR_CHAN_LIGHT] = "light",
  35. [SENSOR_CHAN_IR] = "ir",
  36. [SENSOR_CHAN_RED] = "red",
  37. [SENSOR_CHAN_GREEN] = "green",
  38. [SENSOR_CHAN_BLUE] = "blue",
  39. [SENSOR_CHAN_ALTITUDE] = "altitude",
  40. [SENSOR_CHAN_PM_1_0] = "pm_1_0",
  41. [SENSOR_CHAN_PM_2_5] = "pm_2_5",
  42. [SENSOR_CHAN_PM_10] = "pm_10",
  43. [SENSOR_CHAN_DISTANCE] = "distance",
  44. [SENSOR_CHAN_CO2] = "co2",
  45. [SENSOR_CHAN_VOC] = "voc",
  46. [SENSOR_CHAN_GAS_RES] = "gas_resistance",
  47. [SENSOR_CHAN_VOLTAGE] = "voltage",
  48. [SENSOR_CHAN_CURRENT] = "current",
  49. [SENSOR_CHAN_RESISTANCE] = "resistance",
  50. [SENSOR_CHAN_ROTATION] = "rotation",
  51. [SENSOR_CHAN_POS_DX] = "pos_dx",
  52. [SENSOR_CHAN_POS_DY] = "pos_dy",
  53. [SENSOR_CHAN_POS_DZ] = "pos_dz",
  54. [SENSOR_CHAN_RPM] = "rpm",
  55. [SENSOR_CHAN_GAUGE_VOLTAGE] = "gauge_voltage",
  56. [SENSOR_CHAN_GAUGE_AVG_CURRENT] = "gauge_avg_current",
  57. [SENSOR_CHAN_GAUGE_STDBY_CURRENT] = "gauge_stdby_current",
  58. [SENSOR_CHAN_GAUGE_MAX_LOAD_CURRENT] = "gauge_max_load_current",
  59. [SENSOR_CHAN_GAUGE_TEMP] = "gauge_temp",
  60. [SENSOR_CHAN_GAUGE_STATE_OF_CHARGE] = "gauge_state_of_charge",
  61. [SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY] = "gauge_full_cap",
  62. [SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY] = "gauge_remaining_cap",
  63. [SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY] = "gauge_nominal_cap",
  64. [SENSOR_CHAN_GAUGE_FULL_AVAIL_CAPACITY] = "gauge_full_cap",
  65. [SENSOR_CHAN_GAUGE_AVG_POWER] = "gauge_avg_power",
  66. [SENSOR_CHAN_GAUGE_STATE_OF_HEALTH] = "gauge_state_of_health",
  67. [SENSOR_CHAN_GAUGE_TIME_TO_EMPTY] = "gauge_time_to_empty",
  68. [SENSOR_CHAN_GAUGE_TIME_TO_FULL] = "gauge_time_to_full",
  69. [SENSOR_CHAN_GAUGE_CYCLE_COUNT] = "gauge_cycle_count",
  70. [SENSOR_CHAN_GAUGE_DESIGN_VOLTAGE] = "gauge_design_voltage",
  71. [SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE] = "gauge_desired_voltage",
  72. [SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT] =
  73. "gauge_desired_charging_current",
  74. };
  75. static int handle_channel_by_name(const struct shell *shell,
  76. const struct device *dev,
  77. const char *channel_name)
  78. {
  79. struct sensor_value value[3];
  80. char *endptr;
  81. int err;
  82. int i;
  83. /* Attempt to parse channel name as a number first */
  84. i = strtoul(channel_name, &endptr, 0);
  85. if (*endptr != '\0') {
  86. /* Channel name is not a number, look it up */
  87. for (i = 0; i < ARRAY_SIZE(sensor_channel_name); i++) {
  88. if (strcmp(channel_name, sensor_channel_name[i]) == 0) {
  89. break;
  90. }
  91. }
  92. if (i == ARRAY_SIZE(sensor_channel_name)) {
  93. shell_error(shell, "Channel not supported (%s)",
  94. channel_name);
  95. return -ENOTSUP;
  96. }
  97. }
  98. err = sensor_channel_get(dev, i, value);
  99. if (err < 0) {
  100. return err;
  101. }
  102. if (i >= ARRAY_SIZE(sensor_channel_name)) {
  103. shell_print(shell, "channel idx=%d value = %10.6f", i,
  104. sensor_value_to_double(&value[0]));
  105. } else if (i != SENSOR_CHAN_ACCEL_XYZ &&
  106. i != SENSOR_CHAN_GYRO_XYZ &&
  107. i != SENSOR_CHAN_MAGN_XYZ) {
  108. shell_print(shell,
  109. "channel idx=%d %s = %10.6f", i,
  110. sensor_channel_name[i],
  111. sensor_value_to_double(&value[0]));
  112. } else {
  113. shell_print(shell,
  114. "channel idx=%d %s x = %10.6f y = %10.6f z = %10.6f",
  115. i, sensor_channel_name[i],
  116. sensor_value_to_double(&value[0]),
  117. sensor_value_to_double(&value[1]),
  118. sensor_value_to_double(&value[2]));
  119. }
  120. return 0;
  121. }
  122. static int cmd_get_sensor(const struct shell *shell, size_t argc, char *argv[])
  123. {
  124. const struct device *dev;
  125. int err;
  126. dev = device_get_binding(argv[1]);
  127. if (dev == NULL) {
  128. shell_error(shell, "Device unknown (%s)", argv[1]);
  129. return -ENODEV;
  130. }
  131. err = sensor_sample_fetch(dev);
  132. if (err < 0) {
  133. shell_error(shell, "Failed to read sensor: %d", err);
  134. }
  135. if (argc == 2) {
  136. /* read all channels */
  137. for (int i = 0; i < ARRAY_SIZE(sensor_channel_name); i++) {
  138. if (sensor_channel_name[i]) {
  139. handle_channel_by_name(shell, dev,
  140. sensor_channel_name[i]);
  141. }
  142. }
  143. } else {
  144. for (int i = 2; i < argc; i++) {
  145. err = handle_channel_by_name(shell, dev, argv[i]);
  146. if (err < 0) {
  147. shell_error(shell,
  148. "Failed to read channel (%s)", argv[i]);
  149. }
  150. }
  151. }
  152. return 0;
  153. }
  154. static void channel_name_get(size_t idx, struct shell_static_entry *entry);
  155. SHELL_DYNAMIC_CMD_CREATE(dsub_channel_name, channel_name_get);
  156. static void channel_name_get(size_t idx, struct shell_static_entry *entry)
  157. {
  158. int cnt = 0;
  159. entry->syntax = NULL;
  160. entry->handler = NULL;
  161. entry->help = NULL;
  162. entry->subcmd = &dsub_channel_name;
  163. for (int i = 0; i < SENSOR_CHAN_ALL; i++) {
  164. if (sensor_channel_name[i] != NULL) {
  165. if (cnt == idx) {
  166. entry->syntax = sensor_channel_name[i];
  167. break;
  168. }
  169. cnt++;
  170. }
  171. }
  172. }
  173. static void device_name_get(size_t idx, struct shell_static_entry *entry);
  174. SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get);
  175. static void device_name_get(size_t idx, struct shell_static_entry *entry)
  176. {
  177. const struct device *dev = shell_device_lookup(idx, NULL);
  178. entry->syntax = (dev != NULL) ? dev->name : NULL;
  179. entry->handler = NULL;
  180. entry->help = NULL;
  181. entry->subcmd = &dsub_channel_name;
  182. }
  183. SHELL_STATIC_SUBCMD_SET_CREATE(sub_sensor,
  184. SHELL_CMD_ARG(get, &dsub_device_name, SENSOR_GET_HELP, cmd_get_sensor,
  185. 2, 255),
  186. SHELL_SUBCMD_SET_END
  187. );
  188. SHELL_CMD_REGISTER(sensor, &sub_sensor, "Sensor commands", NULL);