timex_datalink_client 0.4.1 → 0.6.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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/timex_datalink_client/helpers/char_encoders.rb +2 -2
  3. data/lib/timex_datalink_client/helpers/cpacket_paginator.rb +2 -4
  4. data/lib/timex_datalink_client/protocol_1/alarm.rb +82 -0
  5. data/lib/timex_datalink_client/protocol_1/eeprom/anniversary.rb +44 -0
  6. data/lib/timex_datalink_client/protocol_1/eeprom/appointment.rb +49 -0
  7. data/lib/timex_datalink_client/protocol_1/eeprom/list.rb +43 -0
  8. data/lib/timex_datalink_client/protocol_1/eeprom/phone_number.rb +56 -0
  9. data/lib/timex_datalink_client/protocol_1/eeprom.rb +100 -0
  10. data/lib/timex_datalink_client/protocol_1/end.rb +20 -0
  11. data/lib/timex_datalink_client/protocol_1/start.rb +20 -0
  12. data/lib/timex_datalink_client/protocol_1/sync.rb +40 -0
  13. data/lib/timex_datalink_client/protocol_1/time.rb +61 -0
  14. data/lib/timex_datalink_client/protocol_1/time_name.rb +46 -0
  15. data/lib/timex_datalink_client/protocol_3/alarm.rb +59 -0
  16. data/lib/timex_datalink_client/protocol_3/eeprom/anniversary.rb +44 -0
  17. data/lib/timex_datalink_client/protocol_3/eeprom/appointment.rb +49 -0
  18. data/lib/timex_datalink_client/protocol_3/eeprom/list.rb +43 -0
  19. data/lib/timex_datalink_client/protocol_3/eeprom/phone_number.rb +56 -0
  20. data/lib/timex_datalink_client/protocol_3/eeprom.rb +95 -0
  21. data/lib/timex_datalink_client/protocol_3/end.rb +20 -0
  22. data/lib/timex_datalink_client/protocol_3/sound_options.rb +42 -0
  23. data/lib/timex_datalink_client/protocol_3/sound_theme.rb +65 -0
  24. data/lib/timex_datalink_client/protocol_3/start.rb +20 -0
  25. data/lib/timex_datalink_client/protocol_3/sync.rb +40 -0
  26. data/lib/timex_datalink_client/protocol_3/time.rb +77 -0
  27. data/lib/timex_datalink_client/protocol_3/wrist_app.rb +67 -0
  28. data/lib/timex_datalink_client/protocol_9/alarm.rb +63 -0
  29. data/lib/timex_datalink_client/protocol_9/eeprom/chrono.rb +47 -0
  30. data/lib/timex_datalink_client/protocol_9/eeprom/phone_number.rb +74 -0
  31. data/lib/timex_datalink_client/protocol_9/eeprom.rb +85 -0
  32. data/lib/timex_datalink_client/protocol_9/end.rb +20 -0
  33. data/lib/timex_datalink_client/protocol_9/sound_options.rb +42 -0
  34. data/lib/timex_datalink_client/protocol_9/start.rb +20 -0
  35. data/lib/timex_datalink_client/protocol_9/sync.rb +40 -0
  36. data/lib/timex_datalink_client/protocol_9/time.rb +61 -0
  37. data/lib/timex_datalink_client/protocol_9/time_name.rb +46 -0
  38. data/lib/timex_datalink_client/protocol_9/timer.rb +54 -0
  39. data/lib/timex_datalink_client/version.rb +1 -1
  40. data/lib/timex_datalink_client.rb +44 -16
  41. metadata +38 -16
  42. data/lib/timex_datalink_client/alarm.rb +0 -59
  43. data/lib/timex_datalink_client/eeprom/anniversary.rb +0 -42
  44. data/lib/timex_datalink_client/eeprom/appointment.rb +0 -47
  45. data/lib/timex_datalink_client/eeprom/list.rb +0 -41
  46. data/lib/timex_datalink_client/eeprom/phone_number.rb +0 -56
  47. data/lib/timex_datalink_client/eeprom.rb +0 -92
  48. data/lib/timex_datalink_client/end.rb +0 -18
  49. data/lib/timex_datalink_client/sound_options.rb +0 -40
  50. data/lib/timex_datalink_client/sound_theme.rb +0 -62
  51. data/lib/timex_datalink_client/start.rb +0 -18
  52. data/lib/timex_datalink_client/sync.rb +0 -37
  53. data/lib/timex_datalink_client/time.rb +0 -75
  54. data/lib/timex_datalink_client/wrist_app.rb +0 -64
