Skip to content
This repository was archived by the owner on Jul 9, 2024. It is now read-only.

Commit ae1b6e5

Browse files
author
GitHub Actions
committed
1 parent 29397e3 commit ae1b6e5

13 files changed

Lines changed: 614 additions & 204 deletions

File tree

doc/ui_module.rst

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,32 @@ LED indication
4040
The module supports multiple LED patterns to visualize the operating state of the application.
4141
The following table describes the supported LED states:
4242

43-
+---------------------------+-------------------------+-----------------------+
44-
| State | Thingy:91 RGB LED | nRF9160 DK solid LEDs |
45-
+===========================+=========================+=======================+
46-
| LTE connection search | Yellow, blinking | LED1 blinking |
47-
+---------------------------+-------------------------+-----------------------+
48-
| GNSS fix search | Purple, blinking | LED2 blinking |
49-
+---------------------------+-------------------------+-----------------------+
50-
| Publishing data | Green, blinking | LED3 blinking |
51-
+---------------------------+-------------------------+-----------------------+
52-
| Active mode | Light blue, blinking | LED4 blinking |
53-
+---------------------------+-------------------------+-----------------------+
54-
| Passive mode | Dark blue, slow blinking| LED4 slow blinking |
55-
+---------------------------+-------------------------+-----------------------+
56-
| Error | Red, static | all 4 LEDs blinking |
57-
+---------------------------+-------------------------+-----------------------+
58-
| Completion of FOTA update | White, rapid blinking | all 4 LEDs on |
59-
+---------------------------+-------------------------+-----------------------+
43+
+---------------------------+------------------------------+----------------------------+
44+
| State | Thingy:91 RGB LED | nRF9160 DK solid LEDs |
45+
+===========================+==============================+============================+
46+
| LTE connection search | Yellow, blinking | LED1 blinking |
47+
+---------------------------+------------------------------+----------------------------+
48+
| GNSS fix search | Purple, blinking | LED2 blinking |
49+
+---------------------------+------------------------------+----------------------------+
50+
| Cloud association | White, double pulse blinking | LED3 double pulse blinking |
51+
+---------------------------+------------------------------+----------------------------+
52+
| Connecting to cloud | Green, triple pulse blinking | LED3 triple pulse blinking |
53+
+---------------------------+------------------------------+----------------------------+
54+
| Publishing data | Green, blinking | LED3 blinking |
55+
+---------------------------+------------------------------+----------------------------+
56+
| Active mode | Light blue, blinking | LED4 blinking |
57+
+---------------------------+------------------------------+----------------------------+
58+
| Passive mode | Dark blue, blinking | LED3 and LED4 blinking |
59+
+---------------------------+------------------------------+----------------------------+
60+
| Error | Red, static | All 4 LEDs blinking |
61+
+---------------------------+------------------------------+----------------------------+
62+
| FOTA update | Orange, rapid blinking | LED1 and LED2 blinking |
63+
+---------------------------+------------------------------+----------------------------+
64+
| Completion of FOTA update | Orange, static | LED1 and LED2 static |
65+
+---------------------------+------------------------------+----------------------------+
66+
67+
.. note::
68+
The LED pattern that indicates the device mode is visible for a few seconds after an update has been sent to cloud.
6069

6170
Configuration options
6271
*********************
@@ -73,14 +82,20 @@ The UI module continuously updates its internal state based on the mode and oper
7382
This ensures that the correct LED pattern is displayed when the application changes its state of operation.
7483
The UI module has an internal state machine with the following states:
7584

76-
* ``STATE_ACTIVE`` - The application is in the active mode, revert to the active mode LED pattern.
77-
* ``STATE_PASSIVE`` - The application is in the passive mode, revert to the passive mode LED pattern.
85+
* ``STATE_INIT`` - The initial state of the module.
86+
* ``STATE_RUNNING`` - The module has performed all the required initializations and can initiate the display of LED patterns based on incoming events from other modules.
7887

