timex_datalink_client 0.7.0 → 0.8.0
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.
- checksums.yaml +4 -4
- data/lib/timex_datalink_client/helpers/four_byte_formatter.rb +29 -0
- data/lib/timex_datalink_client/protocol_7/eeprom/activity.rb +94 -0
- data/lib/timex_datalink_client/protocol_7/eeprom/calendar/event.rb +33 -0
- data/lib/timex_datalink_client/protocol_7/eeprom/calendar.rb +91 -0
- data/lib/timex_datalink_client/protocol_7/eeprom/games.rb +124 -0
- data/lib/timex_datalink_client/protocol_7/eeprom/phone_number.rb +79 -0
- data/lib/timex_datalink_client/protocol_7/eeprom/speech.rb +228 -0
- data/lib/timex_datalink_client/protocol_7/eeprom.rb +76 -0
- data/lib/timex_datalink_client/protocol_7/end.rb +20 -0
- data/lib/timex_datalink_client/protocol_7/phrase_builder.rb +70 -0
- data/lib/timex_datalink_client/protocol_7/start.rb +20 -0
- data/lib/timex_datalink_client/protocol_7/sync.rb +40 -0
- data/lib/timex_datalink_client/version.rb +1 -1
- data/lib/timex_datalink_client.rb +18 -5
- metadata +29 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93fe636dc699046ea5c14683b355f8c65bb162fb18ee91b3ffe27f4a72633808
|
4
|
+
data.tar.gz: d9476317e2cce78a77247c277e77208969f6e8fa13059a2e0f7452f502f9b112
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 313b6bc8ea78a28ee55534ff28648a6544a8aa7dcf1abd731461fc7b9c21ba3711d441de603d7f538666541d5fce4ca0d6206449a2b8cee6cf5d56a263f8691a
|
7
|
+
data.tar.gz: df31c376348f69fd05ba4c0de720e443074f68d63788601610021e0328598af3cfa8a3f85789336d20e80aac90be5ac32526bc6872d208afdd2c6965582f1617
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TimexDatalinkClient
|
4
|
+
class Helpers
|
5
|
+
module FourByteFormatter
|
6
|
+
BYTE_NULL = 0x000
|
7
|
+
BYTE_TERMINATOR_ENDF = 0x3fe
|
8
|
+
BYTE_TERMINATOR_ENDR = 0x3ff
|
9
|
+
|
10
|
+
def four_byte_format_for(byte_arrays)
|
11
|
+
byte_arrays.each_with_index.flat_map do |bytes, bytes_index|
|
12
|
+
last_index = bytes_index == byte_arrays.count - 1
|
13
|
+
terminator = last_index ? BYTE_TERMINATOR_ENDR : BYTE_TERMINATOR_ENDF
|
14
|
+
|
15
|
+
bytes_with_terminator = bytes + [terminator]
|
16
|
+
|
17
|
+
bytes_with_terminator.each_slice(4).flat_map do |bytes_slice|
|
18
|
+
bytes_slice.fill(BYTE_NULL, bytes_slice.count, 4 - bytes_slice.count)
|
19
|
+
|
20
|
+
packet_lsbs_sum = bytes_slice.each_with_index.sum { |byte, index| byte / 256 << 6 - index * 2 }
|
21
|
+
packet_msbs = bytes_slice.map { |byte| byte % 256 }
|
22
|
+
|
23
|
+
[packet_lsbs_sum] + packet_msbs
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "timex_datalink_client/helpers/four_byte_formatter"
|
4
|
+
|
5
|
+
class TimexDatalinkClient
|
6
|
+
class Protocol7
|
7
|
+
class Eeprom
|
8
|
+
class Activity
|
9
|
+
include Helpers::FourByteFormatter
|
10
|
+
|
11
|
+
METADATA_BYTES_BASE = 6
|
12
|
+
METADATA_BYTES_SIZE = 5
|
13
|
+
|
14
|
+
PACKETS_TERMINATOR = 0x04
|
15
|
+
|
16
|
+
# Compile data for all activities.
|
17
|
+
#
|
18
|
+
# @param activities [Array<Activity>] Activities to compile data for.
|
19
|
+
# @return [Array] Compiled data of all activities.
|
20
|
+
def self.packets(activities)
|
21
|
+
header(activities) + metadata_and_messages(activities) + [PACKETS_TERMINATOR]
|
22
|
+
end
|
23
|
+
|
24
|
+
private_class_method def self.header(activities)
|
25
|
+
[
|
26
|
+
random_speech(activities),
|
27
|
+
0,
|
28
|
+
0,
|
29
|
+
0,
|
30
|
+
activities.count,
|
31
|
+
0
|
32
|
+
]
|
33
|
+
end
|
34
|
+
|
35
|
+
private_class_method def self.random_speech(activities)
|
36
|
+
activities.each_with_index.sum do |activity, activity_index|
|
37
|
+
activity.random_speech ? 1 << activity_index : 0
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private_class_method def self.metadata_and_messages(activities)
|
42
|
+
metadata = activities.each_with_index.map do |activity, activity_index|
|
43
|
+
activity.metadata_packet(activities.count + activity_index)
|
44
|
+
end
|
45
|
+
|
46
|
+
messages = activities.map { |activity| activity.messages_packet }
|
47
|
+
|
48
|
+
(metadata + messages).flatten
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_accessor :time, :messages, :random_speech
|
52
|
+
|
53
|
+
# Create an Activity instance.
|
54
|
+
#
|
55
|
+
# @param time [::Time] Time of activity.
|
56
|
+
# @param messages [Array<Array<Integer>>] Messages for activity.
|
57
|
+
# @param random_speech [Boolean] If activity should have random speech.
|
58
|
+
# @return [Activity] Activity instance.
|
59
|
+
def initialize(time:, messages:, random_speech:)
|
60
|
+
@time = time
|
61
|
+
@messages = messages
|
62
|
+
@random_speech = random_speech
|
63
|
+
end
|
64
|
+
|
65
|
+
# Compile a metadata packet for an activity.
|
66
|
+
#
|
67
|
+
# @param activity_index [Integer] Activity index.
|
68
|
+
# @return [Array<Integer>] Array of integers that represent bytes.
|
69
|
+
def metadata_packet(activity_index)
|
70
|
+
[
|
71
|
+
time.hour,
|
72
|
+
time.min,
|
73
|
+
messages.count,
|
74
|
+
metadata_bytes(activity_index),
|
75
|
+
0
|
76
|
+
].flatten
|
77
|
+
end
|
78
|
+
|
79
|
+
# Compile a message packet for an activity.
|
80
|
+
#
|
81
|
+
# @return [Array<Integer>] Array of integers that represent bytes.
|
82
|
+
def messages_packet
|
83
|
+
four_byte_format_for(messages)
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def metadata_bytes(activity_index)
|
89
|
+
METADATA_BYTES_BASE + METADATA_BYTES_SIZE * activity_index
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TimexDatalinkClient
|
4
|
+
class Protocol7
|
5
|
+
class Eeprom
|
6
|
+
class Calendar
|
7
|
+
class Event
|
8
|
+
FIVE_MINUTES_SECONDS = 300
|
9
|
+
|
10
|
+
attr_accessor :time, :phrase
|
11
|
+
|
12
|
+
# Create an Event instance.
|
13
|
+
#
|
14
|
+
# @param time [::Time] Time of event.
|
15
|
+
# @param phrase [Array<Integer>] Phrase for event.
|
16
|
+
# @return [Event] Event instance.
|
17
|
+
def initialize(time:, phrase:)
|
18
|
+
@time = time
|
19
|
+
@phrase = phrase
|
20
|
+
end
|
21
|
+
|
22
|
+
def time_formatted(device_time)
|
23
|
+
device_time_midnight = Time.new(device_time.year, device_time.month, device_time.day)
|
24
|
+
seconds = (time - device_time_midnight).to_i
|
25
|
+
five_minutes = seconds / FIVE_MINUTES_SECONDS
|
26
|
+
|
27
|
+
five_minutes.divmod(256).reverse
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "timex_datalink_client/helpers/four_byte_formatter"
|
4
|
+
|
5
|
+
class TimexDatalinkClient
|
6
|
+
class Protocol7
|
7
|
+
class Eeprom
|
8
|
+
class Calendar
|
9
|
+
include Helpers::FourByteFormatter
|
10
|
+
|
11
|
+
DAY_START_TIME = Time.new(2000)
|
12
|
+
DAY_SECONDS = 86400
|
13
|
+
|
14
|
+
EVENTS_BYTES_BASE = 2
|
15
|
+
EVENTS_BYTES_EVENT = 4
|
16
|
+
EVENTS_BYTES_PHRASE_PACKET = 5
|
17
|
+
|
18
|
+
PACKETS_TERMINATOR = 0x01
|
19
|
+
|
20
|
+
attr_accessor :time, :events
|
21
|
+
|
22
|
+
# Create a Calendar instance.
|
23
|
+
#
|
24
|
+
# @param time [::Time] Time to set device to.
|
25
|
+
# @param events [Array<Event>] Event instances to add to the calendar.
|
26
|
+
# @return [Calendar] Calendar instance.
|
27
|
+
def initialize(time:, events: [])
|
28
|
+
@time = time
|
29
|
+
@events = events
|
30
|
+
end
|
31
|
+
|
32
|
+
# Compile data for calendar.
|
33
|
+
#
|
34
|
+
# @return [Array<Integer>] Compiled data for calendar.
|
35
|
+
def packet
|
36
|
+
[
|
37
|
+
events_count,
|
38
|
+
event_packets,
|
39
|
+
event_phrases,
|
40
|
+
time.hour,
|
41
|
+
time.min,
|
42
|
+
days_from_2000,
|
43
|
+
time_formatted,
|
44
|
+
PACKETS_TERMINATOR
|
45
|
+
].flatten
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def events_count
|
51
|
+
events.count.divmod(256).reverse
|
52
|
+
end
|
53
|
+
|
54
|
+
def event_packets
|
55
|
+
event_bytes = EVENTS_BYTES_BASE
|
56
|
+
event_bytes += EVENTS_BYTES_EVENT * events.count
|
57
|
+
|
58
|
+
[].tap do |event_packets|
|
59
|
+
events.each_with_index do |event, event_index|
|
60
|
+
event_bytes_formatted = event_bytes.divmod(256).reverse
|
61
|
+
event_time_formatted = event.time_formatted(time)
|
62
|
+
|
63
|
+
event_packets << [event_time_formatted, event_bytes_formatted]
|
64
|
+
|
65
|
+
event_bytes += EVENTS_BYTES_PHRASE_PACKET * (1 + event.phrase.length / 4)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def event_phrases
|
71
|
+
phrases = events.map(&:phrase)
|
72
|
+
|
73
|
+
four_byte_format_for(phrases)
|
74
|
+
end
|
75
|
+
|
76
|
+
def days_from_2000
|
77
|
+
since_start_time_seconds = time - DAY_START_TIME
|
78
|
+
since_start_time_days = since_start_time_seconds.to_i / DAY_SECONDS
|
79
|
+
|
80
|
+
since_start_time_days.divmod(256).reverse
|
81
|
+
end
|
82
|
+
|
83
|
+
def time_formatted
|
84
|
+
five_mintes = (time.hour * 60 + time.min) / 5
|
85
|
+
|
86
|
+
five_mintes.divmod(256).reverse
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "timex_datalink_client/helpers/four_byte_formatter"
|
4
|
+
|
5
|
+
class TimexDatalinkClient
|
6
|
+
class Protocol7
|
7
|
+
class Eeprom
|
8
|
+
class Games
|
9
|
+
include Helpers::FourByteFormatter
|
10
|
+
|
11
|
+
COUNTDOWN_TIMER_SECONDS_DEFAULT = 60
|
12
|
+
|
13
|
+
COUNTDOWN_TIMER_SOUND_DEFAULT = 0x062
|
14
|
+
MUSIC_TIME_KEEPER_SOUND_DEFAULT = 0x062
|
15
|
+
|
16
|
+
PACKETS_TERMINATOR = 0x02
|
17
|
+
|
18
|
+
attr_accessor :memory_game_enabled, :fortune_teller_enabled, :countdown_timer_enabled, :countdown_timer_seconds,
|
19
|
+
:countdown_timer_sound, :mind_reader_enabled, :music_time_keeper_enabled, :music_time_keeper_sound,
|
20
|
+
:morse_code_practice_enabled, :treasure_hunter_enabled, :rhythm_rhyme_buster_enabled, :stop_watch_enabled,
|
21
|
+
:red_light_green_light_enabled
|
22
|
+
|
23
|
+
# Create a Games instance.
|
24
|
+
#
|
25
|
+
# @param memory_game_enabled [Boolean] Toggle memory game.
|
26
|
+
# @param fortune_teller_enabled [Boolean] Toggle fortune teller.
|
27
|
+
# @param countdown_timer_enabled [Boolean] Toggle countdown timer.
|
28
|
+
# @param countdown_timer_seconds [Integer] Duration for countdown timer in seconds.
|
29
|
+
# @param countdown_timer_sound [Integer] Sound for countdown timer.
|
30
|
+
# @param mind_reader_enabled [Boolean] Toggle mind reader.
|
31
|
+
# @param music_time_keeper_enabled [Boolean] Toggle music time keeper.
|
32
|
+
# @param music_time_keeper_sound [Integer] Sound for music time keeper.
|
33
|
+
# @param morse_code_practice_enabled [Boolean] Toggle Morse code practice.
|
34
|
+
# @param treasure_hunter_enabled [Boolean] Toggle treasure hunter.
|
35
|
+
# @param rhythm_rhyme_buster_enabled [Boolean] Toggle rhythm & rhyme buster.
|
36
|
+
# @param stop_watch_enabled [Boolean] Toggle stop watch.
|
37
|
+
# @param red_light_green_light_enabled [Boolean] Toggle red light, green light.
|
38
|
+
# @return [Games] Games instance.
|
39
|
+
def initialize(
|
40
|
+
memory_game_enabled: false,
|
41
|
+
fortune_teller_enabled: false,
|
42
|
+
countdown_timer_enabled: false,
|
43
|
+
countdown_timer_seconds: COUNTDOWN_TIMER_SECONDS_DEFAULT,
|
44
|
+
countdown_timer_sound: COUNTDOWN_TIMER_SOUND_DEFAULT,
|
45
|
+
mind_reader_enabled: false,
|
46
|
+
music_time_keeper_enabled: false,
|
47
|
+
music_time_keeper_sound: MUSIC_TIME_KEEPER_SOUND_DEFAULT,
|
48
|
+
morse_code_practice_enabled: false,
|
49
|
+
treasure_hunter_enabled: false,
|
50
|
+
rhythm_rhyme_buster_enabled: false,
|
51
|
+
stop_watch_enabled: false,
|
52
|
+
red_light_green_light_enabled: false
|
53
|
+
)
|
54
|
+
@memory_game_enabled = memory_game_enabled
|
55
|
+
@fortune_teller_enabled = fortune_teller_enabled
|
56
|
+
@countdown_timer_enabled = countdown_timer_enabled
|
57
|
+
@countdown_timer_seconds = countdown_timer_seconds
|
58
|
+
@countdown_timer_sound = countdown_timer_sound
|
59
|
+
@mind_reader_enabled = mind_reader_enabled
|
60
|
+
@music_time_keeper_enabled = music_time_keeper_enabled
|
61
|
+
@music_time_keeper_sound = music_time_keeper_sound
|
62
|
+
@morse_code_practice_enabled = morse_code_practice_enabled
|
63
|
+
@treasure_hunter_enabled = treasure_hunter_enabled
|
64
|
+
@rhythm_rhyme_buster_enabled = rhythm_rhyme_buster_enabled
|
65
|
+
@stop_watch_enabled = stop_watch_enabled
|
66
|
+
@red_light_green_light_enabled = red_light_green_light_enabled
|
67
|
+
end
|
68
|
+
|
69
|
+
# Compile data for games.
|
70
|
+
#
|
71
|
+
# @return [Array<Integer>] Compiled data for games.
|
72
|
+
def packet
|
73
|
+
[
|
74
|
+
enabled_games,
|
75
|
+
countdown_timer_time,
|
76
|
+
sounds,
|
77
|
+
PACKETS_TERMINATOR
|
78
|
+
].flatten
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def enabled_games
|
84
|
+
bitmask = games.each_with_index.sum do |game, game_index|
|
85
|
+
game ? 1 << game_index : 0
|
86
|
+
end
|
87
|
+
|
88
|
+
bitmask.divmod(256).reverse
|
89
|
+
end
|
90
|
+
|
91
|
+
def countdown_timer_time
|
92
|
+
(countdown_timer_seconds * 10).divmod(256).reverse
|
93
|
+
end
|
94
|
+
|
95
|
+
def sounds
|
96
|
+
sounds_extra_packet = four_byte_format_for(
|
97
|
+
[
|
98
|
+
[music_time_keeper_sound],
|
99
|
+
[countdown_timer_sound],
|
100
|
+
[]
|
101
|
+
]
|
102
|
+
)
|
103
|
+
|
104
|
+
sounds_extra_packet.first(10)
|
105
|
+
end
|
106
|
+
|
107
|
+
def games
|
108
|
+
[
|
109
|
+
memory_game_enabled,
|
110
|
+
fortune_teller_enabled,
|
111
|
+
countdown_timer_enabled,
|
112
|
+
mind_reader_enabled,
|
113
|
+
music_time_keeper_enabled,
|
114
|
+
morse_code_practice_enabled,
|
115
|
+
treasure_hunter_enabled,
|
116
|
+
rhythm_rhyme_buster_enabled,
|
117
|
+
stop_watch_enabled,
|
118
|
+
red_light_green_light_enabled
|
119
|
+
]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "timex_datalink_client/helpers/four_byte_formatter"
|
4
|
+
|
5
|
+
class TimexDatalinkClient
|
6
|
+
class Protocol7
|
7
|
+
class Eeprom
|
8
|
+
class PhoneNumber
|
9
|
+
include Helpers::FourByteFormatter
|
10
|
+
|
11
|
+
PHONE_NUMBER_DIGITS_MAP = {
|
12
|
+
"0" => 0x001,
|
13
|
+
"1" => 0x002,
|
14
|
+
"2" => 0x003,
|
15
|
+
"3" => 0x004,
|
16
|
+
"4" => 0x005,
|
17
|
+
"5" => 0x006,
|
18
|
+
"6" => 0x007,
|
19
|
+
"7" => 0x008,
|
20
|
+
"8" => 0x009,
|
21
|
+
"9" => 0x00a
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
PACKETS_TERMINATOR = 0x03
|
25
|
+
|
26
|
+
# Compile data for all phone numbers.
|
27
|
+
#
|
28
|
+
# @param phone_numbers [Array<PhoneNumber>] Phone numbers to compile data for.
|
29
|
+
# @return [Array] Compiled data of all phone numbers.
|
30
|
+
def self.packets(phone_numbers)
|
31
|
+
header(phone_numbers) + names_and_numbers(phone_numbers) + [PACKETS_TERMINATOR]
|
32
|
+
end
|
33
|
+
|
34
|
+
private_class_method def self.header(phone_numbers)
|
35
|
+
[
|
36
|
+
phone_numbers.count,
|
37
|
+
0
|
38
|
+
]
|
39
|
+
end
|
40
|
+
|
41
|
+
private_class_method def self.names_and_numbers(phone_numbers)
|
42
|
+
return [] if phone_numbers.empty?
|
43
|
+
|
44
|
+
names_and_numbers = phone_numbers.flat_map(&:name_and_number)
|
45
|
+
|
46
|
+
phone_numbers.first.four_byte_format_for(names_and_numbers)
|
47
|
+
end
|
48
|
+
|
49
|
+
attr_accessor :name, :number
|
50
|
+
|
51
|
+
# Create a PhoneNumber instance.
|
52
|
+
#
|
53
|
+
# @param name [Array<Integer>] Name associated to phone number.
|
54
|
+
# @param number [String] Phone number text.
|
55
|
+
# @return [PhoneNumber] PhoneNumber instance.
|
56
|
+
def initialize(name: [], number:)
|
57
|
+
@name = name
|
58
|
+
@number = number
|
59
|
+
end
|
60
|
+
|
61
|
+
# Compile an unformatted name and phone number.
|
62
|
+
#
|
63
|
+
# @return [Array<Integer>] Array of integers that represent bytes.
|
64
|
+
def name_and_number
|
65
|
+
[
|
66
|
+
name,
|
67
|
+
number_characters
|
68
|
+
]
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def number_characters
|
74
|
+
number.each_char.map { |digit| PHONE_NUMBER_DIGITS_MAP[digit] }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,228 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "timex_datalink_client/helpers/four_byte_formatter"
|
4
|
+
|
5
|
+
class TimexDatalinkClient
|
6
|
+
class Protocol7
|
7
|
+
class Eeprom
|
8
|
+
class Speech
|
9
|
+
include Helpers::FourByteFormatter
|
10
|
+
|
11
|
+
NICKNAME_LENGTH_WITHOUT_DEVICE = 10
|
12
|
+
NICKNAME_LENGTH_WITH_DEVICE = 14
|
13
|
+
|
14
|
+
NICKNAME_SUFFIXES = [
|
15
|
+
[0x353, 0x3fd, 0x04d, 0x003, 0x28d],
|
16
|
+
[0x353, 0x3fd, 0x04d, 0x003, 0x27b],
|
17
|
+
[0x3fb, 0x363, 0x039, 0x03c],
|
18
|
+
[0x3fb, 0x361, 0x039, 0x03c, 0x194, 0x3fd, 0x04b, 0x003, 0x144, 0x327],
|
19
|
+
[0x3fb, 0x1ae, 0x030, 0x329, 0x03c, 0x3fb, 0x030, 0x320, 0x03c, 0x039, 0x124],
|
20
|
+
[0x3fb, 0x353, 0x003, 0x1ae, 0x2e6, 0x18e],
|
21
|
+
[0x361, 0x039, 0x03c, 0x144, 0x3fd, 0x04b],
|
22
|
+
[0x3fb, 0x361, 0x33e],
|
23
|
+
[0x1cb, 0x039, 0x03c, 0x144, 0x3fd, 0x04b],
|
24
|
+
[0x039, 0x35a, 0x1ae, 0x3fd, 0x04b, 0x18e, 0x381],
|
25
|
+
[0x039, 0x35a, 0x31c, 0x381],
|
26
|
+
[0x353, 0x3fd, 0x04d, 0x003, 0x28d, 0x07b, 0x094],
|
27
|
+
[0x1e0, 0x1ab],
|
28
|
+
[0x253, 0x3fd, 0x04d, 0x182],
|
29
|
+
[0x353, 0x3fd, 0x04d, 0x003, 0x357, 0x10c, 0x3fd, 0x04d]
|
30
|
+
]
|
31
|
+
|
32
|
+
HEADER_VALUE_1_BASE = 0x0b
|
33
|
+
HEADER_VALUE_1_DEVICE_NICK = 4
|
34
|
+
|
35
|
+
HEADER_VALUE_2_BASE = 0x00
|
36
|
+
HEADER_VALUE_2_PHRASES = 26
|
37
|
+
HEADER_VALUE_2_DEVICE_NICK = 8
|
38
|
+
|
39
|
+
HEADER_VALUE_3_BASE = 0x1a
|
40
|
+
HEADER_VALUE_3_PHRASES = 2
|
41
|
+
HEADER_VALUE_3_DEVICE_NICK = 8
|
42
|
+
|
43
|
+
HEADER_VALUE_4_DEVICE_BASE = 8
|
44
|
+
HEADER_VALUE_4_PHRASE = 2
|
45
|
+
|
46
|
+
HEADER_VALUE_4_BASES = [0x1a, 0x1a, 0x1a, 0x1f, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a]
|
47
|
+
HEADER_VALUE_4_DEVICE_MULTIPLIERS = [5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 5, 5, 5]
|
48
|
+
|
49
|
+
HEADER_VALUE_4_DEVICE_INDEXES = [
|
50
|
+
[0],
|
51
|
+
[0],
|
52
|
+
[0],
|
53
|
+
[0],
|
54
|
+
[0],
|
55
|
+
[0],
|
56
|
+
[0],
|
57
|
+
[0],
|
58
|
+
[0],
|
59
|
+
[0],
|
60
|
+
[0],
|
61
|
+
[0, 1, 11],
|
62
|
+
[0, 1, 11, 12],
|
63
|
+
[0, 1, 11, 12, 13]
|
64
|
+
]
|
65
|
+
|
66
|
+
HEADER_VALUE_4_USER_MULTIPLIERS = [0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
|
67
|
+
|
68
|
+
HEADER_VALUE_4_USER_INDEXES = [
|
69
|
+
[],
|
70
|
+
[],
|
71
|
+
[2],
|
72
|
+
[2, 5],
|
73
|
+
[3, 4, 10],
|
74
|
+
[3, 4, 5, 10],
|
75
|
+
[3, 4, 5, 6, 10],
|
76
|
+
[3, 4, 5, 6, 7, 10],
|
77
|
+
[3, 4, 5, 6, 7, 8, 10],
|
78
|
+
[3, 4, 5, 6, 7, 8, 9, 10],
|
79
|
+
[2, 3, 4, 5, 6, 7, 8, 9, 10],
|
80
|
+
[2, 3, 4, 5, 6, 7, 8, 9, 10],
|
81
|
+
[2, 3, 4, 5, 6, 7, 8, 9, 10],
|
82
|
+
[2, 3, 4, 5, 6, 7, 8, 9, 10]
|
83
|
+
]
|
84
|
+
|
85
|
+
HEADER_VALUE_5_BASE = 0x8d
|
86
|
+
|
87
|
+
HEADER_VALUE_5_DEVICE_BASE = -107
|
88
|
+
HEADER_VALUE_5_DEVICE_INDEXES = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
|
89
|
+
HEADER_VALUE_5_DEVICE_MULTIPLIER = 5
|
90
|
+
|
91
|
+
HEADER_VALUE_5_USER_BASE = 0
|
92
|
+
HEADER_VALUE_5_USER_INDEXES = [14]
|
93
|
+
HEADER_VALUE_5_USER_MULTIPLIER = 5
|
94
|
+
|
95
|
+
HEADER_VALUE_5_PHRASE = 2
|
96
|
+
HEADER_VALUE_5_PHRASE_PACKET = 5
|
97
|
+
|
98
|
+
PACKETS_TERMINATOR = 0x05
|
99
|
+
|
100
|
+
attr_accessor :phrases, :device_nickname, :user_nickname
|
101
|
+
|
102
|
+
# Create a Speech instance.
|
103
|
+
#
|
104
|
+
# @param phrases [Array<Array<Integer>>] Two-dimensional array of phrases.
|
105
|
+
# @param device_nickname [Array<Integer>] Device nickname.
|
106
|
+
# @param user_nickname [Array<Integer>] User nickname.
|
107
|
+
# @return [Speech] Speech instance.
|
108
|
+
def initialize(phrases: [], device_nickname: [], user_nickname: [])
|
109
|
+
@phrases = phrases
|
110
|
+
@device_nickname = device_nickname
|
111
|
+
@user_nickname = user_nickname
|
112
|
+
end
|
113
|
+
|
114
|
+
# Compile data for nicknames and phrases.
|
115
|
+
#
|
116
|
+
# @return [Array<Integer>] Compiled data of all nicknames and phrases.
|
117
|
+
def packet
|
118
|
+
header + nickname_bytes + formatted_phrases + [PACKETS_TERMINATOR]
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
def header
|
124
|
+
all_values = [header_value_1, header_value_2, header_value_3] + header_values_4 + header_values_5
|
125
|
+
|
126
|
+
all_values.flat_map { |value| value.divmod(256).reverse }
|
127
|
+
end
|
128
|
+
|
129
|
+
def header_value_1
|
130
|
+
value_1 = HEADER_VALUE_1_BASE + phrases.count
|
131
|
+
value_1 += HEADER_VALUE_1_DEVICE_NICK if device_nickname.any?
|
132
|
+
|
133
|
+
value_1
|
134
|
+
end
|
135
|
+
|
136
|
+
def header_value_2
|
137
|
+
value_2 = HEADER_VALUE_2_BASE
|
138
|
+
value_2 += HEADER_VALUE_2_PHRASES if phrases.any?
|
139
|
+
value_2 += HEADER_VALUE_2_DEVICE_NICK if phrases.any? && device_nickname.any?
|
140
|
+
|
141
|
+
value_2
|
142
|
+
end
|
143
|
+
|
144
|
+
def header_value_3
|
145
|
+
value_3 = HEADER_VALUE_3_BASE
|
146
|
+
value_3 += HEADER_VALUE_3_DEVICE_NICK if device_nickname.any?
|
147
|
+
value_3 += HEADER_VALUE_3_PHRASES * phrases.count
|
148
|
+
|
149
|
+
value_3
|
150
|
+
end
|
151
|
+
|
152
|
+
def header_values_4
|
153
|
+
value_4_length = device_nickname.any? ? NICKNAME_LENGTH_WITH_DEVICE : NICKNAME_LENGTH_WITHOUT_DEVICE
|
154
|
+
|
155
|
+
value_4_length.times.flat_map do |value_4_index|
|
156
|
+
device_value = HEADER_VALUE_4_DEVICE_INDEXES[value_4_index].sum { |device_index| packet_lengths[device_index] }
|
157
|
+
device_value *= HEADER_VALUE_4_DEVICE_MULTIPLIERS[value_4_index]
|
158
|
+
|
159
|
+
user_value = HEADER_VALUE_4_USER_INDEXES[value_4_index].sum { |device_index| packet_lengths[device_index] }
|
160
|
+
user_value *= HEADER_VALUE_4_USER_MULTIPLIERS[value_4_index]
|
161
|
+
|
162
|
+
value = device_value + user_value
|
163
|
+
value += HEADER_VALUE_4_BASES[value_4_index]
|
164
|
+
value += HEADER_VALUE_4_PHRASE * phrases.count
|
165
|
+
value += HEADER_VALUE_4_DEVICE_BASE if device_nickname.any?
|
166
|
+
|
167
|
+
value
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def header_values_5
|
172
|
+
phrases.each_index.flat_map do |phrase_index|
|
173
|
+
value = HEADER_VALUE_5_BASE
|
174
|
+
|
175
|
+
if device_nickname.any?
|
176
|
+
device_value = HEADER_VALUE_5_DEVICE_INDEXES.sum { |device_index| packet_lengths[device_index] }
|
177
|
+
device_value *= HEADER_VALUE_5_DEVICE_MULTIPLIER
|
178
|
+
device_value += HEADER_VALUE_5_DEVICE_BASE
|
179
|
+
|
180
|
+
value += device_value
|
181
|
+
end
|
182
|
+
|
183
|
+
if user_nickname.any?
|
184
|
+
user_value = HEADER_VALUE_5_USER_INDEXES.sum { |device_index| packet_lengths[device_index] }
|
185
|
+
user_value *= HEADER_VALUE_5_USER_MULTIPLIER
|
186
|
+
user_value += HEADER_VALUE_5_USER_BASE
|
187
|
+
|
188
|
+
value += user_value
|
189
|
+
end
|
190
|
+
|
191
|
+
value += HEADER_VALUE_5_PHRASE * phrases.count
|
192
|
+
value += HEADER_VALUE_5_PHRASE_PACKET * phrases.first(phrase_index).sum { |phrase| 1 + phrase.length / 4 }
|
193
|
+
|
194
|
+
value
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def nickname_bytes
|
199
|
+
four_byte_format_for(nicknames_with_suffixes)
|
200
|
+
end
|
201
|
+
|
202
|
+
def packet_lengths
|
203
|
+
nicknames_with_suffixes.map { |nickname| 1 + nickname.length / 4 }
|
204
|
+
end
|
205
|
+
|
206
|
+
def nickname_format
|
207
|
+
format = [device_nickname] * 2
|
208
|
+
format += [user_nickname] * 9
|
209
|
+
format += [device_nickname] * 4 if device_nickname.any?
|
210
|
+
|
211
|
+
format
|
212
|
+
end
|
213
|
+
|
214
|
+
def nicknames_with_suffixes
|
215
|
+
nickname_format.each_with_index.map do |nickname, nickname_index|
|
216
|
+
nickname + NICKNAME_SUFFIXES[nickname_index]
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def formatted_phrases
|
221
|
+
return [] if phrases.empty?
|
222
|
+
|
223
|
+
four_byte_format_for(phrases)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "timex_datalink_client/helpers/cpacket_paginator"
|
4
|
+
require "timex_datalink_client/helpers/crc_packets_wrapper"
|
5
|
+
|
6
|
+
class TimexDatalinkClient
|
7
|
+
class Protocol7
|
8
|
+
class Eeprom
|
9
|
+
include Helpers::CpacketPaginator
|
10
|
+
prepend Helpers::CrcPacketsWrapper
|
11
|
+
|
12
|
+
# FIXME use arrays for array models
|
13
|
+
# FIXME: check Array<Integer> yardoc around places
|
14
|
+
|
15
|
+
CPACKET_SECT = [0x90, 0x05]
|
16
|
+
CPACKET_DATA = [0x91, 0x05]
|
17
|
+
CPACKET_END = [0x92, 0x05]
|
18
|
+
|
19
|
+
CPACKET_SECT_WELCOME = [
|
20
|
+
0x44, 0x53, 0x49, 0x20, 0x54, 0x6f, 0x79, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x2e,
|
21
|
+
0x2e, 0x2e, 0x65, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00
|
22
|
+
]
|
23
|
+
|
24
|
+
CPACKET_DATA_LENGTH = 32
|
25
|
+
|
26
|
+
attr_accessor :activities, :games, :calendar, :phone_numbers, :speech
|
27
|
+
|
28
|
+
# Create an Eeprom instance.
|
29
|
+
#
|
30
|
+
# @param activities [Array<Activity>, nil] Activities to be added to EEPROM data.
|
31
|
+
# @param games [Games, nil] Games to be added to EEPROM data.
|
32
|
+
# @param calendar [Array<Calendar>, nil] Calendar to be added to EEPROM data.
|
33
|
+
# @param phone_numbers [Array<PhoneNumber>, nil] Phone numbers to be added to EEPROM data.
|
34
|
+
# @param speech [Speech, nil] Speech to be added to EEPROM data.
|
35
|
+
# @return [Eeprom] Eeprom instance.
|
36
|
+
def initialize(activities: nil, games: nil, calendar: nil, phone_numbers: nil, speech: nil)
|
37
|
+
@activities = activities
|
38
|
+
@games = games
|
39
|
+
@calendar = calendar
|
40
|
+
@phone_numbers = phone_numbers
|
41
|
+
@speech = speech
|
42
|
+
end
|
43
|
+
|
44
|
+
# Compile packets for EEPROM data.
|
45
|
+
#
|
46
|
+
# @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
|
47
|
+
def packets
|
48
|
+
[header] + payloads + [CPACKET_END]
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def header
|
54
|
+
[
|
55
|
+
CPACKET_SECT,
|
56
|
+
payloads.length,
|
57
|
+
CPACKET_SECT_WELCOME
|
58
|
+
].flatten
|
59
|
+
end
|
60
|
+
|
61
|
+
def payloads
|
62
|
+
paginate_cpackets(header: CPACKET_DATA, length: CPACKET_DATA_LENGTH, cpackets: all_packets)
|
63
|
+
end
|
64
|
+
|
65
|
+
def all_packets
|
66
|
+
[].tap do |packets|
|
67
|
+
packets.concat(Activity.packets(activities)) if activities
|
68
|
+
packets.concat(games.packet) if games
|
69
|
+
packets.concat(calendar.packet) if calendar
|
70
|
+
packets.concat(PhoneNumber.packets(phone_numbers)) if phone_numbers
|
71
|
+
packets.concat(speech.packet) if speech
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "timex_datalink_client/helpers/crc_packets_wrapper"
|
4
|
+
|
5
|
+
class TimexDatalinkClient
|
6
|
+
class Protocol7
|
7
|
+
class End
|
8
|
+
prepend Helpers::CrcPacketsWrapper
|
9
|
+
|
10
|
+
CPACKET_SKIP = [0x21]
|
11
|
+
|
12
|
+
# Compile packets for data end command.
|
13
|
+
#
|
14
|
+
# @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
|
15
|
+
def packets
|
16
|
+
[CPACKET_SKIP]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mdb"
|
4
|
+
|
5
|
+
class TimexDatalinkClient
|
6
|
+
class Protocol7
|
7
|
+
class PhraseBuilder
|
8
|
+
class WordNotFound < StandardError; end
|
9
|
+
|
10
|
+
attr_accessor :database
|
11
|
+
|
12
|
+
# Create a PhraseBuilder instance.
|
13
|
+
#
|
14
|
+
# @param database [String] Database file to compile phrase data from.
|
15
|
+
# @return [PhraseBuilder] PhraseBuilder instance.
|
16
|
+
def initialize(database:)
|
17
|
+
@database = database
|
18
|
+
end
|
19
|
+
|
20
|
+
# Compile vocabulary IDs for protocol 7 phrases.
|
21
|
+
#
|
22
|
+
# @param words [Array<String>] Array of words.
|
23
|
+
# @raise [WordNotFound] Word not found in protocol 7 database.
|
24
|
+
# @return [Array<Integer>] Array of protocol 7 vocabulary IDs.
|
25
|
+
def vocab_ids_for(*words)
|
26
|
+
words.flat_map do |word|
|
27
|
+
vocab = vocab_for_word(word)
|
28
|
+
|
29
|
+
raise(WordNotFound, "#{word} is not a valid word!") unless vocab
|
30
|
+
|
31
|
+
vocab_links = vocab_links_for_vocab(vocab)
|
32
|
+
|
33
|
+
vocab_links.map do |vocab_link|
|
34
|
+
linked_vocab = vocab_for_vocab_link(vocab_link)
|
35
|
+
|
36
|
+
linked_vocab[:"PC Index"].to_i
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def mdb
|
44
|
+
@mdb ||= Mdb.open(database)
|
45
|
+
end
|
46
|
+
|
47
|
+
def vocab_table
|
48
|
+
@vocab_table ||= mdb["Vocab"]
|
49
|
+
end
|
50
|
+
|
51
|
+
def vocab_links_table
|
52
|
+
@vocab_links_table ||= mdb["Vocab Links"]
|
53
|
+
end
|
54
|
+
|
55
|
+
def vocab_for_word(word)
|
56
|
+
vocab_table.detect { |vocab| vocab[:Label].casecmp?(word) }
|
57
|
+
end
|
58
|
+
|
59
|
+
def vocab_links_for_vocab(vocab)
|
60
|
+
links = vocab_links_table.select { |vocab_link| vocab_link[:"PC Index"] == vocab[:"PC Index"] }
|
61
|
+
|
62
|
+
links.sort_by { |link| link[:Sequence].to_i }
|
63
|
+
end
|
64
|
+
|
65
|
+
def vocab_for_vocab_link(vocab_link)
|
66
|
+
vocab_table.detect { |vocab| vocab[:"PC Index"] == vocab_link[:"eBrain Index"] }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "timex_datalink_client/helpers/crc_packets_wrapper"
|
4
|
+
|
5
|
+
class TimexDatalinkClient
|
6
|
+
class Protocol7
|
7
|
+
class Start
|
8
|
+
prepend Helpers::CrcPacketsWrapper
|
9
|
+
|
10
|
+
CPACKET_START = [0x20, 0x00, 0x00, 0x07]
|
11
|
+
|
12
|
+
# Compile packets for data start command.
|
13
|
+
#
|
14
|
+
# @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
|
15
|
+
def packets
|
16
|
+
[CPACKET_START]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TimexDatalinkClient
|
4
|
+
class Protocol7
|
5
|
+
class Sync
|
6
|
+
PING_BYTE = [0x78]
|
7
|
+
SYNC_1_BYTE = [0x55]
|
8
|
+
SYNC_2_BYTE = [0xaa]
|
9
|
+
|
10
|
+
SYNC_2_LENGTH = 5
|
11
|
+
|
12
|
+
attr_accessor :length
|
13
|
+
|
14
|
+
# Create a Sync instance.
|
15
|
+
#
|
16
|
+
# @param length [Integer] Number of 0x55 sync bytes to use.
|
17
|
+
# @return [Sync] Sync instance.
|
18
|
+
def initialize(length: 300)
|
19
|
+
@length = length
|
20
|
+
end
|
21
|
+
|
22
|
+
# Compile packets for syncronization data.
|
23
|
+
#
|
24
|
+
# @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
|
25
|
+
def packets
|
26
|
+
[PING_BYTE + render_sync_1 + render_sync_2]
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def render_sync_1
|
32
|
+
SYNC_1_BYTE * length
|
33
|
+
end
|
34
|
+
|
35
|
+
def render_sync_2
|
36
|
+
SYNC_2_BYTE * SYNC_2_LENGTH
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -43,6 +43,18 @@ require "timex_datalink_client/protocol_4/sync"
|
|
43
43
|
require "timex_datalink_client/protocol_4/time"
|
44
44
|
require "timex_datalink_client/protocol_4/wrist_app"
|
45
45
|
|
46
|
+
require "timex_datalink_client/protocol_7/eeprom"
|
47
|
+
require "timex_datalink_client/protocol_7/eeprom/activity"
|
48
|
+
require "timex_datalink_client/protocol_7/eeprom/calendar"
|
49
|
+
require "timex_datalink_client/protocol_7/eeprom/calendar/event"
|
50
|
+
require "timex_datalink_client/protocol_7/eeprom/games"
|
51
|
+
require "timex_datalink_client/protocol_7/eeprom/phone_number"
|
52
|
+
require "timex_datalink_client/protocol_7/eeprom/speech"
|
53
|
+
require "timex_datalink_client/protocol_7/end"
|
54
|
+
require "timex_datalink_client/protocol_7/phrase_builder"
|
55
|
+
require "timex_datalink_client/protocol_7/start"
|
56
|
+
require "timex_datalink_client/protocol_7/sync"
|
57
|
+
|
46
58
|
require "timex_datalink_client/protocol_9/alarm"
|
47
59
|
require "timex_datalink_client/protocol_9/eeprom"
|
48
60
|
require "timex_datalink_client/protocol_9/eeprom/chrono"
|
@@ -60,19 +72,20 @@ class TimexDatalinkClient
|
|
60
72
|
|
61
73
|
# Create a TimexDatalinkClient instance.
|
62
74
|
#
|
63
|
-
# @param serial_device [String] Path to serial device.
|
75
|
+
# @param serial_device [String, nil] Path to serial device.
|
64
76
|
# @param models [Array<Protocol1::Sync, Protocol1::Start, Protocol1::Time, Protocol1::TimeName, Protocol1::Alarm,
|
65
77
|
# Protocol1::Eeprom, Protocol1::End, Protocol3::Sync, Protocol3::Start, Protocol3::Time, Protocol3::Alarm,
|
66
78
|
# Protocol3::Eeprom, Protocol3::SoundTheme, Protocol3::SoundOptions, Protocol3::WristApp, Protocol3::End,
|
67
79
|
# Protocol4::Sync, Protocol4::Start, Protocol4::Time, Protocol4::Alarm, Protocol4::Eeprom, Protocol4::SoundTheme,
|
68
|
-
# Protocol4::SoundOptions, Protocol4::WristApp, Protocol4::End,
|
69
|
-
#
|
70
|
-
# Protocol9::End>] Models to compile
|
80
|
+
# Protocol4::SoundOptions, Protocol4::WristApp, Protocol4::End, Protocol7::Sync, Protocol7::Start,
|
81
|
+
# Protocol7::Eeprom, Protocol7::End, Protocol9::Sync, Protocol9::Start, Protocol9::Time, Protocol9::TimeName,
|
82
|
+
# Protocol9::Timer, Protocol9::Alarm, Protocol9::Eeprom, Protocol9::SoundOptions, Protocol9::End>] Models to compile
|
83
|
+
# data for.
|
71
84
|
# @param byte_sleep [Integer, nil] Time to sleep after sending byte.
|
72
85
|
# @param packet_sleep [Integer, nil] Time to sleep after sending packet of bytes.
|
73
86
|
# @param verbose [Boolean] Write verbose output to console.
|
74
87
|
# @return [TimexDatalinkClient] TimexDatalinkClient instance.
|
75
|
-
def initialize(serial_device
|
88
|
+
def initialize(serial_device: nil, models: [], byte_sleep: nil, packet_sleep: nil, verbose: false)
|
76
89
|
@serial_device = serial_device
|
77
90
|
@models = models
|
78
91
|
@byte_sleep = byte_sleep
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timex_datalink_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maxwell Pray
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: crc
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.6.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mdb
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.5.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.5.0
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rspec
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -90,6 +104,7 @@ files:
|
|
90
104
|
- lib/timex_datalink_client/helpers/char_encoders.rb
|
91
105
|
- lib/timex_datalink_client/helpers/cpacket_paginator.rb
|
92
106
|
- lib/timex_datalink_client/helpers/crc_packets_wrapper.rb
|
107
|
+
- lib/timex_datalink_client/helpers/four_byte_formatter.rb
|
93
108
|
- lib/timex_datalink_client/helpers/length_packet_wrapper.rb
|
94
109
|
- lib/timex_datalink_client/notebook_adapter.rb
|
95
110
|
- lib/timex_datalink_client/protocol_1/alarm.rb
|
@@ -129,6 +144,17 @@ files:
|
|
129
144
|
- lib/timex_datalink_client/protocol_4/sync.rb
|
130
145
|
- lib/timex_datalink_client/protocol_4/time.rb
|
131
146
|
- lib/timex_datalink_client/protocol_4/wrist_app.rb
|
147
|
+
- lib/timex_datalink_client/protocol_7/eeprom.rb
|
148
|
+
- lib/timex_datalink_client/protocol_7/eeprom/activity.rb
|
149
|
+
- lib/timex_datalink_client/protocol_7/eeprom/calendar.rb
|
150
|
+
- lib/timex_datalink_client/protocol_7/eeprom/calendar/event.rb
|
151
|
+
- lib/timex_datalink_client/protocol_7/eeprom/games.rb
|
152
|
+
- lib/timex_datalink_client/protocol_7/eeprom/phone_number.rb
|
153
|
+
- lib/timex_datalink_client/protocol_7/eeprom/speech.rb
|
154
|
+
- lib/timex_datalink_client/protocol_7/end.rb
|
155
|
+
- lib/timex_datalink_client/protocol_7/phrase_builder.rb
|
156
|
+
- lib/timex_datalink_client/protocol_7/start.rb
|
157
|
+
- lib/timex_datalink_client/protocol_7/sync.rb
|
132
158
|
- lib/timex_datalink_client/protocol_9/alarm.rb
|
133
159
|
- lib/timex_datalink_client/protocol_9/eeprom.rb
|
134
160
|
- lib/timex_datalink_client/protocol_9/eeprom/chrono.rb
|
@@ -141,7 +167,7 @@ files:
|
|
141
167
|
- lib/timex_datalink_client/protocol_9/time_name.rb
|
142
168
|
- lib/timex_datalink_client/protocol_9/timer.rb
|
143
169
|
- lib/timex_datalink_client/version.rb
|
144
|
-
homepage: https://github.com/synthead/timex_datalink_client/tree/v0.
|
170
|
+
homepage: https://github.com/synthead/timex_datalink_client/tree/v0.8.0
|
145
171
|
licenses:
|
146
172
|
- MIT
|
147
173
|
metadata: {}
|