@@ -1,59 +0,0 @@
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
- # Create an Alarm instance.
18
- #
19
- # @param number [Integer] Alarm number (from 1 to 5).
20
- # @param audible [Boolean] Toggle alarm sounds.
21
- # @param time [::Time] Time of alarm.
22
- # @param message [String] Alarm message text.
23
- # @return [Alarm] Alarm instance.
24
- def initialize(number:, audible:, time:, message:)
25
- @number = number
26
- @audible = audible
27
- @time = time
28
- @message = message
29
- end
30
-
31
- # Compile packets for an alarm.
32
- #
33
- # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
34
- def packets
35
- [
36
- [
37
- CPACKET_ALARM,
38
- number,
39
- time.hour,
40
- time.min,
41
- 0,
42
- 0,
43
- message_characters,
44
- audible_integer
45
- ].flatten
46
- ]
47
- end
48
-
49
- private
50
-
51
- def message_characters
52
- chars_for(message, length: 8, pad: true)
53
- end
54
-
55
- def audible_integer
56
- audible ? 1 : 0
57
- end
58
- end
59
- end
@@ -1,42 +0,0 @@
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
- # Create an Anniversary instance.
15
- #
16
- # @param time [::Time] Time of anniversary.
17
- # @param anniversary [String] Anniversary text.
18
- # @return [Anniversary] Anniversary instance.
19
- def initialize(time:, anniversary:)
20
- @time = time
21
- @anniversary = anniversary
22
- end
23
-
24
- # Compile a packet for an anniversary.
25
- #
26
- # @return [Array<Integer>] Array of integers that represent bytes.
27
- def packet
28
- [
29
- time.month,
30
- time.day,
31
- anniversary_characters
32
- ].flatten
33
- end
34
-
35
- private
36
-
37
- def anniversary_characters
38
- eeprom_chars_for(anniversary)
39
- end
40
- end
41
- end
42
- end
@@ -1,47 +0,0 @@
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
- # Create an Appointment instance.
15
- #
16
- # @param time [::Time] Time of appointment.
17
- # @param message [String] Appointment text.
18
- # @return [Appointment] Appointment instance.
19
- def initialize(time:, message:)
20
- @time = time
21
- @message = message
22
- end
23
-
24
- # Compile a packet for an appointment.
25
- #
26
- # @return [Array<Integer>] Array of integers that represent bytes.
27
- def packet
28
- [
29
- time.month,
30
- time.day,
31
- time_15m,
32
- message_characters
33
- ].flatten
34
- end
35
-
36
- private
37
-
38
- def time_15m
39
- time.hour * 4 + time.min / 15
40
- end
41
-
42
- def message_characters
43
- eeprom_chars_for(message)
44
- end
45
- end
46
- end
47
- end
@@ -1,41 +0,0 @@
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
- # Create a List instance.
15
- #
16
- # @param list_entry [String] List entry text.
17
- # @param priority [Integer] List priority.
18
- # @return [List] List instance.
19
- def initialize(list_entry:, priority:)
20
- @list_entry = list_entry
21
- @priority = priority
22
- end
23
-
24
- # Compile a packet for a list.
25
- #
26
- # @return [Array<Integer>] Array of integers that represent bytes.
27
- def packet
28
- [
29
- priority,
30
- list_entry_characters
31
- ].flatten
32
- end
33
-
34
- private
35
-
36
- def list_entry_characters
37
- eeprom_chars_for(list_entry)
38
- end
39
- end
40
- end
41
- end
@@ -1,56 +0,0 @@
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
- # Create a PhoneNumber instance.
17
- #
18
- # @param name [String] Name associated to phone number.
19
- # @param number [String] Phone number text.
20
- # @param type [String] Phone number type.
21
- # @return [PhoneNumber] PhoneNumber instance.
22
- def initialize(name:, number:, type: " ")
23
- @name = name
24
- @number = number
25
- @type = type
26
- end
27
-
28
- # Compile a packet for a phone number.
29
- #
30
- # @return [Array<Integer>] Array of integers that represent bytes.
31
- def packet
32
- [
33
- number_with_type_characters,
34
- name_characters,
35
- ].flatten
36
- end
37
-
38
- private
39
-
40
- def number_with_type_truncated
41
- number_with_type = "#{number} #{type}"
42
- padded_number_with_type = number_with_type.rjust(PHONE_DIGITS)
43
-
44
- padded_number_with_type[0..PHONE_DIGITS - 1]
45
- end
46
-
47
- def number_with_type_characters
48
- phone_chars_for(number_with_type_truncated)
49
- end
50
-
51
- def name_characters
52
- eeprom_chars_for(name)
53
- end
54
- end
55
- end
56
- end
@@ -1,92 +0,0 @@
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
- # Create an Eeprom instance.
22
- #
23
- # @param appointments [Array<Appointment>] Appointments to be added to EEPROM data.
24
- # @param anniversaries [Array<Anniversary>] Anniversaries to be added to EEPROM data.
25
- # @param phone_numbers [Array<PhoneNumber>] Phone numbers to be added to EEPROM data.
26
- # @param lists [Array<List>] Lists to be added to EEPROM data.
27
- # @param appointment_notification [Integer] Appointment notification (intervals of 15 minutes, 255 for no
28
- # notification)
29
- # @return [Eeprom] Eeprom instance.
30
- def initialize(appointments: [], anniversaries: [], phone_numbers: [], lists: [], appointment_notification: APPOINTMENT_NO_NOTIFICATION)
31
- @appointments = appointments
32
- @anniversaries = anniversaries
33
- @phone_numbers = phone_numbers
34
- @lists = lists
35
- @appointment_notification = appointment_notification
36
- end
37
-
38
- # Compile packets for EEPROM data.
39
- #
40
- # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
41
- def packets
42
- [CPACKET_CLEAR, header] + payloads + [CPACKET_END]
43
- end
44
-
45
- private
46
-
47
- def header
48
- [
49
- CPACKET_SECT,
50
- payloads.length,
51
- items_addresses,
52
- items_lengths,
53
- earliest_appointment_year,
54
- appointment_notification
55
- ].flatten
56
- end
57
-
58
- def payloads
59
- paginate_cpackets(header: CPACKET_DATA, cpackets: all_packets)
60
- end
61
-
62
- def all_items
63
- [appointments, lists, phone_numbers, anniversaries]
64
- end
65
-
66
- def all_packets
67
- all_items.flatten.map(&:packet).flatten
68
- end
69
-
70
- def items_addresses
71
- address = START_ADDRESS
72
-
73
- all_items.each_with_object([]) do |items, addresses|
74
- addresses.concat(address.divmod(256))
75
-
76
- address += items.sum { |item| item.packet.length }
77
- end
78
- end
79
-
80
- def items_lengths
81
- all_items.map(&:length)
82
- end
83
-
84
- def earliest_appointment_year
85
- earliest_appointment = appointments.min_by(&:time)
86
-
87
- return 0 unless earliest_appointment
88
-
89
- earliest_appointment.time.year % 100
90
- end
91
- end
92
- end
@@ -1,18 +0,0 @@
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
- # Compile packets for data end command.
12
- #
13
- # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
14
- def packets
15
- [CPACKET_SKIP]
16
- end
17
- end
18
- end
@@ -1,40 +0,0 @@
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_chime, :button_beep
12
-
13
- # Create a SoundOptions instance.
14
- #
15
- # @param hourly_chime [Boolean] Toggle hourly chime sounds.
16
- # @param button_beep [Boolean] Toggle button beep sounds.
17
- # @return [SoundOptions] SoundOptions instance.
18
- def initialize(hourly_chime:, button_beep:)
19
- @hourly_chime = hourly_chime
20
- @button_beep = button_beep
21
- end
22
-
23
- # Compile packets for sound options.
24
- #
25
- # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
26
- def packets
27
- [
28
- CPACKET_BEEPS + [hourly_chime_integer, button_beep_integer]
29
- ]
30
- end
31
-
32
- def hourly_chime_integer
33
- hourly_chime ? 1 : 0
34
- end
35
-
36
- def button_beep_integer
37
- button_beep ? 1 : 0
38
- end
39
- end
40
- end
@@ -1,62 +0,0 @@
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 :spc_file
18
-
19
- # Create a SoundTheme instance.
20
- #
21
- # @param sound_theme_data [String, nil] Sound theme data.
22
- # @param spc_file [String, nil] Path to SPC file.
23
- # @return [SoundTheme] SoundTheme instance.
24
- def initialize(sound_theme_data: nil, spc_file: nil)
25
- @sound_theme_data = sound_theme_data
26
- @spc_file = spc_file
27
- end
28
-
29
- # Compile packets for a sound theme.
30
- #
31
- # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
32
- def packets
33
- [load_sect] + payloads + [CPACKET_END]
34
- end
35
-
36
- private
37
-
38
- def load_sect
39
- CPACKET_SECT + [payloads.length, offset]
40
- end
41
-
42
- def payloads
43
- paginate_cpackets(header: CPACKET_DATA, cpackets: sound_theme_data.bytes)
44
- end
45
-
46
- def sound_theme_data
47
- @sound_theme_data || spc_file_data_without_header
48
- end
49
-
50
- def spc_file_data
51
- File.open(spc_file, "rb").read
52
- end
53
-
54
- def spc_file_data_without_header
55
- spc_file_data.delete_prefix(SOUND_DATA_HEADER)
56
- end
57
-
58
- def offset
59
- 0x100 - sound_theme_data.bytesize
60
- end
61
- end
62
- end
@@ -1,18 +0,0 @@
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
- # Compile packets for data start command.
12
- #
13
- # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
14
- def packets
15
- [CPACKET_START]
16
- end
17
- end
18
- end
@@ -1,37 +0,0 @@
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
- # Create a Sync instance.
13
- #
14
- # @param length [Integer] Number of 0x55 sync bytes to use.
15
- # @return [Sync] Sync instance.
16
- def initialize(length: 300)
17
- @length = length
18
- end
19
-
20
- # Compile packets for syncronization data.
21
- #
22
- # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
23
- def packets
24
- [render_sync_1 + render_sync_2]
25
- end
26
-
27
- private
28
-
29
- def render_sync_1
30
- SYNC_1_BYTE * length
31
- end
32
-
33
- def render_sync_2
34
- SYNC_2_BYTE * SYNC_2_LENGTH
35
- end
36
- end
37
- end
@@ -1,75 +0,0 @@
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
- # Create a Time instance.
16
- #
17
- # @param zone [Integer] Time zone number (1 or 2).
18
- # @param is_24h [Boolean] Toggle 24 hour time.
19
- # @param date_format [Integer] Date format.
20
- # @param time [::Time] Time to set (including time zone).
21
- # @param name [String, nil] Name of time zone (defaults to zone from time; 3 chars max)
22
- # @return [Time] Time instance.
23
- def initialize(zone:, is_24h:, date_format:, time:, name: nil)
24
- @zone = zone
25
- @is_24h = is_24h
26
- @date_format = date_format
27
- @time = time
28
- @name = name
29
- end
30
-
31
- # Compile packets for a time.
32
- #
33
- # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
34
- def packets
35
- [
36
- [
37
- CPACKET_TIME,
38
- zone,
39
- time.sec,
40
- time.hour,
41
- time.min,
42
- time.month,
43
- time.day,
44
- year_mod_1900,
45
- name_characters,
46
- wday_from_monday,
47
- is_24h_value,
48
- date_format
49
- ].flatten
50
- ]
51
- end
52
-
53
- private
54
-
55
- def name
56
- @name || time.zone.downcase
57
- end
58
-
59
- def name_characters
60
- chars_for(name, length: 3, pad: true)
61
- end
62
-
63
- def year_mod_1900
64
- time.year % 100
65
- end
66
-
67
- def wday_from_monday
68
- (time.wday + 6) % 7
69
- end
70
-
71
- def is_24h_value
72
- is_24h ? 2 : 1
73
- end
74
- end
75
- end
@@ -1,64 +0,0 @@
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 :zap_file
20
-
21
- # Create a WristApp instance.
22
- #
23
- # @param wrist_app_data [String, nil] WristApp data.
24
- # @param zap_file [String, nil] Path to ZAP file.
25
- # @return [WristApp] WristApp instance.
26
- def initialize(wrist_app_data: nil, zap_file: nil)
27
- @wrist_app_data = wrist_app_data
28
- @zap_file = zap_file
29
- end
30
-
31
- # Compile packets for an alarm.
32
- #
33
- # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
34
- def packets
35
- [CPACKET_CLEAR, cpacket_sect] + payloads + [CPACKET_END]
36
- end
37
-
38
- private
39
-
40
- def cpacket_sect
41
- CPACKET_SECT + [payloads.length, 1]
42
- end
43
-
44
- def payloads
45
- paginate_cpackets(header: CPACKET_DATA, cpackets: wrist_app_data.bytes)
46
- end
47
-
48
- def wrist_app_data
49
- @wrist_app_data || zap_file_data_binary
50
- end
51
-
52
- def zap_file_data
53
- File.open(zap_file, "rb").read
54
- end
55
-
56
- def zap_file_data_ascii
57
- zap_file_data.split(WRIST_APP_DELIMITER)[WRIST_APP_CODE_INDEX]
58
- end
59
-
60
- def zap_file_data_binary
61
- [zap_file_data_ascii].pack("H*")
62
- end
63
- end
64
- end