-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathactions.rs
120 lines (94 loc) · 3.51 KB
/
actions.rs
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use anyhow::bail;
use embedded_svc::wifi::{ClientConfiguration, Configuration, Wifi};
use esp_idf_hal::interrupt;
use esp_idf_hal::modem::Modem;
use esp_idf_svc::eventloop::EspSystemEventLoop;
use esp_idf_svc::nvs::EspDefaultNvsPartition;
use esp_idf_svc::sntp::{self, SyncStatus};
use esp_idf_svc::wifi::{EspWifi, WifiWait};
use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
use std::cell::RefCell;
use std::sync::Mutex;
use std::time::Duration;
use bytebeam_esp_rs::{Action, ByteBeamClient};
use esp_idf_hal::gpio::{Gpio2, Output, PinDriver};
use esp_idf_hal::peripherals::Peripherals;
static ONBOARD_LED: Mutex<RefCell<Option<PinDriver<Gpio2, Output>>>> =
Mutex::new(RefCell::new(None));
#[toml_cfg::toml_config]
pub struct Config {
#[default("")]
wifi_ssid: &'static str,
#[default("")]
wifi_psk: &'static str,
}
fn main() -> anyhow::Result<()> {
// It is necessary to call this function once. Otherwise some patches to the runtime
// implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
esp_idf_sys::link_patches();
esp_idf_svc::log::EspLogger::initialize_default();
let peripherals = Peripherals::take().unwrap();
let sysloop = EspSystemEventLoop::take()?;
let nvs = EspDefaultNvsPartition::take()?;
let _wifi = connect_wifi(peripherals.modem, sysloop.clone(), nvs)?;
let sntp = sntp::EspSntp::new_default().unwrap();
while sntp.get_sync_status() != SyncStatus::Completed {}
println!("SNTP Initialized");
let pin2 = peripherals.pins.gpio2;
let pin2_driver = PinDriver::output(pin2)?;
interrupt::free(|| ONBOARD_LED.lock().unwrap().replace(Some(pin2_driver)));
// Bytebeam!
let bytebeam_client = ByteBeamClient::init()?;
bytebeam_client.register_action_handle("toggle".into(), &toggle);
loop {
std::thread::sleep(Duration::from_secs(1));
}
}
fn toggle(action: Action, bytebeam_client: &ByteBeamClient) {
let mut onboard_led = ONBOARD_LED.lock().unwrap();
let onboard_led = onboard_led.get_mut().as_mut().unwrap();
match onboard_led.toggle() {
Ok(_) => bytebeam_client.publish_action_status(&action.id, 100, "Toggled", None),
Err(_) => bytebeam_client.publish_action_status(
&action.id,
0,
"Failed",
Some(&["Failed to toggle LED"]),
),
}
.ok(); // just to satisfy clippy for now!
}
fn connect_wifi(
modem: Modem,
sysloop: EspSystemEventLoop,
nvs: EspDefaultNvsPartition,
) -> anyhow::Result<EspWifi<'static>> {
let wifi_configs = CONFIG;
let mut wifi_driver = EspWifi::new(modem, sysloop.clone(), Some(nvs))?;
let ap_infos = wifi_driver.scan()?;
let ours = ap_infos
.into_iter()
.find(|a| a.ssid == wifi_configs.wifi_ssid);
let channel = if let Some(ours) = ours {
Some(ours.channel)
} else {
None
};
wifi_driver.set_configuration(&Configuration::Client(ClientConfiguration {
ssid: wifi_configs.wifi_ssid.into(),
password: wifi_configs.wifi_psk.into(),
channel,
..Default::default()
}))?;
wifi_driver.start()?;
if !WifiWait::new(&sysloop)?.wait_with_timeout(Duration::from_secs(20), || {
wifi_driver.is_started().unwrap()
}) {
bail!("Wifi did not start");
}
wifi_driver.connect()?;
while !wifi_driver.is_connected()? {
std::thread::sleep(Duration::from_millis(200));
}
Ok(wifi_driver)
}