-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathGlance.proto
495 lines (422 loc) · 13.8 KB
/
Glance.proto
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
syntax = "proto2";
//TODO: required with default?
enum Days {
None = 0;
Monday = 1;
Tuesday = 2;
Wednesday = 3;
Thursday = 4;
Friday = 5;
Saturday = 6;
Sunday = 7;
All = 8;
}
//TODO: is this even valid at all?
//It might be used for customScenes
enum SomeOtherAnimation {
NoneAnimation = 0;
Pulse = 1;
Wave = 2;
GifStart = 3;
Wheel = 5;
Flower = 6;
Flower2 = 7;
Fan = 8;
Sun = 9;
Thunderstorm = 10;
Cloud = 11;
WeatherStart = 13;
WeatherCloudy = 15;
WeatherFog = 16;
WeatherLightRain = 17;
WeatherRain = 18;
WeatherThunderstorm = 19;
WeatherSnow = 20;
WeatherHail = 21;
WeatherWind = 22;
WeatherTornado = 23;
WeatherHurricane = 24;
WeatherSnowThunderstorm = 25;
}
enum Animation {
NoneAnimation = 0;
Pulse = 1;
Wave = 2;
Fire = 10;
Wheel = 11;
Flower = 12;
Flower2 = 13;
Fan = 14;
Sun = 15;
Thunderstorm = 16;
Cloud = 17;
WeatherClear = 101;
WeatherCloudy = 102;
WeatherFog = 103;
WeatherLightRain = 104;
WeatherRain = 105;
WeatherThunderstorm = 106;
WeatherSnow = 107;
WeatherHail = 108;
WeatherWind = 109;
WeatherTornado = 110;
WeatherHurricane = 111;
WeatherSnowThunderstorm = 112;
}
enum Color {
Black = 0;
DarkGoldenRod = 1;
Darkorange = 2;
Olive = 3;
OrangeRed = 4;
Red = 5;
Maroon = 6;
DarkMagenta = 7;
MediumVioletRed = 8;
Brown = 9;
Indigo = 10;
BlueViolet = 11;
White = 12;
LightSlateBlue = 13;
RoyalBlue = 14;
Blue = 15;
CornflowerBlue = 16;
SkyBlue = 17;
Turquoise = 18;
Aqua = 19;
MediumSpringGreen = 20;
LimeGreen = 21;
DarkGreen = 22;
Lime = 23;
LawnGreen = 24;
Google1 = 25;
Google2 = 26;
Google3 = 27;
Google4 = 28;
Google5 = 29;
Google6 = 30;
Google7 = 31;
Google8 = 32;
Google9 = 33;
Google10 = 34;
Google11 = 35;
Google12 = 36;
Google13 = 37;
Google14 = 38;
Google15 = 39;
Google16 = 40;
Google17 = 41;
Google18 = 42;
Google19 = 43;
Google20 = 44;
Google21 = 45;
Google22 = 46;
Google23 = 47;
Google24 = 48;
Google25 = 49;
Google26 = 50;
Google27 = 51;
Google28 = 52;
Google29 = 53;
}
enum Sound {
NoneSound = 0;
Waves = 1; //Also known as Alarm
Rise = 2; //Also known as Calendar_alert
Charging = 3;
Steps = 4; //Also known as Fitness_alert
Radar = 5; //Also known as General_alert_1
Bells = 6; //Also known as General_alert_2
Bye = 7; //Also known as Goodbye
Hello = 8;
Flowers = 9; //Also known as Ringtone
Circles = 10; //Also known as Taxi
Complete = 11; //Also known as Timer_end
Popcorn = 12; //Also known as Weather_alert
Break = 13;
Opening = 14;
High = 15;
Shine = 16;
Extension = 17;
}
//This is most likely the data structure which got generated by the glance backend
//if you had an api key and sent custom scenes
message CustomScene {
repeated Object object = 1;
//This represents a sequence of things where each thing is an object
//The sequence in which they are contained here doesn't specify when they are displayed though
//instead, their visibility depends on their startTime and lifeTime property
//time values are in frames. Framerate is 50FPS
//area & segment uint32 both refer to the same data structure:
//22 Bit number. At Least 1px
// 5 4 3 2 1
//000000 00 000000 00 000000
//Divided like this
//1 Start Pixel from 0 to 47
//2 Offset from outer edge 0-3 px
//3 Length in Pixels from 0 to 47. Note that there will always be one more.
//4 Height 1-3 px
//Note that Offset + height cannot exceed 4 or the clock will reject the command+
//5 Color ID from Color enum
message Object {
required Method method = 1 [default = Fill];
optional int32 startTime = 2 [default = 0];
required int32 lifeTime = 3 [default = 1];
optional Result result = 4 [default = OK];
optional AreaAnimationData areaAnimation = 5;
optional FillData fill = 6;
repeated TextData text = 7;
optional Sound sound = 8 [default = NoneSound];
optional MovingBarData movingBar = 9;
optional CmdData cmd = 11;
optional GifData gif = 12;
optional WeatherData weather = 13;
message AreaAnimationData {
//This gets layered onto already drawn areas
//you draw some areas using MovingBarData and then apply an effect to the same area with this
//LightFlashData, PulseData and WaveData can add further settings to the effect choosen in type
//They are however optional. If not specified, the default effect parameters will be used
//They will also be ignored if a different type is used
required Type type = 1 [default = Pulse];
repeated int32 area = 2;
optional WaveData wave = 3;
optional PulseData pulse = 4;
optional LightFlashData flashLight = 5;
message LightFlashData {
optional Color color = 1 [default = White];
optional int32 speed = 2 [default = 1];
}
message PulseData {
optional int32 riseTime = 1 [default = 50];
optional int32 fallTime = 2 [default = 50];
}
enum Type {
Pulse = 0;
Wave = 1;
LightFlash = 2;
}
message WaveData {
optional int32 speed = 3 [default = 1];
}
}
message CmdData {
//Yeah good luck figuring that out without access to either messages or the firmware sourcecode
required bytes data = 1;
}
message FillData {
repeated int32 segment = 1;
}
message GifData {
required Animation type = 1 [default = GifStart];
//This only accepts a subset of the animation Enum: 10 - 17
optional int32 segment = 2 [default = 782080];
//As length in pixels, only multiples of 8 (-1, due to there already being at least one px) work.
//Everything else will be rounded down to the previous multiple of 8 by the clock
//Also, the height property doesn't have any effect
optional int32 speed = 3 [default = 3]; //0 to 10
}
enum Method {
Cmd = 1;
Fill = 2;
Sound = 3;
Text = 4;
MovingBar = 5;
AreaAnimation = 7;
Gif = 8;
Weather = 9;
}
message MovingBarData {
required int32 area = 1 [default = 0]; //Pixel 0-47
//The color defined in the area data will be ignored
optional Color frontColor = 2 [default = Blue];
optional Color backColor = 3 [default = White];
optional int32 speed = 4 [default = 0]; //-10 to 10 (Controls direction & speed)
}
enum Result { //TODO: Find out the meaning of these
OK = 0; //Everything drawn will stay (albeit inanimate) after its lifeTime is over
SaveTime = 1;
BackTime = 2;
DelTime = 3;
Expired = 4; //Everything drawn will vanish after its lifeTime is over
End = 5; //The whole scene will end after its lifeTime is over
NewSeq = 6;
}
message WeatherData {
required Condition condition = 1 [default = Snow];
optional Position position = 2 [default = FullScreen];
optional int32 intensity = 3 [default = 5]; //0 to 10
enum Condition {
Snow = 0;
Rain = 1;
Fog = 2;
}
enum Position {
FullScreen = 0;
UpperHalf = 1;
DownHalf = 2;
}
}
}
}
message Notice {
optional Animation type = 1 [default = Pulse];
optional Sound sound = 2 [default = General_alert_1];
optional Color color = 3 [default = Lime];
repeated TextData text = 4;
}
message Segments {
repeated Segment segments = 1;
optional Sound sound = 2 [default = Calendar_alert];
message Segment {
required int32 segment = 1 [default = 0];
repeated TextData text = 2;
}
}
message Settings { //TODO defaults
optional DND dnd = 1;
required bool nightModeEnabled = 2 [default = true];
optional bool permanentDND = 3 [default = false];
optional bool permanentMute = 4 [default = false];
required DateFormat dateFormat = 5 [default = DateDisabled];
optional int32 mgrSilentIntervalMin = 6 [default = 0];
optional int32 mgrSilentIntervalMax = 7 [default = 0];
required bool pointsAlwaysEnabled = 9 [default = false];
required int32 displayBrightness = 10 [default = 0];
required bool timeModeEnable = 11 [default = true];
required bool timeFormat12 = 12 [default = false];
optional int32 mgrUserActivityTimeout = 13 [default = 600];
optional Silent silent = 14;
message DND {
required bool recurring = 1 [default = false];
required int32 fromHour = 2 [default = 0];
required int32 tillHour = 3 [default = 0];
}
enum DateFormat {
DateDisabled = 0;
Date24Jan = 1;
Date24Tue = 2;
DateJan24 = 3;
DateTue24 = 4;
}
message Silent {
required bool recurring = 1;
required int32 fromHour = 2;
required int32 tillHour = 3;
}
}
message TextData {
optional Modificator modificators = 1 [default = Repeat];
required bytes text = 2; //Each byte is an ascii charcode
enum Modificator {
None = 0;
Repeat = 1;
Rapid = 2;
Delay = 3;
}
}
message Timer {
optional int32 countdown = 1 [default = 0]; //Pre-timer countdown.
//Values > 99 will work but with broken text e.g. 100 => ":0" since charcode 58 is ":" and 57 is "9"
repeated Interval intervals = 2;
repeated TextData finalText = 3;
message Interval {
repeated TextData text = 1; //Valid, but not used at all?
required int32 duration = 2 [default = 0]; //Seconds
optional int32 countdown = 3 [default = 0]; //Seconds
}
}
message AlarmData {
optional bool enabled = 2 [default = true];
optional int32 days = 3 [default = 0];
required Time time = 4;
required Sound sound = 5 [default = NoneSound];
repeated TextData text = 6;
message Time {
required int32 hours = 1 [default = 0];
required int32 minutes = 2 [default = 0];
}
}
message Alarms {
repeated AlarmData alarm = 1;
}
message ForecastScene {
required int64 timestamp = 1;
//A unix timestamp
//This has to be localtime so its not _really_ a UTC-based unix timestamp
//due to the fact that everything this clock expects is localtime
optional uint32 doNotChange = 2 [default = 0]; //Absolutely no idea.
required int32 maxColor = 4; //RGB FFFFFF = white
required int32 minColor = 5;
required int32 max = 6;
required int32 min = 7;
//The clock will use these to draw the circle from the values in "values"
required bytes values = 8;
//24 Int16LE. Each representing the forecasted value for one time unit (1h)
//starting at timestamp. Valid for 24h
//The clock will smoothen it automatically, so you can't have quickly alternating data.
//Well.. you can, but it will end up as a star pattern which looks pretty nice actually
required bytes template = 9;
//0x08 will be replaced with the current value from values which is valid at this moment
//It can appear multiple times. All appearances will be replaced
//To write an icon, it has to be prefixed with 0xC2. e.g. 0xC2,0xB0 for °
//Regular ascii codes can be used
//Example template: 0xC2,0x8F,0x08,0xC2,0xB0 = "[Thermometer icon][Current Value]°"
}
message AppointmentsScene {
required int64 timestamp = 1;
//A unix timestamp;
//This probably also has to be localtime so its not _really_ a UTC-based unix timestamp
//due to the fact that everything this clock expects is localtime
required bytes appointmentData = 2;
//I don't really understand the format, sadly. It seems like I'm missing something important
//I've added sample appointment messages to this reposity so if you feel like looking into this further go ahead
//sample_appointments.js
//8 Bytes per Appointment
//Byte 0,1 encode the Starting time
//There seem to be two ways times are expressed:
//Upcoming events are defined by the offset in minutes from the messages timestamp
//Currently already active events use a different format. I don't really see a pattern there
//Since the clock doesn't seem to have a proper understanding of timezones, the offset also includes the offset from UTC
//Time is hard, but this is just weird.
//Upcoming event offsets can be parsed by shifting the value 3 bits to the right and then parsing the first 11 bits
//as an unsigned int. This will return the offset in minutes from the timestamp.
//Example:
//0x95 0xE5 is an appointment which starts at 2359 UTC2. Timestamp is 0200 UTC2
//1001111111100101 in binary
//1011001111111100 shift to the right by 3 bit
//10110011111 11100 split in 11 and 5 bit
//10110011111 = 1439 Minutes = 23h 59m => 2h UTC offset included
//There also seem to be bugs in the backend. See this note excerpt:
//1110110011100100 2100UTC2
//0010100011100101 2200UTC2
//0110010011100101 2300UTC2
//1001111111100101 2359UTC2
//0000000011100000 0000UTC2 (NEXT DAY UTC2)
//0011110011100000 0100UTC2 is this the bug?
//0111011111100000 0159UTC2
//0001100011100110 0200UTC2 uuuuh. This must be a bug
//It flipped back to the beginning of the day until it reached 2AM where it returned to the previous format
//If there are multiple already active events which started in the past, they will all share the offset of the oldest
//I'm unsure if that is a bug in the backend or intended
//Byte 2,3 encode the length + notification time. There can only be one notification time per appointment
//To decode the data, you need to read it as a 16-bit LE int,
//shift it 8 bits to the right and then divide it into a 10 and a 6 bit number
//The 10 bit number is the number is the notification time in minutes e.g. 30m in advance. if there's no notification it's all 1's
//The 6 bit number is the number of started half hour segments. 0 means 1 segment, 1 means 2, 2 means 3, etc.
//Since this is kinda hard to understand let's add an example here:
//0x01 0x03 is a 1h Appointment with 12m notification
//0000000100000011 in binary.
//0000001100000001 shift to the right by 8 bit
//0000001100 000001 split in 10 and 6 bit
//So now we have 12 and 1 which translates to 12m and 2 Segments
//Byte 4,5,6 encode the appointment color as B G R (whyever they've changed the order here)
//Byte 7 encodes the "height" of the appointment if there are multiple appointments at the same time
// => Decimal 3, 6, 9, 12 for 1,2,3 and 4 pixel height
repeated TextData appointmentNames = 3;
required Notify notify = 6;
required Sound sound = 7;
enum Notify {
DISABLED = 0;
ENABLED = 1;
}
}