Skip to content

Commit c1bf87a

Browse files
feat: add home screen clock counter support
Within this commit, we introduce a device twin configuration manager. This device twin singleton instance will hold all the details about the hardware. Furthermore, we store the latest time information on the device twin and update the home screen view every minute to track the time information.
1 parent d75770d commit c1bf87a

File tree

5 files changed

+123
-15
lines changed

5 files changed

+123
-15
lines changed

src/devicetwin/devicetwin.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <stdlib.h>
2+
#include "devicetwin/devicetwin.h"
3+
4+
// Function to construct a single device twin instance. This is a singleton.
5+
static device_twin_t* s_device_twin_instance = NULL;
6+
7+
device_twin_t* get_device_twin_instance(void) {
8+
return s_device_twin_instance;
9+
}
10+
11+
device_twin_t* create_device_twin_instance(utc_time_t current_time, int8_t utc_zone) {
12+
device_twin_t* instance = malloc(sizeof(device_twin_t));
13+
instance->current_time = current_time;
14+
instance->utc_zone = utc_zone;
15+
// For now, we'll assume the singleton instance is always created.
16+
s_device_twin_instance = instance;
17+
return instance;
18+
}

src/devicetwin/devicetwin.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#ifndef _DEVICE_TWIN_H
2+
#define _DEVICE_TWIN_H
3+
4+
#include <timeutils/timeutils.h>
5+
6+
#ifdef __cplusplus
7+
extern "C" {
8+
#endif
9+
10+
/* A struct that holds the device settings.
11+
* This datatype will hold the neccesarry details
12+
* about the smart-watch's daily usage such as
13+
* health monitoring, time, user settings, etc.
14+
*/
15+
typedef struct {
16+
utc_time_t current_time;
17+
int8_t utc_zone;
18+
} device_twin_t;
19+
20+
/*
21+
* Function to construct a new device twin instance with given parameters.
22+
*/
23+
device_twin_t* create_device_twin_instance(utc_time_t current_timei, int8_t utc_zone);
24+
25+
/*
26+
* Factory method to get the existing or newly constructed singleton device twin instance.
27+
*/
28+
device_twin_t* get_device_twin_instance(void);
29+
30+
#ifdef __cplusplus
31+
} // extern "C"
32+
#endif
33+
34+
#endif

src/display/screens/home/home.c

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,50 @@
33

44
// Holds the home screen object.
55
lv_obj_t *home_screen;
6-
6+
lv_obj_t *label_clock;
77

