timex_datalink_client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b30f06f6a23f4312ee7167089c7e0704ef5f799b4c3f7a2be36d57b445074f46
4
+ data.tar.gz: f2a82191c18efa5a7c51b422ff6b8c0ad30589890eac654a47507ece261ec445
5
+ SHA512:
6
+ metadata.gz: 78ddeedea22f0d2476b934d84a0751e67c63c2528cdab1a077cf5a4ddde7310e716da02be053d7abfee90e17bd9110ea92d75f84df510b7acc79e81c814598c3
7
+ data.tar.gz: 9a4974b2abd86722dacc1d4badd802fcc3b7ac84fab8d27d2bc6f39c31269d0c188635cf4e89e55b189aa86c9290a5148e26925e9c9f15337503d539df01c838
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "timex_datalink_client/helpers/char_encoders"
4
+ require "timex_datalink_client/helpers/crc_packets_wrapper"
5
+
6
+ class TimexDatalinkClient
7
+ class Alarm
8
+ include Helpers::CharEncoders
9
+ prepend Helpers::CrcPacketsWrapper
10
+
11
+ CPACKET_ALARM = [0x50]
12
+
13
+ MESSAGE_LENGTH = 8
14
+
15
+ attr_accessor :number, :audible, :time, :message
16
+
17
+ def initialize(number:, audible:, time:, message:)
18
+ @number = number
19
+ @audible = audible
20
+ @time = time
21
+ @message = message
22
+ end
23
+
24
+ def packets
25
+ [
26
+ [
27
+ CPACKET_ALARM,
28
+ number,
29
+ time.hour,
30
+ time.min,
31
+ 0,
32
+ 0,
33
+ message_characters,
34
+ audible
35
+ ].flatten
36
+ ]
37
+ end
38
+
39
+ private
40
+
41
+ def message_characters
42
+ message_padded = message.ljust(MESSAGE_LENGTH)
43
+
44
+ chars_for(message_padded)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "timex_datalink_client/helpers/char_encoders"
4
+ require "timex_datalink_client/helpers/length_packet_wrapper"
5
+
6
+ class TimexDatalinkClient
7
+ class Eeprom
8
+ class Anniversary
9
+ include Helpers::CharEncoders
10
+ prepend Helpers::LengthPacketWrapper
11
+
12
+ attr_accessor :time, :anniversary
13
+
14
+ def initialize(time:, anniversary:)
15
+ @time = time
16
+ @anniversary = anniversary
17
+ end
18
+
19
+ def packet
20
+ [
21
+ time.month,
22
+ time.day,
23
+ anniversary_characters
24
+ ].flatten
25
+ end
26
+
27
+ private
28
+
29
+ def anniversary_characters
30
+ eeprom_chars_for(anniversary)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "timex_datalink_client/helpers/char_encoders"
4
+ require "timex_datalink_client/helpers/length_packet_wrapper"
5
+
6
+ class TimexDatalinkClient
7
+ class Eeprom
8
+ class Appointment
9
+ include Helpers::CharEncoders
10
+ prepend Helpers::LengthPacketWrapper
11
+
12
+ attr_accessor :time, :message
13
+
14
+ def initialize(time:, message:)
15
+ @time = time
16
+ @message = message
17
+ end
18
+
19
+ def packet
20
+ [
21
+ time.month,
22
+ time.day,
23
+ time_15m,
24
+ message_characters
25
+ ].flatten
26
+ end
27
+
28
+ private
29
+
30
+ def time_15m
31
+ time.hour * 4 + time.min / 15
32
+ end
33
+
34
+ def message_characters
35
+ eeprom_chars_for(message)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "timex_datalink_client/helpers/char_encoders"
4
+ require "timex_datalink_client/helpers/length_packet_wrapper"
5
+
6
+ class TimexDatalinkClient
7
+ class Eeprom
8
+ class List
9
+ include Helpers::CharEncoders
10
+ prepend Helpers::LengthPacketWrapper
11
+
12
+ attr_accessor :list_entry, :priority
13
+
14
+ def initialize(list_entry:, priority:)
15
+ @list_entry = list_entry
16
+ @priority = priority
17
+ end
18
+
19
+ def packet
20
+ [
21
+ priority,
22
+ list_entry_characters
23
+ ].flatten
24
+ end
25
+
26
+ private
27
+
28
+ def list_entry_characters
29
+ eeprom_chars_for(list_entry)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "timex_datalink_client/helpers/char_encoders"
4
+ require "timex_datalink_client/helpers/length_packet_wrapper"
5
+
6
+ class TimexDatalinkClient
7
+ class Eeprom
8
+ class PhoneNumber
9
+ include Helpers::CharEncoders
10
+ prepend Helpers::LengthPacketWrapper
11
+
12
+ PHONE_DIGITS = 12
13
+
14
+ attr_accessor :name, :number, :type
15
+
16
+ def initialize(name:, number:, type: " ")
17
+ @name = name
18
+ @number = number
19
+ @type = type
20
+ end
21
+
22
+ def packet
23
+ [
24
+ number_with_type_characters,
25
+ name_characters,
26
+ ].flatten
27
+ end
28
+
29
+ private
30
+
31
+ def number_with_type_truncated
32
+ number_with_type = "#{number} #{type}"
33
+ padded_number_with_type = number_with_type.rjust(PHONE_DIGITS)
34
+
35
+ padded_number_with_type[0..PHONE_DIGITS - 1]
36
+ end
37
+
38
+ def number_with_type_characters
39
+ phone_chars_for(number_with_type_truncated)
40
+ end
41
+
42
+ def name_characters
43
+ eeprom_chars_for(name)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,80 @@
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 Eeprom
8
+ include Helpers::CpacketPaginator
9
+ prepend Helpers::CrcPacketsWrapper
10
+
11
+ CPACKET_CLEAR = [0x93, 0x01]
12
+ CPACKET_SECT = [0x90, 0x01]
13
+ CPACKET_DATA = [0x91, 0x01]
14
+ CPACKET_END = [0x92, 0x01]
15
+
16
+ START_ADDRESS = 0x0236
17
+ APPOINTMENT_NO_NOTIFICATION = 0xff
18
+
19
+ attr_accessor :appointments, :anniversaries, :phone_numbers, :lists, :appointment_notification
20
+
21
+ def initialize(appointments: [], anniversaries: [], phone_numbers: [], lists: [], appointment_notification: APPOINTMENT_NO_NOTIFICATION)
22
+ @appointments = appointments
23
+ @anniversaries = anniversaries
24
+ @phone_numbers = phone_numbers
25
+ @lists = lists
26
+ @appointment_notification = appointment_notification
27
+ end
28
+
29
+ def packets
30
+ [CPACKET_CLEAR, header] + payloads + [CPACKET_END]
31
+ end
32
+
33
+ private
34
+
35
+ def header
36
+ [
37
+ CPACKET_SECT,
38
+ payloads.length,
39
+ items_addresses,
40
+ items_lengths,
41
+ earliest_appointment_year,
42
+ appointment_notification
43
+ ].flatten
44
+ end
45
+
46
+ def payloads
47
+ paginate_cpackets(header: CPACKET_DATA, cpackets: all_packets)
48
+ end
49
+
50
+ def all_items
51
+ [appointments, lists, phone_numbers, anniversaries]
52
+ end
53
+
54
+ def all_packets
55
+ all_items.flatten.map(&:packet).flatten
56
+ end
57
+
58
+ def items_addresses
59
+ address = START_ADDRESS
60
+
61
+ all_items.each_with_object([]) do |items, addresses|
62
+ addresses.concat(address.divmod(256))
63
+
64
+ address += items.sum { |item| item.packet.length }
65
+ end
66
+ end
67
+
68
+ def items_lengths
69
+ all_items.map(&:length)
70
+ end
71
+
72
+ def earliest_appointment_year
73
+ earliest_appointment = appointments.min_by(&:time)
74
+
75
+ return 0 unless earliest_appointment
76
+
77
+ earliest_appointment.time.year % 100
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "timex_datalink_client/helpers/crc_packets_wrapper"
4
+
5
+ class TimexDatalinkClient
6
+ class End
7
+ prepend Helpers::CrcPacketsWrapper
8
+
9
+ CPACKET_SKIP = [0x21]
10
+
11
+ def packets
12
+ [CPACKET_SKIP]
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TimexDatalinkClient
4
+ class Helpers
5
+ module CharEncoders
6
+ CHARS = "0123456789abcdefghijklmnopqrstuvwxyz !\"#$%&'()*+,-./:\\;=@?ABCDEF"
7
+ EEPROM_TERMINATOR = 0x3f
8
+
9
+ PHONE_CHARS = "0123456789cfhpw "
10
+
11
+ def chars_for(string_chars, char_map: CHARS)
12
+ string_chars.each_char.map do |string_char|
13
+ char_map.index(string_char)
14
+ end
15
+ end
16
+
17
+ def eeprom_chars_for(string_chars)
18
+ chars = chars_for(string_chars).append(EEPROM_TERMINATOR)
19
+
20
+ packed_int = chars.each_with_index.sum do |char, index|
21
+ char << (6 * index)
22
+ end
23
+
24
+ packed_int.digits(256)
25
+ end
26
+
27
+ def phone_chars_for(string_chars)
28
+ chars = chars_for(string_chars, char_map: PHONE_CHARS)
29
+
30
+ packed_int = chars.each_with_index.sum do |char, index|
31
+ char << (4 * index)
32
+ end
33
+
34
+ packed_int.digits(256)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TimexDatalinkClient
4
+ class Helpers
5
+ module CpacketPaginator
6
+ ITEMS_PER_PACKET = 32
7
+
8
+ def paginate_cpackets(header:, cpackets:)
9
+ paginated_cpackets = cpackets.each_slice(ITEMS_PER_PACKET)
10
+
11
+ paginated_cpackets.map.with_index(1) do |paginated_cpacket, index|
12
+ header + [index] + paginated_cpacket
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "crc"
4
+
5
+ class TimexDatalinkClient
6
+ class Helpers
7
+ module CrcPacketsWrapper
8
+ def packets
9
+ super.map do |packet|
10
+ crc_header(packet) + packet + crc_footer(packet)
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def crc_header(packet)
17
+ [packet.length + 3]
18
+ end
19
+
20
+ def crc_footer(packet)
21
+ crc_check = (crc_header(packet) + packet).pack("C*")
22
+ crc = CRC.crc16_arc(crc_check)
23
+
24
+ crc.divmod(256)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TimexDatalinkClient
4
+ class Helpers
5
+ module LengthPacketWrapper
6
+ def packet
7
+ [super.length + 1] + super
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubyserial"
4
+
5
+ class TimexDatalinkClient
6
+ class NotebookAdapter
7
+ BYTE_SLEEP = 0.025
8
+ PACKET_SLEEP = 0.25
9
+
10
+ attr_accessor :serial_device
11
+
12
+ def initialize(serial_device)
13
+ @serial_device = serial_device
14
+ end
15
+
16
+ def write(packets)
17
+ packets.each do |packet|
18
+ packet.each do |byte|
19
+ serial.write(byte.chr)
20
+
21
+ sleep(BYTE_SLEEP)
22
+ end
23
+
24
+ sleep(PACKET_SLEEP)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def serial
31
+ @serial ||= Serial.new(serial_device)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "timex_datalink_client/helpers/crc_packets_wrapper"
4
+
5
+ class TimexDatalinkClient
6
+ class SoundOptions
7
+ prepend Helpers::CrcPacketsWrapper
8
+
9
+ CPACKET_BEEPS = [0x71]
10
+
11
+ attr_accessor :hourly_chimes, :button_beep
12
+
13
+ def initialize(hourly_chimes:, button_beep:)
14
+ @hourly_chimes = hourly_chimes
15
+ @button_beep = button_beep
16
+ end
17
+
18
+ def packets
19
+ [
20
+ CPACKET_BEEPS + [hourly_chimes, button_beep]
21
+ ]
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,45 @@
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 SoundTheme
8
+ include Helpers::CpacketPaginator
9
+ prepend Helpers::CrcPacketsWrapper
10
+
11
+ CPACKET_SECT = [0x90, 0x03]
12
+ CPACKET_DATA = [0x91, 0x03]
13
+ CPACKET_END = [0x92, 0x03]
14
+
15
+ SOUND_DATA_HEADER = "\x25\x04\x19\x69"
16
+
17
+ attr_accessor :sound_data
18
+
19
+ def initialize(sound_data:)
20
+ @sound_data = sound_data
21
+ end
22
+
23
+ def packets
24
+ [load_sect] + payloads + [CPACKET_END]
25
+ end
26
+
27
+ private
28
+
29
+ def sound_bytes
30
+ sound_data.delete_prefix(SOUND_DATA_HEADER).bytes
31
+ end
32
+
33
+ def load_sect
34
+ CPACKET_SECT + [payloads.length, offset]
35
+ end
36
+
37
+ def payloads
38
+ paginate_cpackets(header: CPACKET_DATA, cpackets: sound_bytes)
39
+ end
40
+
41
+ def offset
42
+ 0x100 - sound_bytes.length
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "timex_datalink_client/helpers/crc_packets_wrapper"
4
+
5
+ class TimexDatalinkClient
6
+ class Start
7
+ prepend Helpers::CrcPacketsWrapper
8
+
9
+ CPACKET_START = [0x20, 0x00, 0x00, 0x03]
10
+
11
+ def packets
12
+ [CPACKET_START]
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TimexDatalinkClient
4
+ class Sync
5
+ SYNC_1_BYTE = [0x55]
6
+ SYNC_2_BYTE = [0xaa]
7
+
8
+ SYNC_2_LENGTH = 40
9
+
10
+ attr_accessor :length
11
+
12
+ def initialize(length: 300)
13
+ @length = length
14
+ end
15
+
16
+ def packets
17
+ [render_sync_1 + render_sync_2]
18
+ end
19
+
20
+ private
21
+
22
+ def render_sync_1
23
+ SYNC_1_BYTE * length
24
+ end
25
+
26
+ def render_sync_2
27
+ SYNC_2_BYTE * SYNC_2_LENGTH
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "timex_datalink_client/helpers/char_encoders"
4
+ require "timex_datalink_client/helpers/crc_packets_wrapper"
5
+
6
+ class TimexDatalinkClient
7
+ class Time
8
+ include Helpers::CharEncoders
9
+ prepend Helpers::CrcPacketsWrapper
10
+
11
+ CPACKET_TIME = [0x32]
12
+
13
+ attr_accessor :zone, :is_24h, :date_format, :time
14
+
15
+ def initialize(zone:, is_24h:, date_format:, time:)
16
+ @zone = zone
17
+ @is_24h = is_24h
18
+ @date_format = date_format
19
+ @time = time
20
+ end
21
+
22
+ def packets
23
+ [
24
+ [
25
+ CPACKET_TIME,
26
+ zone,
27
+ time.sec,
28
+ time.hour,
29
+ time.min,
30
+ time.month,
31
+ time.day,
32
+ year_mod_1900,
33
+ timezone_characters,
34
+ wday_from_monday,
35
+ is_24h_value,
36
+ date_format
37
+ ].flatten
38
+ ]
39
+ end
40
+
41
+ private
42
+
43
+ def timezone_characters
44
+ chars_for(time.zone.downcase)
45
+ end
46
+
47
+ def year_mod_1900
48
+ time.year % 100
49
+ end
50
+
51
+ def wday_from_monday
52
+ (time.wday + 6) % 7
53
+ end
54
+
55
+ def is_24h_value
56
+ is_24h ? 2 : 1
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TimexDatalinkClient
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,47 @@
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 WristApp
8
+ include Helpers::CpacketPaginator
9
+ prepend Helpers::CrcPacketsWrapper
10
+
11
+ CPACKET_CLEAR = [0x93, 0x02]
12
+ CPACKET_SECT = [0x90, 0x02]
13
+ CPACKET_DATA = [0x91, 0x02]
14
+ CPACKET_END = [0x92, 0x02]
15
+
16
+ WRIST_APP_DELIMITER = /\xac.*\r\n/n
17
+ WRIST_APP_CODE_INDEX = 8
18
+
19
+ attr_accessor :wrist_app_data
20
+
21
+ def initialize(wrist_app_data:)
22
+ @wrist_app_data = wrist_app_data
23
+ end
24
+
25
+ def packets
26
+ [CPACKET_CLEAR, cpacket_sect] + payloads + [CPACKET_END]
27
+ end
28
+
29
+ private
30
+
31
+ def cpacket_sect
32
+ CPACKET_SECT + [payloads.length, 1]
33
+ end
34
+
35
+ def wrist_app_ascii
36
+ wrist_app_data.split(WRIST_APP_DELIMITER)[WRIST_APP_CODE_INDEX]
37
+ end
38
+
39
+ def wrist_app_bytes
40
+ [wrist_app_ascii].pack("H*").bytes
41
+ end
42
+
43
+ def payloads
44
+ paginate_cpackets(header: CPACKET_DATA, cpackets: wrist_app_bytes)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "timex_datalink_client/alarm"
4
+ require "timex_datalink_client/eeprom"
5
+ require "timex_datalink_client/eeprom/anniversary"
6
+ require "timex_datalink_client/eeprom/appointment"
7
+ require "timex_datalink_client/eeprom/list"
8
+ require "timex_datalink_client/eeprom/phone_number"
9
+ require "timex_datalink_client/end"
10
+ require "timex_datalink_client/notebook_adapter"
11
+ require "timex_datalink_client/sound_options"
12
+ require "timex_datalink_client/sound_theme"
13
+ require "timex_datalink_client/start"
14
+ require "timex_datalink_client/sync"
15
+ require "timex_datalink_client/time"
16
+ require "timex_datalink_client/version"
17
+ require "timex_datalink_client/wrist_app"
18
+
19
+ class TimexDatalinkClient
20
+ attr_accessor :serial_device, :models
21
+
22
+ def initialize(serial_device:, models: [])
23
+ @serial_device = serial_device
24
+ @models = models
25
+ end
26
+
27
+ def write
28
+ notebook_adapter.write(packets)
29
+ end
30
+
31
+ def packets
32
+ models.map(&:packets).flatten(1)
33
+ end
34
+
35
+ private
36
+
37
+ def notebook_adapter
38
+ @notebook_adapter ||= NotebookAdapter.new(serial_device)
39
+ end
40
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: timex_datalink_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Maxwell Pray
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-09-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: crc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.4.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.4.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubyserial
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.6.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.6.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.11.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.11.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: tzinfo
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 2.0.5
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 2.0.5
69
+ description: Write data to Timex Datalink watches with an optical sensor
70
+ email: synthead@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/timex_datalink_client.rb
76
+ - lib/timex_datalink_client/alarm.rb
77
+ - lib/timex_datalink_client/eeprom.rb
78
+ - lib/timex_datalink_client/eeprom/anniversary.rb
79
+ - lib/timex_datalink_client/eeprom/appointment.rb
80
+ - lib/timex_datalink_client/eeprom/list.rb
81
+ - lib/timex_datalink_client/eeprom/phone_number.rb
82
+ - lib/timex_datalink_client/end.rb
83
+ - lib/timex_datalink_client/helpers/char_encoders.rb
84
+ - lib/timex_datalink_client/helpers/cpacket_paginator.rb
85
+ - lib/timex_datalink_client/helpers/crc_packets_wrapper.rb
86
+ - lib/timex_datalink_client/helpers/length_packet_wrapper.rb
87
+ - lib/timex_datalink_client/notebook_adapter.rb
88
+ - lib/timex_datalink_client/sound_options.rb
89
+ - lib/timex_datalink_client/sound_theme.rb
90
+ - lib/timex_datalink_client/start.rb
91
+ - lib/timex_datalink_client/sync.rb
92
+ - lib/timex_datalink_client/time.rb
93
+ - lib/timex_datalink_client/version.rb
94
+ - lib/timex_datalink_client/wrist_app.rb
95
+ homepage: https://github.com/synthead/timex_datalink_client
96
+ licenses:
97
+ - MIT
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubygems_version: 3.3.7
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Library for optical Timex Datalink watches
118
+ test_files: []