readerboard 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,465 @@
1
+ """Byte constants for the Alpha sign communications protocol.
2
+
3
+ The bulk of this module is vendored, with thanks, from jonathankoren/readerboard:
4
+ https://github.com/jonathankoren/readerboard/blob/141111ffc94d5f12a83b5072e4b4a7e3cd7e191f/readerboard.py
5
+
6
+ Changes made when it was vendored: a handful of comments that contradicted the
7
+ byte they annotated were corrected, four names whose on/off sense was inverted
8
+ relative to their value were swapped to match, two octal escapes that should
9
+ have been hex were fixed, and the constants this service needs for memory
10
+ configuration and run sequencing were added at the end.
11
+
12
+ Note on provenance: that repository carries no license file, so no permission to
13
+ copy it has actually been granted, whatever the attribution above implies. This
14
+ project is MIT licensed and this module is the one part of it that is not
15
+ cleanly so. Everything here is a byte value dictated by the Alpha Sign
16
+ Communications Protocol rather than an authored expression, and
17
+ docs/protocol-notes.md now cites the protocol document directly, so the table
18
+ can be regenerated from the primary source if the provenance ever needs to be
19
+ clean.
20
+ """
21
+
22
+ # Frame Control Bytes
23
+ WAKEUP = b"\x00\x00\x00\x00\x00\x00" # Wakes up the sign and
24
+ # negotiates communication
25
+ # speed
26
+
27
+ SIGN_ADDRESS_BROADCAST = b"00" # can be anything between "00" and "FF"
28
+ # hexcode, 00 is broadcast
29
+ # Can be wildcarded with ? (e.g. "0?"
30
+ # addresses "01" - "0F")
31
+ SIGN_TYPE_ALL_VERIFY = b"?" # all signs
32
+ # Verify success by displaying
33
+ # "TRANSMISSION OK" or
34
+ # "TRANSMISSION ERROR"
35
+ SIGN_TYPE_SERIAL_CLOCK = b"\"" # serial clock
36
+ SIGN_TYPE_RESPONSE = b"0" # sign response
37
+ SIGN_TYPE_ONE_LINE = b"1" # one line signs
38
+ SIGN_TYPE_TWO_LINE = b"2" # two line signs
39
+ # SIGN_TYPE_ALL = b"?" # all signs (except BetaBrite)
40
+ SIGN_TYPE_430I = b"C" # 430i
41
+ SIGN_TYPE_440I = b"D" # 440i
42
+ SIGN_TYPE_460I = b"E" # 460i
43
+ SIGN_TYPE_790I = b"U" # 790i
44
+ SIGN_TYPE_ALL = b"Z" # all signs
45
+ SIGN_TYPE_BETABRITE = b"^" # readerboard
46
+ SIGN_TYPE_4120C = b"a" # 4120c
47
+ SIGN_TYPE_4160C = b"b" # 4160c
48
+ SIGN_TYPE_4200C = b"c" # 4200c
49
+ SIGN_TYPE_4240C = b"d" # 4240c
50
+ SIGN_TYPE_215 = b"e" # 215
51
+ SIGN_TYPE_215C = b"f" # 215c
52
+ SIGN_TYPE_4120R = b"g" # 4120r
53
+ SIGN_TYPE_4160R = b"h" # 4160r
54
+ SIGN_TYPE_4200R = b"i" # 4200r
55
+ SIGN_TYPE_4240R = b"j" # 4240r
56
+ SIGN_TYPE_300 = b"k" # 300
57
+ SIGN_TYPE_7000 = b"l" # 7000
58
+ SIGN_TYPE_SOLAR_96X16 = b"m" # solar 96x16 matrix
59
+ SIGN_TYPE_SOLAR_128X16 = b"n" # solar 128x16 matrix
60
+ SIGN_TYPE_SOLAR_160X16 = b"o" # solar 160x16 matrix
61
+ SIGN_TYPE_SOLAR_192X16 = b"p" # solar 192x16 matrix
62
+ SIGN_TYPE_SOLAR_PPD = b"q" # ppd
63
+ SIGN_TYPE_DIRECTOR = b"r" # director
64
+ SIGN_TYPE_4080C = b"t" # 4080c
65
+ SIGN_TYPE_2X0C = b"u" # 210c and 220c
66
+ SIGN_TYPE_ALL_CONFIG = b"z" # all signs
67
+ # configure memory for 26 files (A-Z)
68
+ # of 150 characters each, then
69
+ # execute the command
70
+ COMMAND_WRITE_TEXT = b"A" # write TEXT file
71
+ COMMAND_READ_TEXT = b"B" # read TEXT file
72
+ COMMAND_WRITE_SPECIAL = b"E" # write SPECIAL function
73
+ COMMAND_READ_SPECIAL = b"F" # read SPECIAL function
74
+ COMMAND_WRITE_STRING = b"G" # write STRING file
75
+ COMMAND_READ_STRING = b"H" # read STRING file
76
+ COMMAND_WRITE_DOTS = b"I" # write DOTS picture
77
+ COMMAND_READ_DOTS = b"J" # read DOTS picture
78
+ COMMAND_WRITE_ALPHA_DOTS = b"M" # write ALPHAVISION DOTS picture
79
+ COMMAND_READ_ALPHA_DOTS = b"N" # read ALPHAVISION DOTS picture
80
+ COMMAND_ALPHA_BULLETIN = b"O" # write ALPHAVISION BULLETIN
81
+
82
+ FILE_PRIORITY = b"0" # Can be anything in 0x20 to 0x7E
83
+ # Note: 0x30 ("0") is reserved for priorty
84
+ # TEXT messages, and "0" and "?" (0x3F)
85
+ # can not be used to store STRINGS
86
+
87
+ PRINT2_SOH = b"]!" # 2 byte printable SOH
88
+ PRINT2_STX = b"]\"" # 2 byte printable STX
89
+ PRINT2_EOT = b"]$" # 2 byte printable EOT
90
+
91
+ PRINT3_SOH = b"_01" # 3 byte printable SOH
92
+ PRINT3_STX = b"_02" # 3 byte printable STX
93
+ PRINT3_EOT = b"_04" # 3 byte printable EOT
94
+
95
+ CMD_WRITE_TEXT = b"A" # write TEXT file
96
+ CMD_READ_TEXT = b"B" # read TEXT file
97
+
98
+ CMD_SET_TIME = b"\x20"
99
+ CMD_SET_TIME_FORMAT = b"\x27"
100
+
101
+ CMD_SET_DAY_OF_WEEK = b"\x26"
102
+
103
+ TEXT_POS_MIDDLE = b" " # center text vertically
104
+ TEXT_POS_TOP = b"\"" # text begins at top and at most n-1
105
+ # lines
106
+ TEXT_POS_BOTTOM = b"&" # text immediately follows the TOP
107
+ TEXT_POS_FILL = b"0" # center text verically and use all
108
+ # available lines
109
+
110
+ MODE_ROTATE = b"a" # rotate right to left
111
+ MODE_HOLD = b"b" # stationary
112
+ MODE_FLASH = b"c" # stationary and flash
113
+ MODE_ROLLUP = b"e" # push up old message by new message
114
+ MODE_ROLLDOWN = b"f" # push down old message by new message
115
+ MODE_ROLLLEFT = b"g" # push left old message by new message
116
+ MODE_ROLLRIGHT = b"h" # push right old message by new message
117
+ MODE_WIPEUP = b"i" # wipe up over old message with new
118
+ MODE_WIPEDOWN = b"j" # wipe down over old message with new
119
+ MODE_WIPELEFT = b"k" # wipe left over old message with new
120
+ MODE_WIPERIGHT = b"l" # wipe right over old message with new
121
+ MODE_SCROLL = b"m" # new message pushes the bottom line
122
+ # to the top of a 2 line sign
123
+ MODE_AUTO = b"o" # random mode selected automatically
124
+ MODE_ROLLIN = b"p" # new message pushed inward
125
+ MODE_ROLLOUT = b"q" # new message pushed outward
126
+ MODE_WIPEIN = b"r" # new message wiped over old inward
127
+ MODE_WIPEOUT = b"s" # new message wiped over old outward
128
+ MODE_CMPRSROT = b"t" # rotate right to left with text
129
+ # only half as wide
130
+ MODE_TWINKLE = b"n0" # twinkle message
131
+ MODE_SPARKLE = b"n1" # new message sparkles over the old
132
+ MODE_SNOW = b"n2" # snow the new message
133
+ MODE_INTERLOCK = b"n3" # new message interlocks over the old
134
+ MODE_SWITCH = b"n4" # switch "off" the old message char by
135
+ # char. new message switches "on"
136
+ # char by char
137
+ MODE_SLIDE = b"n5" # slide chars right to left one at a
138
+ # time
139
+ MODE_SPRAY = b"n6" # spray message right to left
140
+ MODE_STARBURST = b"n7" # explode new message
141
+ MODE_WELCOME = b"n8" # display a script "Welcome"
142
+ MODE_SLOTMACHINE = b"n9" # display slot machine reels
143
+ MODE_NEWSFLASH = b"nA" # display "Newsflash" animation
144
+ MODE_TRUMPET = b"nB" # display a trumpet animation
145
+ MODE_THANKYOU = b"nS" # display a script "Thank You"
146
+ MODE_NOSMOKING = b"nU" # display "No Smoking" animation
147
+ MODE_DRINKDRIVE = b"nV" # display "Don't Drink and Drive"
148
+ # animation
149
+ MODE_ANIMAL = b"nW" # display a running animal
150
+ MODE_FISH = b"nW" # display fish
151
+ # (BetaBrite alternate for ANIMAL)
152
+ MODE_FIREWORKS = b"nX" # display fireworks animation
153
+ MODE_TURBOCAR = b"nY" # display a car animation
154
+ MODE_BALLOONS = b"nY" # display a balloon animation
155
+ # (BetaBrite alternate for TURBOCAR)
156
+ MODE_CHERRYBOMB = b"nZ" # display a cherry bomb animation
157
+
158
+ BULLETIN_POS_TOP = b"T" # display bulletin at the top
159
+ BULLETIN_POS_BOTTOM = b"B" # display bulletin at the bottom
160
+
161
+ BULLETIN_JUST_LEFT = b"L" # left justify bulletin
162
+ BULLETIN_JUST_RIGHT = b"R" # right justify bulletin
163
+ BULLETIN_JUST_CENTER = b"C" # center bulletin
164
+
165
+ # character table
166
+
167
+ NUL = b"\x00" # NULl
168
+ SOH = b"\x01" # Start Of Header
169
+ STX = b"\x02" # Start Of Text
170
+ ETX = b"\x03" # End of TeXt
171
+ EOT = b"\x04" # End Of Transmission
172
+ DBL_HEIGHT_CHARS_OFF = b"\x05\x30" # double height chars off (default)
173
+ DBL_HEIGHT_CHARS_ON = b"\x05\x31" # double height chars on
174
+ TRUE_DESCENDERS_OFF = b"\x06\x30" # true descenders off (default)
175
+ TRUE_DESCENDERS_ON = b"\x06\x31" # true descenders on
176
+ CHAR_FLASH_ON = b"\x07\x31" # character flash on
177
+ CHAR_FLASH_OFF = b"\x07\x30" # character flash off (default)
178
+ TEMP_CELSIUS = b"\x08\x1c" # current temperature in celsius
179
+ TEMP_FAHRENHEIT = b"\x08\x1d" # current temperature in fahrenheit
180
+ XC_C_TAIL = b"\x08\x20" # capital 'c' with tail
181
+ XC_u_UMLAUT = b"\x08\x21" # lowercase 'u' with umlaut
182
+ XC_e_ACCENT = b"\x08\x22" # lowercase 'e' with grave accent
183
+ XC_a_CIRCUMFLEX = b"\x08\x23" # lowercase 'a' with circumflex
184
+ XC_a_UMLAUT = b"\x08\x24" # lowercase 'a' with umlaut
185
+ XC_a_GRAVE = b"\x08\x25" # lowercase 'a' with accent
186
+ XC_a_CIRCLE = b"\x08\x26" # lowercase 'a' with circle
187
+ XC_c_TAIL = b"\x08\x27" # lowercase 'c' with tail
188
+ XC_e_CIRCUMFLEX = b"\x08\x28" # lowercase 'e' with circumflex
189
+ XC_e_UMLAUT = b"\x08\x29" # lowercase 'e' with umlaut
190
+ XC_e_GRAVE = b"\x08\x2a" # lowercase 'e' with grave accent
191
+ XC_i_UMLAUT = b"\x08\x2b" # lowercase 'i' with umlaut
192
+ XC_i_CIRCUMFLEX = b"\x08\x2c" # lowercase 'i' with circumflex
193
+ XC_i_GRAVE = b"\x08\x2d" # lowercase 'i' with grave accent
194
+ XC_A_UMLAUT = b"\x08\x2e" # capital 'a' with umlaut
195
+ XC_A_CIRCLE = b"\x08\x2f" # capital 'a' with circle
196
+ XC_E_ACCENT = b"\x08\x30" # capital 'e' with accent
197
+ XC_ae_LIGATURE = b"\x08\x31" # lowercase 'ae' ligature
198
+ XC_AE_LIGATURE = b"\x08\x32" # capital 'ae' ligature
199
+ XC_o_CIRCUMFLEX = b"\x08\x33" # lowercase 'o' with circumflex
200
+ XC_o_UMLAUT = b"\x08\x34" # lowercase 'o' with umlaut
201
+ XC_o_GRAVE = b"\x08\x35" # lowercase 'o' with grave accent
202
+ XC_u_CIRCUMFLEX = b"\x08\x36" # lowercase 'u' with circumflex
203
+ XC_u_GRAVE = b"\x08\x37" # lowercase 'u' with grave accent
204
+ XC_y_UMLAUT = b"\x08\x38" # lowercase 'y' with umlaut
205
+ XC_O_UMLAUT = b"\x08\x39" # capital 'o' with umlaut
206
+ XC_U_UMLAUT = b"\x08\x3a" # capital 'u' with umlaut
207
+ XC_CENTS = b"\x08\x3b" # cents sign
208
+ XC_POUNDS = b"\x08\x3c" # british pounds sign
209
+ XC_YEN = b"\x08\x3d" # yen sign
210
+ XC_PERCENT = b"\x08\x3e" # percent sign
211
+ XC_SLANT_F = b"\x08\x3f" # slant lowercase f
212
+ XC_a_ACCENT = b"\x08\x40" # lowercase 'a' with accent
213
+ XC_i_ACCENT = b"\x08\x41" # lowercase 'i' with accent
214
+ XC_o_ACCENT = b"\x08\x42" # lowercase 'o' with accent
215
+ XC_u_ACCENT = b"\x08\x43" # lowercase 'u' with accent
216
+ XC_n_TILDE = b"\x08\x44" # lowercase 'n' with tilde
217
+ XC_N_TILDE = b"\x08\x45" # capital 'n' with tilde
218
+ XC_SUPER_a = b"\x08\x46" # superscript 'a'
219
+ XC_SUPER_o = b"\x08\x47" # superscript 'o'
220
+ XC_INVERT_QUESTION = b"\x08\x48" # inverted question mark
221
+ XC_DEGREES = b"\x08\x49" # degree sign (superscript circle)
222
+ XC_INVERT_EXCLAIM = b"\x08\x4a" # inverted exclaimation mark
223
+ XC_SINGLE_COL_SPACE = b"\x08\x4b" # single column space
224
+ XC_theta = b"\x08\x4c" # lowercase theta
225
+ XC_THETA = b"\x08\x4d" # capital theta
226
+ XC_c_ACCENT = b"\x08\x4e" # lowercase 'c' with accent
227
+ XC_C_ACCENT = b"\x08\x4f" # capital 'c' with accent
228
+ XC_c = b"\x08\x50" # lowercase 'c'
229
+ XC_C = b"\x08\x51" # capital 'c'
230
+ XC_d = b"\x08\x52" # lowercase 'd'
231
+ XC_D = b"\x08\x53" # capital 'd'
232
+ XC_s = b"\x08\x54" # lowercase 's'
233
+ XC_z = b"\x08\x55" # lowercase 'z'
234
+ XC_Z = b"\x08\x56" # capital 'z'
235
+ XC_BETA = b"\x08\x57" # beta
236
+ XC_S = b"\x08\x58" # capital 's'
237
+ XC_BETA2 = b"\x08\x59" # beta
238
+ XC_A_ACCENT = b"\x08\x5a" # capital 'a' with accent
239
+ XC_A_GRAVE = b"\x08\x5b" # capital 'a' with grave accent
240
+ XC_A_2ACCENT = b"\x08\x5c" # capital 'a' with two accents
241
+ XC_a_2ACCENT = b"\x08\x5d" # lowercase ''a' with two accents
242
+ XC_E_CAP = b"\x08\x5e" # capital 'e' with 'cap' accent
243
+ XC_I_ACCENT = b"\x08\x5f" # capital 'i' with accent
244
+ XC_O_TILDE = b"\x08\x60" # capital 'o' with tilde
245
+ XC_o_TILDE = b"\x08\x61" # lowecase 'o' with tilde
246
+ COUNTER_1 = b"\x08\x7a" # current value in counter 1
247
+ COUNTER_2 = b"\x08\x7b" # current value in counter 2
248
+ COUNTER_3 = b"\x08\x7c" # current value in counter 3
249
+ COUNTER_4 = b"\x08\x7d" # current value in counter 4
250
+ COUNTER_5 = b"\x08\x7e" # current value in counter 5
251
+ NO_HOLD_SPEED = b"\x09" # no hold speed (no pause following
252
+ # the mode presentation. not
253
+ # applicable to ROTATE or
254
+ # COMPRESSED_ROTATE modes)
255
+ LF = b"\x0a" # Line Feed
256
+ CURDATE_MMDDYY_SLASH = b"\x0b\x30" # current date MM/DD/YY
257
+ CURDATE_DDMMYY_SLASH = b"\x0b\x31" # current date DD/MM/YY
258
+ CURDATE_MMDDYY_DASH = b"\x0b\x32" # current date MM-DD-YY
259
+ CURDATE_DDMMYY_DASH = b"\x0b\x33" # current date DD-MM-YY
260
+ CURDATE_MMDDYY_DOT = b"\x0b\x34" # current date MM.DD.YY
261
+ CURDATE_DDMMYY_DOT = b"\x0b\x35" # current date DD.MM.YY
262
+ CURDATE_MMDDYY_SPACE = b"\x0b\x36" # current date MM DD YY
263
+ CURDATE_DDMMYY_SPACE = b"\x0b\x37" # current date DD MM YY
264
+ CURDATE_MMMDDYYYY: bytes = b"\x0b\x38" # current date MMM.DD, YYYY
265
+ CURDATE_WEEKDAYY = b"\x0b\x39" # current day of week
266
+ NEW_PAGE = b"\x0c" # start next display page
267
+ CR = b"\x0d" # Carriage Return (new line)
268
+ NEWLINE = CR
269
+ STRING_FILE_INSERT = b"\x10" # insert STRING file (next char is
270
+ # the filename)
271
+ WIDE_CHARS_OFF = b"\x11" # disable wide characters
272
+ WIDE_CHARS_ON = b"\x12" # enables wide characters
273
+ CURTIME_INSERT = b"\x13" # current time
274
+ DOTS_INSERT = b"\x14" # insert DOTS picture (next char is
275
+ # the filename)
276
+ SPEED_1 = b"\x15" # set scroll speed to 1 (slowest)
277
+ SPEED_2 = b"\x16" # set scroll speed to 2
278
+ SPEED_3 = b"\x17" # set scroll speed to 3
279
+ SPEED_4 = b"\x18" # set scroll speed to 4
280
+ SPEED_5 = b"\x19" # set scroll speed to 5 (fastest)
281
+ CHARSET_5_NORMAL = b"\x1a\x31" # set character set 5 high normal
282
+ CHARSET_7_NORMAL = b"\x1a\x33" # set character set 7 high normal
283
+ CHARSET_7_FANCY = b"\x1a\x35" # set character set 7 high fancy
284
+ CHARSET_10_NORMAL = b"\x1a\x36" # set character set 10 high normal
285
+ CHARSET_FULL_FANCY = b"\x1a\x38" # set character set full height fancy
286
+ CHARSET_FULL_NORMAL = b"\x1a\x39" # set character set full height normal
287
+ SOM = b"\x1b" # Start Of Mode
288
+ TEXT_COLOR_RED = b"\x1c\x31" # set text color to red
289
+ TEXT_COLOR_GREEN = b"\x1c\x32" # set text color to green
290
+ TEXT_COLOR_AMBER = b"\x1c\x33" # set text color to amber
291
+ TEXT_COLOR_DIMRED = b"\x1c\x34" # set text color to dim red
292
+ TEXT_COLOR_DIMGREEN = b"\x1c\x35" # set text color to dim green
293
+ TEXT_COLOR_BROWN = b"\x1c\x36" # set text color to brown
294
+ TEXT_COLOR_ORANGE = b"\x1c\x37" # set text color to orange
295
+ TEXT_COLOR_YELLOW = b"\x1c\x38" # set text color to yellow
296
+ TEXT_COLOR_RAINBOW1 = b"\x1c\x39" # set text color to rainbow all chars
297
+ TEXT_COLOR_RAINBOW2 = b"\x1c\x41" # set text color to rainbow indiv chars
298
+ TEXT_COLOR_MIX = b"\x1c\x42" # each char gets a differnt color
299
+ TEXT_COLOR_AUTO = b"\x1c\x43" # cycle through color modes
300
+ CHAR_ATTRIB_WIDE_ON = b"\x1d\x30\x31" # char attrib wide on
301
+ CHAR_ATTRIB_WIDE_OFF = b"\x1d\x30\x30" # char attrib wide off
302
+ CHAR_ATTRIB_DBLW_ON = b"\x1d\x31\x31" # char attrib dbl width on
303
+ CHAR_ATTRIB_DBLW_OFF = b"\x1d\x31\x30" # char attrib dbl width off
304
+ CHAR_ATTRIB_DBLH_ON = b"\x1d\x32\x31" # char attrib dbl height on
305
+ CHAR_ATTRIB_DBLH_OFF = b"\x1d\x32\x30" # char attrib dbl height off
306
+ CHAR_ATTRIB_DESC_ON = b"\x1d\x33\x31" # char attrib true desc on
307
+ CHAR_ATTRIB_DESC_OFF = b"\x1d\x33\x30" # char attrib true desc off
308
+ CHAR_ATTRIB_FIX_ON = b"\x1d\x34\x31" # char attrib fixed width on
309
+ CHAR_ATTRIB_FIX_OFF = b"\x1d\x34\x30" # char attrib fixed width off
310
+ CHAR_ATTRIB_FNCY_ON = b"\x1d\x35\x31" # char attrib fancy on
311
+ CHAR_ATTRIB_FNCY_OFF = b"\x1d\x35\x30" # char attrib fancy off
312
+ FIXED_WIDTH_OFF = b"\x1e\x30" # fixed width chars off (default)
313
+ FIXED_WIDTH_ON = b"\x1e\x31" # fixed width chars on
314
+ ALPHA_DOTS_INSERT = b"\x1f" # insert ALPHAVISION DOTS picture
315
+ # must be followed by:
316
+ # SFFFFFFFFFtttt
317
+ # S = b"C" file is part of a
318
+ # QuickFlick animation.
319
+ # Clear display and uses
320
+ # hold time
321
+ # S = b"L" file is a DOTS picture.
322
+ # if inserted in a
323
+ # TEXT file, then hold
324
+ # time is ignored
325
+ # Fx9 = filename (pad with SPACEEs)
326
+ # tttt = 4 digit ascii hexdump
327
+ # indicating tenths of
328
+ # seconds
329
+ FILE_NAME_CENTS = b"^" # cents sign
330
+ TILDE = b"~" # half a space
331
+ BLOCK_CHAR = b"\x7f" # a square block character
332
+ C_TAIL = b"\x80" # capital 'c' with tail
333
+ u_UMLAUT = b"\x81" # lowercase 'u' with umlaut
334
+ e_ACCENT = b"\x82" # lowercase 'e' with grave accent
335
+ a_CIRCUMFLEX = b"\x83" # lowercase 'a' with circumflex
336
+ a_UMLAUT = b"\x84" # lowercase 'a' with umlaut
337
+ a_GRAVE = b"\x85" # lowercase 'a' with accent
338
+ a_CIRCLE = b"\x86" # lowercase 'a' with circle
339
+ c_TAIL = b"\x87" # lowercase 'c' with tail
340
+ e_CIRCUMFLEX = b"\x88" # lowercase 'e' with circumflex
341
+ e_UMLAUT = b"\x89" # lowercase 'e' with umlaut
342
+ e_GRAVE = b"\x8a" # lowercase 'e' with grave accent
343
+ i_UMLAUT = b"\x8b" # lowercase 'i' with umlaut
344
+ i_CIRCUMFLEX = b"\x8c" # lowercase 'i' with circumflex
345
+ i_GRAVE = b"\x8d" # lowercase 'i' with grave accent
346
+ A_UMLAUT = b"\x8e" # capital 'a' with umlaut
347
+ A_CIRCLE = b"\x8f" # capital 'a' with circle
348
+ E_ACCENT = b"\x90" # capital 'e' with accent
349
+ ae_LIGATURE = b"\x91" # lowercase 'ae' ligature
350
+ AE_LIGATURE = b"\x92" # capital 'ae' ligature
351
+ o_CIRCUMFLEX = b"\x93" # lowercase 'o' with circumflex
352
+ o_UMLAUT = b"\x94" # lowercase 'o' with umlaut
353
+ o_GRAVE = b"\x95" # lowercase 'o' with grave accent
354
+ u_CIRCUMFLEX = b"\x96" # lowercase 'u' with circumflex
355
+ u_GRAVE = b"\x97" # lowercase 'u' with grave accent
356
+ y_UMLAUT = b"\x98" # lowercase 'y' with umlaut
357
+ O_UMLAUT = b"\x99" # capital 'o' with umlaut
358
+ U_UMLAUT = b"\x9a" # capital 'u' with umlaut
359
+ CENTS = b"\x9b" # cents sign
360
+ POUNDS = b"\x9c" # british pounds sign
361
+ YEN = b"\x9d" # yen sign
362
+ PERCENT = b"\x9e" # percent sign
363
+ SLANT_F = b"\x9f" # slant lowercase f
364
+ a_ACCENT = b"\xa0" # lowercase 'a' with accent
365
+ i_ACCENT = b"\xa1" # lowercase 'i' with accent
366
+ o_ACCENT = b"\xa2" # lowercase 'o' with accent
367
+ u_ACCENT = b"\xa3" # lowercase 'u' with accent
368
+ n_TILDE = b"\xa4" # lowercase 'n' with tilde
369
+ N_TILDE = b"\xa5" # capital 'n' with tilde
370
+ SUPER_a = b"\xa6" # superscript 'a'
371
+ SUPER_o = b"\xa7" # superscript 'o'
372
+ INVERT_QUESTION = b"\xa8" # inverted question mark
373
+ DEGREES = b"\xa9" # degree sign (superscript circle)
374
+ INVERT_EXCLAIM = b"\xaa" # inverted exclaimation mark
375
+ SINGLE_COL_SPACE = b"\xab" # single column space
376
+ theta = b"\xac" # lowercase theta
377
+ THETA = b"\xad" # capital theta
378
+ c_ACCENT = b"\xae" # lowercase 'c' with accent
379
+ C_ACCENT = b"\xaf" # capital 'c' with accent
380
+ CHAR_c = b"\xb0" # lowercase 'c'
381
+ CHAR_C = b"\xb1" # capital 'c'
382
+ CHAR_d = b"\xb2" # lowercase 'd'
383
+ CHAR_D = b"\xb3" # capital 'd'
384
+ CHAR_s = b"\xb4" # lowercase 's'
385
+ CHAR_z = b"\xb5" # lowercase 'z'
386
+ CHAR_Z = b"\xb6" # capital 'z'
387
+ BETA = b"\xb7" # beta
388
+ CHAR_S = b"\xb8" # capital 's'
389
+ BETA2 = b"\xb9" # beta
390
+ A_ACCENT = b"\xba" # capital 'a' with accent
391
+ A_GRAVE = b"\xbb" # capital 'a' with grave accent
392
+ A_2ACCENT = b"\xbc" # capital 'a' with two accents
393
+ a_2ACCENT = b"\xbd" # lowercase ''a' with two accents
394
+ E_ACCENT_HAT = b"\xbe" # capital 'e' with accent hat
395
+ I_ACCENT = b"\xbf" # capital 'i' with accent
396
+ O_TILDE = b"\xc0" # capital 'o' with tilde
397
+ o_TILDE = b"\xc1" # lowecase 'o' with tilde
398
+
399
+ # ===========================================================================
400
+ # Constants added for this service, sourced from the Alpha Sign Communications
401
+ # Protocol (Adaptive Micro Systems, form 9708-8061F). See docs/protocol-notes.md
402
+ # for where each of these came from and what is still unconfirmed on hardware.
403
+ # ===========================================================================
404
+
405
+ # Special function labels. Each follows COMMAND_WRITE_SPECIAL in the payload.
406
+ SF_SET_MEMORY_CONFIG = b"$" # allocate files; erases everything already stored
407
+ SF_SET_RUN_SEQUENCE = b"." # choose which TEXT files play, and in what order
408
+
409
+ # File types used in a memory configuration entry.
410
+ FILE_TYPE_TEXT = b"A"
411
+ FILE_TYPE_STRING = b"B"
412
+ FILE_TYPE_DOTS = b"D"
413
+
414
+ # Whether the sign's own infrared keyboard may change a file.
415
+ FILE_LOCKED = b"L"
416
+ FILE_UNLOCKED = b"U"
417
+
418
+ # Run sequence modes.
419
+ RUN_SEQ_BY_TIME = b"T" # honour each file's own start and stop time (default)
420
+ RUN_SEQ_IGNORE_TIME = b"S" # play in the given order whatever the file's times
421
+ RUN_SEQ_DELETE_AT_STOP = b"D" # delete a file when its stop time arrives
422
+
423
+ # The start and stop time pair in a TEXT file's memory configuration entry.
424
+ # A start time of "FF" means always, and the protocol says the stop time is
425
+ # ignored entirely when the start is Always, so a file allocated with this pair
426
+ # is eligible to play whenever the run sequence names it.
427
+ TEXT_SCHEDULE_ALWAYS = b"FFFF"
428
+
429
+ # Bytes of directory overhead the sign charges for each configured file, on top
430
+ # of the file's own size, when working out whether a pool fits in the memory
431
+ # pool.
432
+ FILE_OVERHEAD_BYTES = 11
433
+
434
+ # The priority TEXT file always exists, is a fixed 125 bytes, and sits outside
435
+ # the memory pool, so it is never part of a memory configuration.
436
+ PRIORITY_FILE_CAPACITY = 125
437
+
438
+ # The labels available for the service's own rotating messages. The priority
439
+ # file "0" is deliberately absent.
440
+ TEXT_FILE_LABELS = tuple(bytes([code]) for code in range(ord("A"), ord("Z") + 1))
441
+
442
+ # Special function labels used with COMMAND_READ_SPECIAL to ask the sign what it
443
+ # currently holds. These exist so that divergence can be detected rather than
444
+ # assumed; see docs/protocol-notes.md for what is still unproven about reads
445
+ # over the Ethernet adapter.
446
+ SF_MEMORY_POOL_SIZE = b"#" # returns total and unused pool bytes
447
+ SF_RUN_TIME_TABLE = b")" # returns priority status and per-file start/stop times
448
+
449
+ # Protocol generation. A BetaBrite Classic speaks Alpha 1.0 and EZ KEY II only,
450
+ # so nothing in this package may use a command the protocol document marks as
451
+ # Alpha 2.0 or 3.0. That rules out the "E$$$$" clear-memory-and-flash command,
452
+ # programmable sounds, and the ACK/NAK response feature.
453
+ PROTOCOL_GENERATION = "1.0"
454
+
455
+ # File labels the layout planner must not hand out. "0" is the priority file,
456
+ # and "1" through "5" become reserved target files if the sign's counter feature
457
+ # is ever switched on.
458
+ RESERVED_FILE_LABELS = (b"0", b"1", b"2", b"3", b"4", b"5")
459
+
460
+ # Timing the protocol document states, for reference when tuning
461
+ # inter_packet_delay. The inter-byte timeout for a standard packet is one
462
+ # second, and a nested packet needs at least 100 ms after its STX. This service
463
+ # sends no nested packets.
464
+ INTER_BYTE_TIMEOUT_SECONDS = 1.0
465
+ NESTED_PACKET_DELAY_SECONDS = 0.1