88
void home_screen_init() {
99
// Create the screen object which is the LV object with no parent.
1010
home_screen = lv_obj_create(NULL);
11+
// Remove the ability to scroll the screen.
1112
lv_obj_remove_flag(home_screen, LV_OBJ_FLAG_SCROLLABLE);
1213

13-
lv_obj_t *ui_ClockText = lv_label_create(home_screen);
14-
lv_obj_set_width( ui_ClockText, LV_SIZE_CONTENT); /// 2
15-
lv_obj_set_height( ui_ClockText, LV_SIZE_CONTENT); /// 2
16-
lv_obj_set_align( ui_ClockText, LV_ALIGN_CENTER );
17-
lv_label_set_text(ui_ClockText,"21\n14");
18-
lv_obj_set_style_text_letter_space(ui_ClockText, 5, LV_PART_MAIN| LV_STATE_DEFAULT);
19-
lv_obj_set_style_text_line_space(ui_ClockText, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
20-
lv_obj_set_style_text_align(ui_ClockText, LV_TEXT_ALIGN_AUTO, LV_PART_MAIN| LV_STATE_DEFAULT);
21-
lv_obj_set_style_text_decor(ui_ClockText, LV_TEXT_DECOR_NONE, LV_PART_MAIN| LV_STATE_DEFAULT);
22-
lv_obj_set_style_text_font(ui_ClockText, &lv_font_montserrat_46, LV_PART_MAIN| LV_STATE_DEFAULT);
14+
// Create a new label and expand its size to content size and align it to center.
15+
label_clock = lv_label_create(home_screen);
16+
lv_obj_set_width(label_clock, LV_SIZE_CONTENT);
17+
lv_obj_set_height(label_clock, LV_SIZE_CONTENT);
18+
lv_obj_set_align(label_clock, LV_ALIGN_CENTER);
19+
20+
// Set the default text.
21+
lv_label_set_text(label_clock, "HH\nMM");
22+
23+
// Format the clock text string.
24+
/* 1. Set the letter spacing to 5. (Between letters)
25+
* 2. Set the line spacing to 0. (Between new lines)
26+
* 3. Align the text automatically.
27+
* 4. Set no decoration on the text.
28+
* 5. Set the font and the size to Montserrat 46.
29+
*/
30+
lv_obj_set_style_text_letter_space(label_clock, 5, LV_PART_MAIN | LV_STATE_DEFAULT);
31+
lv_obj_set_style_text_line_space(label_clock, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
32+
lv_obj_set_style_text_align(label_clock, LV_TEXT_ALIGN_AUTO, LV_PART_MAIN | LV_STATE_DEFAULT);
33+
lv_obj_set_style_text_decor(label_clock, LV_TEXT_DECOR_NONE, LV_PART_MAIN | LV_STATE_DEFAULT);
34+
lv_obj_set_style_text_font(label_clock, &lv_font_montserrat_46, LV_PART_MAIN | LV_STATE_DEFAULT);
2335

36+
// Add an event handler for all possible events.
2437
lv_obj_add_event_cb(home_screen, home_screen_event, LV_EVENT_ALL, NULL);
2538
}
2639

2740
void home_screen_event(lv_event_t * e) {
2841
// lv_event_code_t event_code = lv_event_get_code(e);lv_obj_t * target = lv_event_get_target(e);
2942
}
43+
44+
uint8_t home_screen_set_clock(uint8_t hour, uint8_t minute) {
45+
// Check if the label_clock is NULL.
46+
if (label_clock == NULL) return 1;
47+
// Set the text of the label_clock to the current time in 24-hour format.
48+
lv_label_set_text_fmt(label_clock, "%02d:%02d", hour, minute);
49+
// Update the display.
50+
lv_disp_flush_ready(lv_disp_get_default());
51+
return 0;
52+
}

src/display/screens/home/home.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ extern lv_obj_t *home_screen;
1414
void home_screen_init();
1515
void home_screen_event(lv_event_t * e);
1616

17+
// Set the time on the clock. Returns 0 if successful, 1 otherwise.
18+
uint8_t home_screen_set_clock(uint8_t hour, uint8_t minute);
19+
1720

1821
#ifdef __cplusplus
1922
} // extern "C"

src/main.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@
2020
#include <zephyr/drivers/pwm.h>
2121

2222
#include "display/display.h"
23+
#include "display/screens/home/home.h"
2324
#include "timeutils/timeutils.h"
25+
#include "devicetwin/devicetwin.h"
2426

2527
// Define the logger.
2628
LOG_MODULE_REGISTER(ZephyrWatch, LOG_LEVEL_DBG);
2729

2830
// Global value to hold time value in UNIX time.
2931
uint32_t unix_time = 1748554674;
32+
int8_t utc_zone = +1;
3033

3134
// Define timers to track real time.
3235
void update_unix_time_callback(struct k_timer *timer);
@@ -43,6 +46,13 @@ const char* weekdays[] = {
4346
int main(void) {
4447
int ret;
4548

49+
// Create the device twin.
50+
device_twin_t* device_twin = create_device_twin_instance(unix_to_localtime(unix_time, utc_zone), utc_zone);
51+
if (!device_twin) {
52+
LOG_ERR("Cannot create device twin instance.");
53+
return 0;
54+
}
55+
4656
// Start the timer to track the real time.
4757
k_timer_start(&unix_time_timer, K_MSEC(0), K_MSEC(1000));
4858
k_timer_start(&clock_view_timer, K_SECONDS(60), K_SECONDS(60));
@@ -98,8 +108,28 @@ void update_unix_time_callback(struct k_timer *timer) {
98108
* the clock view in the LVGL UI by using the unix_time variable.
99109
*/
100110
void update_clock_view_callback(struct k_timer *timer) {
101-
utc_time_t local = unix_to_localtime(unix_time, +1); // UTC+1
102-
LOG_INF("Local : %04u-%02u-%02u %02u:%02u:%02u (%s) [UTC+1]",
103-
local.year, local.month, local.day, local.hour, local.minute, local.second,
104-
weekdays[local.weekday]);
111+
// Get the device twin to find UTC zone.
112+
device_twin_t* device_twin = get_device_twin_instance();
113+
114+
// Construct the local time from UNIX time and save it.
115+
utc_time_t local_time = unix_to_localtime(unix_time, device_twin->utc_zone);
116+
device_twin->current_time = local_time;
117+
118+
// Log the current time.
119+
LOG_INF("Setting new time. %04u-%02u-%02u %02u:%02u:%02u (%s) [UTC %d]",
120+
device_twin->current_time.year,
121+
device_twin->current_time.month,
122+
device_twin->current_time.day,
123+
device_twin->current_time.hour,
124+
device_twin->current_time.minute,
125+
device_twin->current_time.second,
126+
weekdays[device_twin->current_time.weekday],
127+
device_twin->utc_zone
128+
);
129+
130+
// Update the clock view.
131+
uint8_t ret = home_screen_set_clock(device_twin->current_time.hour, device_twin->current_time.minute);
132+
if (ret != 0) {
133+
LOG_ERR("Failed to update the clock view.");
134+
}
105135
}

0 commit comments

Comments
 (0)