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
|
#include "button.h"
#include "display.h"
#include "http_api.h"
#include "jpeg_decoder.h"
#include "local_screens.h"
#include "mdns_service.h"
#include "net_eth.h"
#include "nvs_config.h"
#include "state_client.h"
#include "state_machine.h"
#include "touch.h"
#include "viewport_state.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "nvs_flash.h"
static const char *TAG = "viewport";
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
viewport_state_init();
nvs_config_load(); // apply persisted config over defaults (best-effort)
ESP_LOGI(TAG, "Scrypted Viewport boot (v%s)", VIEWPORT_VERSION);
ESP_ERROR_CHECK(net_eth_init());
if (net_eth_wait_for_ip(30 * 1000) == ESP_OK) {
ESP_LOGI(TAG, "online at %s", net_eth_get_ip_str());
} else {
ESP_LOGW(TAG, "no DHCP lease after 30s, will keep retrying in the background");
}
ESP_ERROR_CHECK(state_machine_init());
ESP_ERROR_CHECK(state_client_init());
ESP_ERROR_CHECK(mdns_service_start());
ESP_ERROR_CHECK(http_api_start());
// Display is best-effort — a missing/miswired panel must not kill
// networking + /state.
if (display_init() == ESP_OK) {
local_screens_init();
// Reconcile panel with current run-state:
// UNCONFIGURED -> IP screen (so operator can register from Scrypted)
// ASLEEP -> backlight off (configured device booted asleep)
// AWAKE -> leave on (not reached on fresh boot)
viewport_state_lock();
viewport_run_state_t s = viewport_state_get()->state;
viewport_state_unlock();
if (s == VIEWPORT_STATE_ASLEEP) {
display_sleep();
ESP_LOGI(TAG, "display up — configured, backlight off (asleep)");
} else {
local_screens_show_ip();
ESP_LOGI(TAG, "display up — IP screen (unconfigured)");
}
} else {
ESP_LOGW(TAG, "display init failed — continuing without panel");
}
// JPEG decoder is the M5 dependency for POST /frame. Best-effort.
if (jpeg_decoder_init() != ESP_OK) {
ESP_LOGW(TAG, "jpeg decoder init failed — /frame will be unavailable");
}
// Touch shares the panel I2C bus; only meaningful if display came up.
if (display_is_up()) {
if (touch_init() != ESP_OK) {
ESP_LOGW(TAG, "touch init failed — taps won't work");
}
}
// BOOT button — short press = IP overlay, hold 5s = factory reset.
// GPIO is a guess until confirmed against the Waveshare schematic.
if (button_init() != ESP_OK) {
ESP_LOGW(TAG, "BOOT button init failed — overlay + factory reset disabled");
}
}
|