79-
* ``SUB_STATE_GNSS_ACTIVE`` - The application is performing a GNSS search, revert to the GNSS search LED pattern.
80-
* ``SUB_STATE_GNSS_INACTIVE`` - A GNSS search is not being performed.
88+
* ``SUB_STATE_ACTIVE`` - The application is in the active mode. The module reverts to the active mode LED pattern after cloud publication.
89+
* ``SUB_STATE_PASSIVE`` - The application is in the passive mode. The module reverts to the passive mode LED pattern after cloud publication.
8190

82-
* ``STATE_SHUTDOWN`` - The module has been shut down after receiving a request from the utility module.
91+
* ``SUB_SUB_STATE_GNSS_ACTIVE`` - The application is performing a GNSS search. The module reverts to the GNSS search LED pattern.
92+
* ``SUB_SUB_STATE_GNSS_INACTIVE`` - A GNSS search is not being performed.
8393

94+
* ``STATE_LTE_CONNECTING`` - The modem module is performing an LTE connection search. The UI module triggers the LTE connection search LED pattern.
95+
* ``STATE_CLOUD_CONNECTING`` - The cloud module is connecting to cloud. The UI module triggers the cloud connection LED pattern.
96+
* ``STATE_CLOUD_ASSOCIATING`` - The cloud module is performing user association. The UI module triggers the cloud association LED pattern.
97+
* ``STATE_FOTA_UPDATING`` - The cloud module is performing a FOTA update. The UI module triggers the FOTA update LED pattern.
98+
* ``STATE_SHUTDOWN`` - The module has been shut down after receiving a request from the utility module. It triggers the appropriate LED pattern that corresponds to the shutdown reason.
8499

85100
Module events
86101
*************
@@ -99,8 +114,7 @@ API documentation
99114
*****************
100115

101116
| Header file: :file:`asset_tracker_v2/src/events/ui_module_event.h`
102-
| Source files: :file:`asset_tracker_v2/src/events/ui_module_event.c`
103-
:file:`asset_tracker_v2/src/modules/ui_module.c`
117+
| Source files: :file:`asset_tracker_v2/src/events/ui_module_event.c`, :file:`asset_tracker_v2/src/modules/ui_module.c`
104118
105119
.. doxygengroup:: ui_module_event
106120
:project: nrf

include/nrf9160dk_nrf9160_ns/led_state_def.h

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,45 @@ enum led_id {
2525
LED_ID_COUNT,
2626

2727
LED_ID_CONNECTING = LED_ID_1,
28+
LED_ID_CLOUD_CONNECTING = LED_ID_3,
2829
LED_ID_SEARCHING = LED_ID_2,
2930
LED_ID_PUBLISHING = LED_ID_3,
30-
LED_ID_MODE = LED_ID_4,
31+
LED_ID_ASSOCIATING = LED_ID_3,
32+
LED_ID_ASSOCIATED = LED_ID_3,
33+
LED_ID_FOTA_1 = LED_ID_1,
34+
LED_ID_FOTA_2 = LED_ID_2,
35+
LED_ID_PASSIVE_MODE_1 = LED_ID_3,
36+
LED_ID_PASSIVE_MODE_2 = LED_ID_4,
37+
LED_ID_ACTIVE_MODE = LED_ID_4,
3138
};
3239

33-
#define LED_PERIOD_NORMAL 500
34-
#define LED_PERIOD_LONG 3500
40+
#define LED_PERIOD_NORMAL 350
41+
#define LED_PERIOD_RAPID 100
42+
#define LED_TICKS_DOUBLE 2
43+
#define LED_TICKS_TRIPLE 3
3544

