timex_datalink_client 0.4.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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