timex_datalink_client 0.1.0 → 0.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b30f06f6a23f4312ee7167089c7e0704ef5f799b4c3f7a2be36d57b445074f46
4
- data.tar.gz: f2a82191c18efa5a7c51b422ff6b8c0ad30589890eac654a47507ece261ec445
3
+ metadata.gz: 187352acb16bdc8baa7fec37d4793942f49b6c3d60da9a778b4afd94505c9f1e
4
+ data.tar.gz: 55214e32e3536da008eb7739d0921af0012c1af6ff70d17491ef37a2fd6008a8
5
5
  SHA512:
6
- metadata.gz: 78ddeedea22f0d2476b934d84a0751e67c63c2528cdab1a077cf5a4ddde7310e716da02be053d7abfee90e17bd9110ea92d75f84df510b7acc79e81c814598c3
7
- data.tar.gz: 9a4974b2abd86722dacc1d4badd802fcc3b7ac84fab8d27d2bc6f39c31269d0c188635cf4e89e55b189aa86c9290a5148e26925e9c9f15337503d539df01c838
6
+ metadata.gz: 9106e98e689a8646ab779cd1ca38bce9c220c8aa80ae0fe984237e6a92270b0ee10bbdf9b31bc40c4492dc7b17d25c796baf7f3a5720a4649d7deb09a37b540f
7
+ data.tar.gz: 70e7601d4ba51ecfc3cb6d3f51549e8272ec3baf55ee39174a6fbc5f48272569efcfad25b3eef447a05af767c855f79a4b84d15c286a39d30d2ad7506d273213
@@ -14,6 +14,13 @@ class TimexDatalinkClient
14
14
 
15
15
  attr_accessor :number, :audible, :time, :message
16
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.
17
24
  def initialize(number:, audible:, time:, message:)
18
25
  @number = number
19
26
  @audible = audible
@@ -21,6 +28,9 @@ class TimexDatalinkClient
21
28
  @message = message
22
29
  end
23
30
 
31
+ # Compile packets for an alarm.
32
+ #
33
+ # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
24
34
  def packets
25
35
  [
26
36
  [
@@ -31,7 +41,7 @@ class TimexDatalinkClient
31
41
  0,
32
42
  0,
33
43
  message_characters,
34
- audible
44
+ audible_integer
35
45
  ].flatten
36
46
  ]
37
47
  end
@@ -43,5 +53,9 @@ class TimexDatalinkClient
43
53
 
44
54
  chars_for(message_padded)
45
55
  end
56
+
57
+ def audible_integer
58
+ audible ? 1 : 0
59
+ end
46
60
  end
47
61
  end
@@ -11,11 +11,19 @@ class TimexDatalinkClient
11
11
 
12
12
  attr_accessor :time, :anniversary
13
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.
14
19
  def initialize(time:, anniversary:)
15
20
  @time = time
16
21
  @anniversary = anniversary
17
22
  end
18
23
 
24
+ # Compile a packet for an anniversary.
25
+ #
26
+ # @return [Array<Integer>] Array of integers that represent bytes.
19
27
  def packet