3645
static const struct led_effect asset_tracker_led_effect[] = {
3746
[LED_STATE_LTE_CONNECTING] = LED_EFFECT_LED_BLINK(LED_PERIOD_NORMAL,
38-
LED_COLOR(100, 100, 100)),
47+
LED_COLOR(100, 100, 100)),
3948
[LED_STATE_GNSS_SEARCHING] = LED_EFFECT_LED_BLINK(LED_PERIOD_NORMAL,
40-
LED_COLOR(100, 100, 100)),
49+
LED_COLOR(100, 100, 100)),
4150
[LED_STATE_CLOUD_PUBLISHING] = LED_EFFECT_LED_BLINK(LED_PERIOD_NORMAL,
42-
LED_COLOR(100, 100, 100)),
51+
LED_COLOR(100, 100, 100)),
52+
[LED_STATE_CLOUD_CONNECTING] = LED_EFFECT_LED_CLOCK(LED_TICKS_TRIPLE,
53+
LED_COLOR(100, 100, 100)),
54+
[LED_STATE_CLOUD_ASSOCIATING] = LED_EFFECT_LED_CLOCK(LED_TICKS_DOUBLE,
55+
LED_COLOR(100, 100, 100)),
56+
[LED_STATE_CLOUD_ASSOCIATED] = LED_EFFECT_LED_ON_GO_OFF(LED_COLOR(100, 100, 100),
57+
LED_PERIOD_NORMAL,
58+
LED_PERIOD_RAPID),
4359
[LED_STATE_ACTIVE_MODE] = LED_EFFECT_LED_BLINK(LED_PERIOD_NORMAL,
44-
LED_COLOR(100, 100, 100)),
45-
[LED_STATE_PASSIVE_MODE] = LED_EFFECT_LED_BLINK(LED_PERIOD_LONG,
46-
LED_COLOR(100, 100, 100)),
60+
LED_COLOR(100, 100, 100)),
61+
[LED_STATE_PASSIVE_MODE] = LED_EFFECT_LED_BLINK(LED_PERIOD_NORMAL,
62+
LED_COLOR(100, 100, 100)),
4763
[LED_STATE_ERROR_SYSTEM_FAULT] = LED_EFFECT_LED_BLINK(LED_PERIOD_NORMAL,
48-
LED_COLOR(100, 100, 100)),
64+
LED_COLOR(100, 100, 100)),
65+
[LED_STATE_FOTA_UPDATING] = LED_EFFECT_LED_BLINK(LED_PERIOD_RAPID,
66+
LED_COLOR(100, 100, 100)),
4967
[LED_STATE_FOTA_UPDATE_REBOOT] = LED_EFFECT_LED_ON(LED_COLOR(100, 100, 100)),
5068
[LED_STATE_TURN_OFF] = LED_EFFECT_LED_OFF(),
5169
};

include/thingy91_nrf9160_ns/led_state_def.h

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,22 @@ enum led_id {
2222
LED_ID_COUNT,
2323

2424
LED_ID_CONNECTING = LED_ID_1,
25+
LED_ID_CLOUD_CONNECTING = LED_ID_1,
2526
LED_ID_SEARCHING = LED_ID_1,
2627
LED_ID_PUBLISHING = LED_ID_1,
27-
LED_ID_MODE = LED_ID_1,
28+
LED_ID_ASSOCIATING = LED_ID_1,
29+
LED_ID_ASSOCIATED = LED_ID_1,
30+
LED_ID_FOTA_1 = LED_ID_1,
31+
LED_ID_FOTA_2 = LED_ID_1,
32+
LED_ID_PASSIVE_MODE_1 = LED_ID_1,
33+
LED_ID_PASSIVE_MODE_2 = LED_ID_1,
34+
LED_ID_ACTIVE_MODE = LED_ID_1,
2835
};
2936

30-
31-
#define LED_PERIOD_NORMAL 500
32-
#define LED_PERIOD_LONG 3500
33-
#define LED_PERIOD_RAPID 200
37+
#define LED_PERIOD_NORMAL 350
38+
#define LED_PERIOD_RAPID 100
39+
#define LED_TICKS_DOUBLE 2
40+
#define LED_TICKS_TRIPLE 3
3441

