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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
extern crate hidapi;
extern crate color_processing;
extern crate timer;
extern crate chrono;
use color_processing::Color;
use timer::{Guard, Timer};
use std::sync::{Arc, Mutex};
use std::ops::Deref;
const VID: u16 = 0x04D8;
pub enum Tones {
OpenOffice = 136,
Quiet = 144,
Funky = 152,
FairyTale = 160,
KuandoTrain = 168,
TelephoneNordic = 176,
TelephoneOriginal = 184,
TelephonePickMeUp = 192,
Buzz = 216
}
pub enum Positions {
Red = 3,
Green = 4,
Blue = 5,
Sound = 8
}
pub struct BusyLight {
device: Arc<Mutex<hidapi::HidDevice>>,
buffer: Arc<Mutex<[u8; 9]>>,
keep_alive_timer: Timer,
keep_alive_guard: Guard,
}
impl BusyLight {
pub fn new() -> Self {
let api = match hidapi::HidApi::new() {
Ok(api) => api,
Err(_) => panic!("Can't init hidapi!"),
};
let devices = api.devices();
let mut pid: u16 = 0xF848;
for d in devices {
if d.vendor_id == VID {
pid = d.product_id;
break;
}
}
let device = Arc::new(Mutex::new(match api.open(VID, pid) {
Ok(dev) => dev,
Err(_) => panic!("Can't find the BusyLight! Is it plugged in?"),
}));
let defaults = Arc::new(Mutex::new([0, 0, 0, 0, 0, 0, 0, 0, 128]));
let timer = timer::Timer::new();
let guard = timer.schedule_with_delay(chrono::Duration::minutes(1000), || {});
BusyLight{device: device, buffer: defaults, keep_alive_timer: timer, keep_alive_guard: guard}
}
pub fn send(&mut self) {
let shared_device = self.device.clone();
let shared_buffer = self.buffer.clone();
let dev = shared_device.lock().unwrap();
let buf = shared_buffer.lock().unwrap();
dev.write(buf.deref()).expect("Can't write payload to device!");
}
pub fn keepalive_enable(&mut self) {
let shared_device = self.device.clone();
let shared_buffer = self.buffer.clone();
self.keep_alive_guard = self.keep_alive_timer.schedule_repeating(chrono::Duration::seconds(20), move || {
let dev = shared_device.lock().unwrap();
let buf = shared_buffer.lock().unwrap();
dev.write(buf.deref()).expect("KeepAlive: Can't write payload to device!");
});
}
pub fn keepalive_disable(&mut self) {
self.keep_alive_guard = self.keep_alive_timer.schedule_with_delay(chrono::Duration::minutes(1000), || {});
}
pub fn ring(&mut self, tone: Tones, volume: u8) {
if volume > 7 {
panic!("[ring()] Volume can only be between 0-7 with both inclusive")
}
self.stop_ring();
let shared_buffer = self.buffer.clone();
let mut buf = shared_buffer.lock().unwrap();
buf[Positions::Sound as usize] = (tone as u8) + volume;
drop(buf);
self.send();
}
pub fn stop_ring(&mut self) {
let shared_buffer = self.buffer.clone();
let mut buf = shared_buffer.lock().unwrap();
buf[Positions::Sound as usize] = 128;
drop(buf);
self.send();
}
pub fn light(&mut self, colour: &str) {
let col = Color::new_string(colour).unwrap();
let shared_buffer = self.buffer.clone();
let mut buf = shared_buffer.lock().unwrap();
buf[Positions::Red as usize] = col.red;
buf[Positions::Green as usize] = col.green;
buf[Positions::Blue as usize] = col.blue;
drop(buf);
self.send();
}
pub fn stop_light(&mut self) {
let shared_buffer = self.buffer.clone();
let mut buf = shared_buffer.lock().unwrap();
buf[Positions::Red as usize] = 0;
buf[Positions::Green as usize] = 0;
buf[Positions::Blue as usize] = 0;
drop(buf);
self.send();
}
}