20
28
  [
21
29
  time.month,
@@ -11,11 +11,19 @@ class TimexDatalinkClient
11
11
 
12
12
  attr_accessor :time, :message
13
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.
14
19
  def initialize(time:, message:)
15
20
  @time = time
16
21
  @message = message
17
22
  end
18
23
 
24
+ # Compile a packet for an appointment.
25
+ #
26
+ # @return [Array<Integer>] Array of integers that represent bytes.
19
27
  def packet
20
28
  [
21
29
  time.month,
@@ -11,11 +11,19 @@ class TimexDatalinkClient
11
11
 
12
12
  attr_accessor :list_entry, :priority
13
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.
14
19
  def initialize(list_entry:, priority:)
15
20
  @list_entry = list_entry
16
21
  @priority = priority
17
22
  end
18
23
 
24
+ # Compile a packet for a list.
25
+ #
26
+ # @return [Array<Integer>] Array of integers that represent bytes.
19
27
  def packet
20
28
  [
21
29
  priority,
@@ -13,12 +13,21 @@ class TimexDatalinkClient
13
13
 
14
14
  attr_accessor :name, :number, :type
15
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.
16
22
  def initialize(name:, number:, type: " ")
17
23
  @name = name
18
24
  @number = number
19
25
  @type = type
20
26
  end
21
27
 
28
+ # Compile a packet for a phone number.
29
+ #
30
+ # @return [Array<Integer>] Array of integers that represent bytes.
22
31
  def packet
23
32
  [
24
33
  number_with_type_characters,
@@ -18,6 +18,15 @@ class TimexDatalinkClient
18
18
 
19
19
  attr_accessor :appointments, :anniversaries, :phone_numbers, :lists, :appointment_notification
20
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.
21
30
  def initialize(appointments: [], anniversaries: [], phone_numbers: [], lists: [], appointment_notification: APPOINTMENT_NO_NOTIFICATION)
22
31
  @appointments = appointments
23
32
  @anniversaries = anniversaries
@@ -26,6 +35,9 @@ class TimexDatalinkClient
26
35
  @appointment_notification = appointment_notification
27
36
  end
28
37
 
38
+ # Compile packets for EEPROM data.
39
+ #
40
+ # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
29
41
  def packets
30
42
  [CPACKET_CLEAR, header] + payloads + [CPACKET_END]
31
43
  end
@@ -8,6 +8,9 @@ class TimexDatalinkClient
8
8
 
9
9
  CPACKET_SKIP = [0x21]
10
10
 
11
+ # Compile packets for data end command.
12
+ #
13
+ # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
11
14
  def packets
12
15
  [CPACKET_SKIP]
13
16
  end
@@ -4,24 +4,42 @@ require "rubyserial"
4
4
 
5
5
  class TimexDatalinkClient
6
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)
7
+ BYTE_SLEEP_DEFAULT = 0.025
8
+ PACKET_SLEEP_DEFAULT = 0.25
9
+
10
+ attr_accessor :serial_device, :byte_sleep, :packet_sleep, :verbose
11
+
12
+ # Create a NotebookAdapter instance.
13
+ #
14
+ # @param serial_device [String] Path to serial device.
15
+ # @param byte_sleep [Integer, nil] Time to sleep after sending byte.
16
+ # @param packet_sleep [Integer, nil] Time to sleep after sending packet of bytes.
17
+ # @param verbose [Boolean] Write verbose output to console.
18
+ # @return [NotebookAdapter] NotebookAdapter instance.
19
+ def initialize(serial_device:, byte_sleep: nil, packet_sleep: nil, verbose: false)
13
20
  @serial_device = serial_device
21
+ @byte_sleep = byte_sleep || BYTE_SLEEP_DEFAULT
22
+ @packet_sleep = packet_sleep || PACKET_SLEEP_DEFAULT
23
+ @verbose = verbose
14
24
  end
15
25
 
26
+ # Write packets of bytes to serial device.
27
+ #
28
+ # @param packets [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
29
+ # @return [void]
16
30
  def write(packets)
17
31
  packets.each do |packet|
18
32
  packet.each do |byte|
33
+ printf("%.2X ", byte) if verbose
34
+
19
35
  serial.write(byte.chr)
20
36
 
21
- sleep(BYTE_SLEEP)
37
+ sleep(byte_sleep)
22
38
  end
23
39
 
24
- sleep(PACKET_SLEEP)
40
+ sleep(packet_sleep)
41
+
42
+ puts if verbose
25
43
  end
26
44
  end
27
45
 
@@ -8,17 +8,33 @@ class TimexDatalinkClient
8
8
 
9
9
  CPACKET_BEEPS = [0x71]
10
10
 
11
- attr_accessor :hourly_chimes, :button_beep
11
+ attr_accessor :hourly_chime, :button_beep
12
12
 
13
- def initialize(hourly_chimes:, button_beep:)
14
- @hourly_chimes = hourly_chimes
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
15
20
  @button_beep = button_beep
16
21
  end
17
22
 
23
+ # Compile packets for sound options.
24
+ #
25
+ # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
18
26
  def packets
19
27
  [
20
- CPACKET_BEEPS + [hourly_chimes, button_beep]
28
+ CPACKET_BEEPS + [hourly_chime_integer, button_beep_integer]
21
29
  ]
22
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
23
39
  end
24
40
  end
@@ -14,32 +14,49 @@ class TimexDatalinkClient
14
14
 
15
15
  SOUND_DATA_HEADER = "\x25\x04\x19\x69"
16
16
 
17
- attr_accessor :sound_data
18
-
19
- def initialize(sound_data:)
20
- @sound_data = sound_data
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
21
27
  end
22
28
 
29
+ # Compile packets for a sound theme.
30
+ #
31
+ # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
23
32
  def packets
24
33
  [load_sect] + payloads + [CPACKET_END]
25
34
  end
26
35
 
27
36
  private
28
37
 
29
- def sound_bytes
30
- sound_data.delete_prefix(SOUND_DATA_HEADER).bytes
31
- end
32
-
33
38
  def load_sect
34
39
  CPACKET_SECT + [payloads.length, offset]
35
40
  end
36
41
 
37
42
  def payloads
38
- paginate_cpackets(header: CPACKET_DATA, cpackets: sound_bytes)
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)
39
56
  end
40
57
 
41
58
  def offset
42
- 0x100 - sound_bytes.length
59
+ 0x100 - sound_theme_data.bytesize
43
60
  end
44
61
  end
45
62
  end
@@ -8,6 +8,9 @@ class TimexDatalinkClient
8
8
 
9
9
  CPACKET_START = [0x20, 0x00, 0x00, 0x03]
10
10
 
11
+ # Compile packets for data start command.
12
+ #
13
+ # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
11
14
  def packets
12
15
  [CPACKET_START]
13
16
  end
@@ -9,10 +9,17 @@ class TimexDatalinkClient
9
9
 
10
10
  attr_accessor :length
11
11
 
12
+ # Create a Sync instance.
13
+ #
14
+ # @param length [Integer] Number of 0x55 sync bytes to use.
15
+ # @return [Sync] Sync instance.
12
16
  def initialize(length: 300)
13
17
  @length = length
14
18
  end
15
19
 
20
+ # Compile packets for syncronization data.
21
+ #
22
+ # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
16
23
  def packets
17
24
  [render_sync_1 + render_sync_2]
18
25
  end
@@ -12,6 +12,13 @@ class TimexDatalinkClient
12
12
 
13
13
  attr_accessor :zone, :is_24h, :date_format, :time
14
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
+ # @return [Time] Time instance.
15
22
  def initialize(zone:, is_24h:, date_format:, time:)
16
23
  @zone = zone
17
24
  @is_24h = is_24h
@@ -19,6 +26,9 @@ class TimexDatalinkClient
19
26
  @time = time
20
27
  end
21
28
 
29
+ # Compile packets for a time.
30
+ #
31
+ # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
22
32
  def packets
23
33
  [
24
34
  [
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class TimexDatalinkClient
4
- VERSION = "0.1.0"
4
+ VERSION = "0.3.1"
5
5
  end
@@ -16,12 +16,21 @@ class TimexDatalinkClient
16
16
  WRIST_APP_DELIMITER = /\xac.*\r\n/n
17
17
  WRIST_APP_CODE_INDEX = 8
18
18
 
19
- attr_accessor :wrist_app_data
19
+ attr_accessor :zap_file
20
20
 
21
- def initialize(wrist_app_data:)
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)
22
27
  @wrist_app_data = wrist_app_data
28
+ @zap_file = zap_file
23
29
  end
24
30
 
31
+ # Compile packets for an alarm.
32
+ #
33
+ # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
25
34
  def packets
26
35
  [CPACKET_CLEAR, cpacket_sect] + payloads + [CPACKET_END]
27
36
  end
@@ -32,16 +41,24 @@ class TimexDatalinkClient
32
41
  CPACKET_SECT + [payloads.length, 1]
33
42
  end
34
43
 
35
- def wrist_app_ascii
36
- wrist_app_data.split(WRIST_APP_DELIMITER)[WRIST_APP_CODE_INDEX]
44
+ def payloads
45
+ paginate_cpackets(header: CPACKET_DATA, cpackets: wrist_app_data.bytes)
37
46
  end
38
47
 
39
- def wrist_app_bytes
40
- [wrist_app_ascii].pack("H*").bytes
48
+ def wrist_app_data
49
+ @wrist_app_data || zap_file_data_binary
41
50
  end
42
51
 
43
- def payloads
44
- paginate_cpackets(header: CPACKET_DATA, cpackets: wrist_app_bytes)
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*")
45
62
  end
46
63
  end
47
64
  end
@@ -17,17 +17,35 @@ require "timex_datalink_client/version"
17
17
  require "timex_datalink_client/wrist_app"
18
18
 
19
19
  class TimexDatalinkClient
20
- attr_accessor :serial_device, :models
20
+ attr_accessor :serial_device, :models, :byte_sleep, :packet_sleep, :verbose
21
21
 
22
- def initialize(serial_device:, models: [])
22
+ # Create a TimexDatalinkClient instance.
23
+ #
24
+ # @param serial_device [String] Path to serial device.
25
+ # @param models [Array<Alarm, Eeprom, End, SoundOptions, SoundTheme, Start, Sync, Time, WristApp>] Models to compile
26
+ # data for.
27
+ # @param byte_sleep [Integer, nil] Time to sleep after sending byte.
28
+ # @param packet_sleep [Integer, nil] Time to sleep after sending packet of bytes.
29
+ # @param verbose [Boolean] Write verbose output to console.
30
+ # @return [TimexDatalinkClient] TimexDatalinkClient instance.
31
+ def initialize(serial_device:, models: [], byte_sleep: nil, packet_sleep: nil, verbose: false)
23
32
  @serial_device = serial_device
24
33
  @models = models
34
+ @byte_sleep = byte_sleep
35
+ @packet_sleep = packet_sleep
36
+ @verbose = verbose
25
37
  end
26
38
 
39
+ # Write data for all models to serial device.
40
+ #
41
+ # @return [void]
27
42
  def write
28
43
  notebook_adapter.write(packets)
29
44
  end
30
45
 
46
+ # Compile packets for all models.
47
+ #
48
+ # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
31
49
  def packets
32
50
  models.map(&:packets).flatten(1)
33
51
  end
@@ -35,6 +53,11 @@ class TimexDatalinkClient
35
53
  private
36
54
 
37
55
  def notebook_adapter
38
- @notebook_adapter ||= NotebookAdapter.new(serial_device)
56
+ @notebook_adapter ||= NotebookAdapter.new(
57
+ serial_device: serial_device,
58
+ byte_sleep: byte_sleep,
59
+ packet_sleep: packet_sleep,
60
+ verbose: verbose
61
+ )
39
62
  end
40
63
  end
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.1.0
4
+ version: 0.3.1
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-09-05 00:00:00.000000000 Z
11
+ date: 2022-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: crc
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 2.0.5
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard-junk
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.0.9
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.0.9
69
83
  description: Write data to Timex Datalink watches with an optical sensor
70
84
  email: synthead@gmail.com
71
85
  executables: []