3542
static const struct led_effect asset_tracker_led_effect[] = {
3643
[LED_STATE_LTE_CONNECTING] = LED_EFFECT_LED_BREATH(LED_PERIOD_NORMAL,
@@ -39,12 +46,20 @@ static const struct led_effect asset_tracker_led_effect[] = {
3946
LED_COLOR(255, 0, 255)),
4047
[LED_STATE_CLOUD_PUBLISHING] = LED_EFFECT_LED_BREATH(LED_PERIOD_NORMAL,
4148
LED_COLOR(0, 255, 0)),
49+
[LED_STATE_CLOUD_CONNECTING] = LED_EFFECT_LED_CLOCK(LED_TICKS_TRIPLE,
50+
LED_COLOR(0, 255, 0)),
51+
[LED_STATE_CLOUD_ASSOCIATING] = LED_EFFECT_LED_CLOCK(LED_TICKS_DOUBLE,
52+
LED_COLOR(255, 255, 255)),
53+
[LED_STATE_CLOUD_ASSOCIATED] = LED_EFFECT_LED_ON_GO_OFF(LED_COLOR(255, 255, 255),
54+
LED_PERIOD_NORMAL,
55+
LED_PERIOD_RAPID),
4256
[LED_STATE_ACTIVE_MODE] = LED_EFFECT_LED_BREATH(LED_PERIOD_NORMAL,
4357
LED_COLOR(0, 255, 255)),
44-
[LED_STATE_PASSIVE_MODE] = LED_EFFECT_LED_BREATH(LED_PERIOD_LONG,
58+
[LED_STATE_PASSIVE_MODE] = LED_EFFECT_LED_BREATH(LED_PERIOD_NORMAL,
4559
LED_COLOR(0, 0, 255)),
4660
[LED_STATE_ERROR_SYSTEM_FAULT] = LED_EFFECT_LED_ON(LED_COLOR(255, 0, 0)),
47-
[LED_STATE_FOTA_UPDATE_REBOOT] = LED_EFFECT_LED_BREATH(LED_PERIOD_RAPID,
48-
LED_COLOR(255, 255, 255)),
61+
[LED_STATE_FOTA_UPDATING] = LED_EFFECT_LED_BREATH(LED_PERIOD_RAPID,
62+
LED_COLOR(255, 165, 0)),
63+
[LED_STATE_FOTA_UPDATE_REBOOT] = LED_EFFECT_LED_ON(LED_COLOR(255, 165, 0)),
4964
[LED_STATE_TURN_OFF] = LED_EFFECT_LED_OFF(),
5065
};

src/cloud/cloud_wrapper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ enum cloud_wrap_event_type {
3535
* Payload is of type @ref cloud_wrap_event_data.
3636
*/
3737
CLOUD_WRAP_EVT_DATA_RECEIVED,
38+
/** User association request received from cloud. */
39+
CLOUD_WRAP_EVT_USER_ASSOCIATION_REQUEST,
40+
/** User association completed. */
41+
CLOUD_WRAP_EVT_USER_ASSOCIATED,
3842
/** A-GPS data received from the cloud integration layer.
3943
* Payload is of type @ref cloud_wrap_event_data.
4044
*/

src/cloud/nrf_cloud_integration.c

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ LOG_MODULE_REGISTER(MODULE, CONFIG_CLOUD_INTEGRATION_LOG_LEVEL);
1919
*/
2020
#define CELL_POS_FILTER_STRING "CELL_POS"
2121

22+
static struct k_work_delayable user_associating_work;
23+
2224
static cloud_wrap_evt_handler_t wrapper_evt_handler;
2325

2426
static void cloud_wrapper_notify_event(const struct cloud_wrap_event *evt)
@@ -30,6 +32,25 @@ static void cloud_wrapper_notify_event(const struct cloud_wrap_event *evt)
3032
}
3133
}
3234

35+
/* Work item that is called if user association fails to succeed within
36+
* CONFIG_CLOUD_USER_ASSOCIATION_TIMEOUT_SEC.
37+
*/
38+
static void user_association_work_fn(struct k_work *work)
39+
{
40+
/* Report an irrecoverable error in case user association fails. Will cause a reboot of the
41+
* application.
42+
*/
43+
struct cloud_wrap_event cloud_wrap_evt = {
44+
.type = CLOUD_WRAP_EVT_ERROR,
45+
.err = -ETIMEDOUT
46+
};
47+
48+
LOG_ERR("Failed to associate the device within: %d seconds",
49+
CONFIG_CLOUD_USER_ASSOCIATION_TIMEOUT_SEC);
50+
51+
cloud_wrapper_notify_event(&cloud_wrap_evt);
52+
}
53+
3354
static int send_service_info(void)
3455
{
3556
int err;
@@ -40,10 +61,12 @@ static int send_service_info(void)
4061
};
4162
struct nrf_cloud_svc_info_ui ui_info = {
4263
.gps = true,
64+
#if defined(CONFIG_BOARD_THINGY91_NRF9160_NS)
4365
.humidity = true,
4466
.air_pressure = true,
45-
.rsrp = true,
4667
.temperature = true,
68+
#endif
69+
.rsrp = true,
4770
.button = true
4871
};
4972
struct nrf_cloud_svc_info service_info = {
@@ -88,6 +111,8 @@ static void nrf_cloud_event_handler(const struct nrf_cloud_evt *evt)
88111
switch (evt->type) {
89112
case NRF_CLOUD_EVT_TRANSPORT_CONNECTING:
90113
LOG_DBG("NRF_CLOUD_EVT_TRANSPORT_CONNECTING");
114+
cloud_wrap_evt.type = CLOUD_WRAP_EVT_CONNECTING;
115+
notify = true;
91116
break;
92117
case NRF_CLOUD_EVT_TRANSPORT_CONNECTED:
93118
LOG_DBG("NRF_CLOUD_EVT_TRANSPORT_CONNECTED");
@@ -116,11 +141,21 @@ static void nrf_cloud_event_handler(const struct nrf_cloud_evt *evt)
116141
case NRF_CLOUD_EVT_SENSOR_DATA_ACK:
117142
LOG_DBG("NRF_CLOUD_EVT_SENSOR_DATA_ACK");
118143
break;
144+
case NRF_CLOUD_EVT_FOTA_START:
145+
LOG_DBG("NRF_CLOUD_EVT_FOTA_START");
146+
cloud_wrap_evt.type = CLOUD_WRAP_EVT_FOTA_START;
147+
notify = true;
148+
break;
119149
case NRF_CLOUD_EVT_FOTA_DONE:
120150
LOG_DBG("NRF_CLOUD_EVT_FOTA_DONE");
121151
cloud_wrap_evt.type = CLOUD_WRAP_EVT_FOTA_DONE;
122152
notify = true;
123153
break;
154+
case NRF_CLOUD_EVT_FOTA_ERROR:
155+
LOG_DBG("NRF_CLOUD_EVT_FOTA_ERROR");
156+
cloud_wrap_evt.type = CLOUD_WRAP_EVT_FOTA_ERROR;
157+
notify = true;
158+
break;
124159
case NRF_CLOUD_EVT_RX_DATA:
125160
LOG_DBG("NRF_CLOUD_EVT_RX_DATA");
126161

@@ -141,36 +176,41 @@ static void nrf_cloud_event_handler(const struct nrf_cloud_evt *evt)
141176
break;
142177
case NRF_CLOUD_EVT_USER_ASSOCIATION_REQUEST:
143178
LOG_WRN("NRF_CLOUD_EVT_USER_ASSOCIATION_REQUEST");
144-
LOG_WRN("Add the device to nRF Cloud and wait for it to reconnect");
145-
146-
/* A disconnect/reconnect is required by nRF Cloud after the
147-
* NRF_CLOUD_EVT_USER_ASSOCIATED event is received. This event is sent from
148-
* nRF Cloud when the device has been added to an nRF Cloud account.
149-
* However, it is likely that the device is in PSM when this occurs and not able to
150-
* receive this event.
151-
*
152-
* Due to this, we explicitly disconnect the application
153-
* when the NRF_CLOUD_EVT_USER_ASSOCIATION_REQUEST event is received and depend on
154-
* the reconnection routine in the cloud module to reconnect the application until
155-
* the device has been registered to the nRF Cloud account.
156-
*
157-
* It is expected that the application will disconnect and reconnect to nRF Cloud
158-
* several times during device association.
179+
LOG_WRN("Add the device to nRF Cloud to complete user association");
180+
181+
/* Schedule a work item that causes an error in case user association is not
182+
* carried out within a configurable amount of time.
159183
*/
160-
err = nrf_cloud_disconnect();
161-
if (err) {
162-
LOG_ERR("nrf_cloud_disconnect failed, error: %d", err);
184+
k_work_schedule(&user_associating_work,
185+
K_SECONDS(CONFIG_CLOUD_USER_ASSOCIATION_TIMEOUT_SEC));
163186

164-
/* If disconnection from nRF Cloud fails, the cloud module is notified with
165-
* an error. The application is expected to perform a reboot in order
166-
* to reconnect to nRF Cloud and complete device association.
167-
*/
168-
cloud_wrap_evt.type = CLOUD_WRAP_EVT_ERROR;
169-
notify = true;
170-
}
187+
cloud_wrap_evt.type = CLOUD_WRAP_EVT_USER_ASSOCIATION_REQUEST;
188+
notify = true;
171189
break;
172190
case NRF_CLOUD_EVT_USER_ASSOCIATED:
173191
LOG_DBG("NRF_CLOUD_EVT_USER_ASSOCIATED");
192+
193+
/* Disconnect/reconnect the device to apply the appropriate device policies and to
194+
* complete the user association process.
195+
*/
196+
if (k_work_delayable_is_pending(&user_associating_work)) {
197+
err = nrf_cloud_disconnect();
198+
if (err) {
199+
LOG_ERR("nrf_cloud_disconnect, error: %d", err);
200+
201+
cloud_wrap_evt.type = CLOUD_WRAP_EVT_ERROR;
202+
cloud_wrap_evt.err = err;
203+
cloud_wrapper_notify_event(&cloud_wrap_evt);
204+
return;
205+
}
206+
207+
/* Cancel user association timeout upon completion of user association. */
208+
k_work_cancel_delayable(&user_associating_work);
209+
210+
/* Notify the rest of the applicaiton that user association succeeded. */
211+
cloud_wrap_evt.type = CLOUD_WRAP_EVT_USER_ASSOCIATED;
212+
notify = true;
213+
}
174214
break;
175215
default:
176216
LOG_ERR("Unknown nRF Cloud event type: %d", evt->type);
@@ -202,6 +242,8 @@ int cloud_wrap_init(cloud_wrap_evt_handler_t event_handler)
202242
LOG_DBG(" Endpoint: %s", CONFIG_NRF_CLOUD_HOST_NAME);
203243
LOG_DBG("********************************************");
204244

245+
k_work_init_delayable(&user_associating_work, user_association_work_fn);
246+
205247
wrapper_evt_handler = event_handler;
206248

207249
return 0;

src/events/cloud_module_event.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ static char *get_evt_type_str(enum cloud_module_event_type type)
1919
return "CLOUD_EVT_CONNECTING";
2020
case CLOUD_EVT_CONNECTION_TIMEOUT:
2121
return "CLOUD_EVT_CONNECTION_TIMEOUT";
22+
case CLOUD_EVT_USER_ASSOCIATION_REQUEST:
23+
return "CLOUD_EVT_USER_ASSOCIATION_REQUEST";
24+
case CLOUD_EVT_USER_ASSOCIATED:
25+
return "CLOUD_EVT_USER_ASSOCIATED";
2226
case CLOUD_EVT_CONFIG_RECEIVED:
2327
return "CLOUD_EVT_CONFIG_RECEIVED";
2428
case CLOUD_EVT_CONFIG_EMPTY:
@@ -27,8 +31,12 @@ static char *get_evt_type_str(enum cloud_module_event_type type)
2731
return "CLOUD_EVT_DATA_ACK";
2832
case CLOUD_EVT_SHUTDOWN_READY:
2933
return "CLOUD_EVT_SHUTDOWN_READY";
34+
case CLOUD_EVT_FOTA_START:
35+
return "CLOUD_EVT_FOTA_START";
3036
case CLOUD_EVT_FOTA_DONE:
3137
return "CLOUD_EVT_FOTA_DONE";
38+
case CLOUD_EVT_FOTA_ERROR:
39+
return "CLOUD_EVT_FOTA_ERROR";
3240
case CLOUD_EVT_ERROR:
3341
return "CLOUD_EVT_ERROR";
3442
default:

0 commit comments

Comments
 (0)