timex_datalink_client 0.8.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 93fe636dc699046ea5c14683b355f8c65bb162fb18ee91b3ffe27f4a72633808
4
- data.tar.gz: d9476317e2cce78a77247c277e77208969f6e8fa13059a2e0f7452f502f9b112
3
+ metadata.gz: 7bbd5ed72c50f798a4efc663846f406338e1a777cd8587ba504a283c7976e7bf
4
+ data.tar.gz: '0843b0db0875cfc5ea663e85dcf0cf007bfb88b89306945390d51ab9eba09693'
5
5
  SHA512:
6
- metadata.gz: 313b6bc8ea78a28ee55534ff28648a6544a8aa7dcf1abd731461fc7b9c21ba3711d441de603d7f538666541d5fce4ca0d6206449a2b8cee6cf5d56a263f8691a
7
- data.tar.gz: df31c376348f69fd05ba4c0de720e443074f68d63788601610021e0328598af3cfa8a3f85789336d20e80aac90be5ac32526bc6872d208afdd2c6965582f1617
6
+ metadata.gz: 17da22510b17f02379419c84d0c80c35c9d63861d9186627d4adad2cbf7d00ed5c6aaf458316f7ec4bad5ee98fdcfa4bdbbaa96cb01b4506cce81b7193946eaa
7
+ data.tar.gz: 183bdf6f467c802df1e31c3f2b7e76d5a93a07e851fed8caf85fff56a93f3a48ef448d3b4f9b3884e46e9481e3c894702ae2994b96de92d9c09c4c1737a696af
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TimexDatalinkClient
4
+ class Helpers
5
+ module LsbMsbFormatter
6
+ def lsb_msb_format_for(value)
7
+ value.divmod(256).reverse
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/char_encoders"
4
6
  require "timex_datalink_client/helpers/crc_packets_wrapper"
5
7
 
6
8
  class TimexDatalinkClient
7
9
  class Protocol1
8
10
  class Alarm
11
+ include ActiveModel::Validations
9
12
  include Helpers::CharEncoders
10
13
  prepend Helpers::CrcPacketsWrapper
11
14
 
@@ -14,8 +17,50 @@ class TimexDatalinkClient
14
17
 
15
18
  ALARM_SILENT_START_INDEX = 0x61
16
19
 
20
+ VALID_DAYS_IN_MONTH = {
21
+ 1 => 1..31,
22
+ 2 => 1..29,
23
+ 3 => 1..31,
24
+ 4 => 1..30,
25
+ 5 => 1..31,
26
+ 6 => 1..30,
27
+ 7 => 1..31,
28
+ 8 => 1..31,
29
+ 9 => 1..30,
30
+ 10 => 1..31,
31
+ 11 => 1..30,
32
+ 12 => 1..31
33
+ }.freeze
34
+
17
35
  attr_accessor :number, :audible, :time, :message, :month, :day
18
36
 
37
+ validates :number, inclusion: {
38
+ in: 1..5,
39
+ message: "value %{value} is invalid! Valid number values are 1..5."
40
+ }
41
+
42
+ validates :month, inclusion: {
43
+ in: 1..12,
44
+ allow_nil: true,
45
+ message: "%{value} is invalid! Valid months are 1..12 and nil."
46
+ }
47
+
48
+ validates :day, inclusion: {
49
+ if: ->(alarm) { alarm.month.nil? },
50
+ in: 1..31,
51
+ allow_nil: true,
52
+ message: "%{value} is invalid! Valid days are 1..31 and nil."
53
+ }
54
+
55
+ validates :day, inclusion: {
56
+ if: ->(alarm) { alarm.day && alarm.month },
57
+ in: ->(alarm) { VALID_DAYS_IN_MONTH[alarm.month] },
58
+ message: ->(alarm, _attributes) do
59
+ "#{alarm.day} is invalid for month #{alarm.month}! " \
60
+ "Valid days are #{VALID_DAYS_IN_MONTH[alarm.month]} and nil when month is #{alarm.month}."
61
+ end
62
+ }
63
+
19
64
  # Create an Alarm instance.
20
65
  #
21
66
  # @param number [Integer] Alarm number (from 1 to 5).
@@ -36,8 +81,11 @@ class TimexDatalinkClient
36
81
 
37
82
  # Compile packets for an alarm.
38
83
  #
84
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
39
85
  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
40
86
  def packets
87
+ validate!
88
+
41
89
  [alarm_data_packet].tap do |packets|
42
90
  packets << alarm_silent_packet unless audible
43
91
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/char_encoders"
4
6
  require "timex_datalink_client/helpers/length_packet_wrapper"
5
7
 
@@ -7,11 +9,18 @@ class TimexDatalinkClient
7
9
  class Protocol1
8
10
  class Eeprom
9
11
  class List
12
+ include ActiveModel::Validations
10
13
  include Helpers::CharEncoders
11
14
  prepend Helpers::LengthPacketWrapper
12
15
 
13
16
  attr_accessor :list_entry, :priority
14
17
 
18
+ validates :priority, inclusion: {
19
+ in: 1..5,
20
+ allow_nil: true,
21
+ message: "%{value} is invalid! Valid priorities are 1..5 or nil."
22
+ }
23
+
15
24
  # Create a List instance.
16
25
  #
17
26
  # @param list_entry [String] List entry text.
@@ -24,10 +33,13 @@ class TimexDatalinkClient
24
33
 
25
34
  # Compile a packet for a list.
26
35
  #
36
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
27
37
  # @return [Array<Integer>] Array of integers that represent bytes.
28
38
  def packet
39
+ validate!
40
+
29
41
  [
30
- priority,
42
+ priority_value,
31
43
  list_entry_characters
32
44
  ].flatten
33
45
  end
@@ -37,6 +49,10 @@ class TimexDatalinkClient
37
49
  def list_entry_characters
38
50
  eeprom_chars_for(list_entry)
39
51
  end
52
+
53
+ def priority_value
54
+ priority.nil? ? 0 : priority
55
+ end
40
56
  end
41
57
  end
42
58
  end
@@ -1,16 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/crc_packets_wrapper"
4
6
 
5
7
  class TimexDatalinkClient
6
8
  class Protocol1
7
9
  class Time
10
+ include ActiveModel::Validations
8
11
  prepend Helpers::CrcPacketsWrapper
9
12
 
10
13
  CPACKET_TIME = [0x30]
11
14
 
12
15
  attr_accessor :zone, :is_24h, :time
13
16
 
17
+ validates :zone, inclusion: {
18
+ in: 1..2,
19
+ message: "%{value} is invalid! Valid zones are 1..2."
20
+ }
21
+
14
22
  # Create a Time instance.
15
23
  #
16
24
  # @param zone [Integer] Time zone number (1 or 2).
@@ -25,8 +33,11 @@ class TimexDatalinkClient
25
33
 
26
34
  # Compile packets for a time.
27
35
  #
36
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
28
37
  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
29
38
  def packets
39
+ validate!
40
+
30
41
  [
31
42
  [
32
43
  CPACKET_TIME,
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/char_encoders"
4
6
  require "timex_datalink_client/helpers/crc_packets_wrapper"
5
7
 
6
8
  class TimexDatalinkClient
7
9
  class Protocol1
8
10
  class TimeName
11
+ include ActiveModel::Validations
9
12
  include Helpers::CharEncoders
10
13
  prepend Helpers::CrcPacketsWrapper
11
14
 
@@ -13,6 +16,11 @@ class TimexDatalinkClient
13
16
 
14
17
  attr_accessor :zone, :name
15
18
 
19
+ validates :zone, inclusion: {
20
+ in: 1..2,
21
+ message: "%{value} is invalid! Valid zones are 1..2."
22
+ }
23
+
16
24
  # Create a TimeName instance.
17
25
  #
18
26
  # @param zone [Integer] Time zone number (1 or 2).
@@ -25,8 +33,11 @@ class TimexDatalinkClient
25
33
 
26
34
  # Compile packets for a time name.
27
35
  #
36
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
28
37
  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
29
38
  def packets
39
+ validate!
40
+
30
41
  [
31
42
  [
32
43
  CPACKET_NAME,
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/char_encoders"
4
6
  require "timex_datalink_client/helpers/crc_packets_wrapper"
5
7
 
6
8
  class TimexDatalinkClient
7
9
  class Protocol3
8
10
  class Alarm
11
+ include ActiveModel::Validations
9
12
  include Helpers::CharEncoders
10
13
  prepend Helpers::CrcPacketsWrapper
11
14
 
@@ -13,6 +16,11 @@ class TimexDatalinkClient
13
16
 
14
17
  attr_accessor :number, :audible, :time, :message
15
18
 
19
+ validates :number, inclusion: {
20
+ in: 1..5,
21
+ message: "value %{value} is invalid! Valid number values are 1..5."
22
+ }
23
+
16
24
  # Create an Alarm instance.
17
25
  #
18
26
  # @param number [Integer] Alarm number (from 1 to 5).
@@ -29,8 +37,11 @@ class TimexDatalinkClient
29
37
 
30
38
  # Compile packets for an alarm.
31
39
  #
40
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
32
41
  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
33
42
  def packets
43
+ validate!
44
+
34
45
  [
35
46
  [
36
47
  CPACKET_ALARM,
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/char_encoders"
4
6
  require "timex_datalink_client/helpers/length_packet_wrapper"
5
7
 
@@ -7,15 +9,22 @@ class TimexDatalinkClient
7
9
  class Protocol3
8
10
  class Eeprom
9
11
  class List
12
+ include ActiveModel::Validations
10
13
  include Helpers::CharEncoders
11
14
  prepend Helpers::LengthPacketWrapper
12
15
 
13
16
  attr_accessor :list_entry, :priority
14
17
 
18
+ validates :priority, inclusion: {
19
+ in: 1..5,
20
+ allow_nil: true,
21
+ message: "%{value} is invalid! Valid priorities are 1..5 or nil."
22
+ }
23
+
15
24
  # Create a List instance.
16
25
  #
17
26
  # @param list_entry [String] List entry text.
18
- # @param priority [Integer] List priority.
27
+ # @param priority [Integer, nil] List priority.
19
28
  # @return [List] List instance.
20
29
  def initialize(list_entry:, priority:)
21
30
  @list_entry = list_entry
@@ -24,10 +33,13 @@ class TimexDatalinkClient
24
33
 
25
34
  # Compile a packet for a list.
26
35
  #
36
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
27
37
  # @return [Array<Integer>] Array of integers that represent bytes.
28
38
  def packet
39
+ validate!
40
+
29
41
  [
30
- priority,
42
+ priority_value,
31
43
  list_entry_characters
32
44
  ].flatten
33
45
  end
@@ -37,6 +49,10 @@ class TimexDatalinkClient
37
49
  def list_entry_characters
38
50
  eeprom_chars_for(list_entry)
39
51
  end
52
+
53
+ def priority_value
54
+ priority.nil? ? 0 : priority
55
+ end
40
56
  end
41
57
  end
42
58
  end
@@ -1,23 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/char_encoders"
4
6
  require "timex_datalink_client/helpers/crc_packets_wrapper"
5
7
 
6
8
  class TimexDatalinkClient
7
9
  class Protocol3
8
10
  class Time
11
+ include ActiveModel::Validations
9
12
  include Helpers::CharEncoders
10
13
  prepend Helpers::CrcPacketsWrapper
11
14
 
12
15
  CPACKET_TIME = [0x32]
13
16
 
17
+ DATE_FORMAT_MAP = {
18
+ "%_m-%d-%y" => 0,
19
+ "%_d-%m-%y" => 1,
20
+ "%y-%m-%d" => 2,
21
+ "%_m.%d.%y" => 4,
22
+ "%_d.%m.%y" => 5,
23
+ "%y.%m.%d" => 6
24
+ }.freeze
25
+
26
+ validates :zone, inclusion: {
27
+ in: 1..2,
28
+ message: "%{value} is invalid! Valid zones are 1..2."
29
+ }
30
+
31
+ validates :date_format, inclusion: {
32
+ in: DATE_FORMAT_MAP.keys,
33
+ message: "%{value} is invalid! Valid date formats are #{DATE_FORMAT_MAP.keys}."
34
+ }
35
+
14
36
  attr_accessor :zone, :is_24h, :date_format, :time
15
37
 
16
38
  # Create a Time instance.
17
39
  #
18
40
  # @param zone [Integer] Time zone number (1 or 2).
19
41
  # @param is_24h [Boolean] Toggle 24 hour time.
20
- # @param date_format [Integer] Date format.
42
+ # @param date_format ["%_m-%d-%y", "%_d-%m-%y", "%y-%m-%d", "%_m.%d.%y", "%_d.%m.%y", "%y.%m.%d"] Date format
43
+ # (represented by Time#strftime format).
21
44
  # @param time [::Time] Time to set (including time zone).
22
45
  # @param name [String, nil] Name of time zone (defaults to zone from time; 3 chars max)
23
46
  # @return [Time] Time instance.
@@ -31,8 +54,11 @@ class TimexDatalinkClient
31
54
 
32
55
  # Compile packets for a time.
33
56
  #
57
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
34
58
  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
35
59
  def packets
60
+ validate!
61
+
36
62
  [
37
63
  [
38
64
  CPACKET_TIME,
@@ -46,7 +72,7 @@ class TimexDatalinkClient
46
72
  name_characters,
47
73
  wday_from_monday,
48
74
  is_24h_value,
49
- date_format
75
+ date_format_value
50
76
  ].flatten
51
77
  ]
52
78
  end
@@ -72,6 +98,10 @@ class TimexDatalinkClient
72
98
  def is_24h_value
73
99
  is_24h ? 2 : 1
74
100
  end
101
+
102
+ def date_format_value
103
+ DATE_FORMAT_MAP.fetch(date_format)
104
+ end
75
105
  end
76
106
  end
77
107
  end
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/char_encoders"
4
6
  require "timex_datalink_client/helpers/crc_packets_wrapper"
5
7
 
6
8
  class TimexDatalinkClient
7
9
  class Protocol4
8
10
  class Alarm
11
+ include ActiveModel::Validations
9
12
  include Helpers::CharEncoders
10
13
  prepend Helpers::CrcPacketsWrapper
11
14
 
@@ -13,6 +16,11 @@ class TimexDatalinkClient
13
16
 
14
17
  attr_accessor :number, :audible, :time, :message
15
18
 
19
+ validates :number, inclusion: {
20
+ in: 1..5,
21
+ message: "value %{value} is invalid! Valid number values are 1..5."
22
+ }
23
+
16
24
  # Create an Alarm instance.
17
25
  #
18
26
  # @param number [Integer] Alarm number (from 1 to 5).
@@ -29,8 +37,11 @@ class TimexDatalinkClient
29
37
 
30
38
  # Compile packets for an alarm.
31
39
  #
40
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
32
41
  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
33
42
  def packets
43
+ validate!
44
+
34
45
  [
35
46
  [
36
47
  CPACKET_ALARM,
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/char_encoders"
4
6
  require "timex_datalink_client/helpers/length_packet_wrapper"
5
7
 
@@ -7,11 +9,18 @@ class TimexDatalinkClient
7
9
  class Protocol4
8
10
  class Eeprom
9
11
  class List
12
+ include ActiveModel::Validations
10
13
  include Helpers::CharEncoders
11
14
  prepend Helpers::LengthPacketWrapper
12
15
 
13
16
  attr_accessor :list_entry, :priority
14
17
 
18
+ validates :priority, inclusion: {
19
+ in: 1..5,
20
+ allow_nil: true,
21
+ message: "%{value} is invalid! Valid priorities are 1..5 or nil."
22
+ }
23
+
15
24
  # Create a List instance.
16
25
  #
17
26
  # @param list_entry [String] List entry text.
@@ -24,10 +33,13 @@ class TimexDatalinkClient
24
33
 
25
34
  # Compile a packet for a list.
26
35
  #
36
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
27
37
  # @return [Array<Integer>] Array of integers that represent bytes.
28
38
  def packet
39
+ validate!
40
+
29
41
  [
30
- priority,
42
+ priority_value,
31
43
  list_entry_characters
32
44
  ].flatten
33
45
  end
@@ -37,6 +49,10 @@ class TimexDatalinkClient
37
49
  def list_entry_characters
38
50
  eeprom_chars_for(list_entry)
39
51
  end
52
+
53
+ def priority_value
54
+ priority.nil? ? 0 : priority
55
+ end
40
56
  end
41
57
  end
42
58
  end
@@ -1,23 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/char_encoders"
4
6
  require "timex_datalink_client/helpers/crc_packets_wrapper"
5
7
 
6
8
  class TimexDatalinkClient
7
9
  class Protocol4
8
10
  class Time
11
+ include ActiveModel::Validations
9
12
  include Helpers::CharEncoders
10
13
  prepend Helpers::CrcPacketsWrapper
11
14
 
12
15
  CPACKET_TIME = [0x32]
13
16
 
17
+ DATE_FORMAT_MAP = {
18
+ "%_m-%d-%y" => 0,
19
+ "%_d-%m-%y" => 1,
20
+ "%y-%m-%d" => 2,
21
+ "%_m.%d.%y" => 4,
22
+ "%_d.%m.%y" => 5,
23
+ "%y.%m.%d" => 6
24
+ }.freeze
25
+
26
+ validates :zone, inclusion: {
27
+ in: 1..2,
28
+ message: "%{value} is invalid! Valid zones are 1..2."
29
+ }
30
+
31
+ validates :date_format, inclusion: {
32
+ in: DATE_FORMAT_MAP.keys,
33
+ message: "%{value} is invalid! Valid date formats are #{DATE_FORMAT_MAP.keys}."
34
+ }
35
+
14
36
  attr_accessor :zone, :is_24h, :date_format, :time
15
37
 
16
38
  # Create a Time instance.
17
39
  #
18
40
  # @param zone [Integer] Time zone number (1 or 2).
19
41
  # @param is_24h [Boolean] Toggle 24 hour time.
20
- # @param date_format [Integer] Date format.
42
+ # @param date_format ["%_m-%d-%y", "%_d-%m-%y", "%y-%m-%d", "%_m.%d.%y", "%_d.%m.%y", "%y.%m.%d"] Date format
43
+ # (represented by Time#strftime format).
21
44
  # @param time [::Time] Time to set (including time zone).
22
45
  # @param name [String, nil] Name of time zone (defaults to zone from time; 3 chars max)
23
46
  # @return [Time] Time instance.
@@ -31,8 +54,11 @@ class TimexDatalinkClient
31
54
 
32
55
  # Compile packets for a time.
33
56
  #
57
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
34
58
  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
35
59
  def packets
60
+ validate!
61
+
36
62
  [
37
63
  [
38
64
  CPACKET_TIME,
@@ -46,7 +72,7 @@ class TimexDatalinkClient
46
72
  name_characters,
47
73
  wday_from_monday,
48
74
  is_24h_value,
49
- date_format
75
+ date_format_value
50
76
  ].flatten
51
77
  ]
52
78
  end
@@ -72,6 +98,10 @@ class TimexDatalinkClient
72
98
  def is_24h_value
73
99
  is_24h ? 2 : 1
74
100
  end
101
+
102
+ def date_format_value
103
+ DATE_FORMAT_MAP.fetch(date_format)
104
+ end
75
105
  end
76
106
  end
77
107
  end
@@ -1,10 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "timex_datalink_client/helpers/lsb_msb_formatter"
4
+
3
5
  class TimexDatalinkClient
4
6
  class Protocol7
5
7
  class Eeprom
6
8
  class Calendar
7
9
  class Event
10
+ include Helpers::LsbMsbFormatter
11
+
8
12
  FIVE_MINUTES_SECONDS = 300
9
13
 
10
14
  attr_accessor :time, :phrase
@@ -24,7 +28,7 @@ class TimexDatalinkClient
24
28
  seconds = (time - device_time_midnight).to_i
25
29
  five_minutes = seconds / FIVE_MINUTES_SECONDS
26
30
 
27
- five_minutes.divmod(256).reverse
31
+ lsb_msb_format_for(five_minutes)
28
32
  end
29
33
  end
30
34
  end
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "timex_datalink_client/helpers/four_byte_formatter"
4
+ require "timex_datalink_client/helpers/lsb_msb_formatter"
4
5
 
5
6
  class TimexDatalinkClient
6
7
  class Protocol7
7
8
  class Eeprom
8
9
  class Calendar
9
10
  include Helpers::FourByteFormatter
11
+ include Helpers::LsbMsbFormatter
10
12
 
11
13
  DAY_START_TIME = Time.new(2000)
12
14
  DAY_SECONDS = 86400
@@ -48,7 +50,7 @@ class TimexDatalinkClient
48
50
  private
49
51
 
50
52
  def events_count
51
- events.count.divmod(256).reverse
53
+ lsb_msb_format_for(events.count)
52
54
  end
53
55
 
54
56
  def event_packets
@@ -57,7 +59,7 @@ class TimexDatalinkClient
57
59
 
58
60
  [].tap do |event_packets|
59
61
  events.each_with_index do |event, event_index|
60
- event_bytes_formatted = event_bytes.divmod(256).reverse
62
+ event_bytes_formatted = lsb_msb_format_for(event_bytes)
61
63
  event_time_formatted = event.time_formatted(time)
62
64
 
63
65
  event_packets << [event_time_formatted, event_bytes_formatted]
@@ -77,13 +79,13 @@ class TimexDatalinkClient
77
79
  since_start_time_seconds = time - DAY_START_TIME
78
80
  since_start_time_days = since_start_time_seconds.to_i / DAY_SECONDS
79
81
 
80
- since_start_time_days.divmod(256).reverse
82
+ lsb_msb_format_for(since_start_time_days)
81
83
  end
82
84
 
83
85
  def time_formatted
84
86
  five_mintes = (time.hour * 60 + time.min) / 5
85
87
 
86
- five_mintes.divmod(256).reverse
88
+ lsb_msb_format_for(five_mintes)
87
89
  end
88
90
  end
89
91
  end
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "timex_datalink_client/helpers/four_byte_formatter"
4
+ require "timex_datalink_client/helpers/lsb_msb_formatter"
4
5
 
5
6
  class TimexDatalinkClient
6
7
  class Protocol7
7
8
  class Eeprom
8
9
  class Games
9
10
  include Helpers::FourByteFormatter
11
+ include Helpers::LsbMsbFormatter
10
12
 
11
13
  COUNTDOWN_TIMER_SECONDS_DEFAULT = 60
12
14
 
@@ -85,11 +87,11 @@ class TimexDatalinkClient
85
87
  game ? 1 << game_index : 0
86
88
  end
87
89
 
88
- bitmask.divmod(256).reverse
90
+ lsb_msb_format_for(bitmask)
89
91
  end
90
92
 
91
93
  def countdown_timer_time
92
- (countdown_timer_seconds * 10).divmod(256).reverse
94
+ lsb_msb_format_for(countdown_timer_seconds * 10)
93
95
  end
94
96
 
95
97
  def sounds
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "timex_datalink_client/helpers/four_byte_formatter"
4
+ require "timex_datalink_client/helpers/lsb_msb_formatter"
4
5
 
5
6
  class TimexDatalinkClient
6
7
  class Protocol7
7
8
  class Eeprom
8
9
  class Speech
9
10
  include Helpers::FourByteFormatter
11
+ include Helpers::LsbMsbFormatter
10
12
 
11
13
  NICKNAME_LENGTH_WITHOUT_DEVICE = 10
12
14
  NICKNAME_LENGTH_WITH_DEVICE = 14
@@ -123,7 +125,7 @@ class TimexDatalinkClient
123
125
  def header
124
126
  all_values = [header_value_1, header_value_2, header_value_3] + header_values_4 + header_values_5
125
127
 
126
- all_values.flat_map { |value| value.divmod(256).reverse }
128
+ all_values.flat_map { |value| lsb_msb_format_for(value) }
127
129
  end
128
130
 
129
131
  def header_value_1
@@ -1,18 +1,63 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/char_encoders"
4
6
  require "timex_datalink_client/helpers/crc_packets_wrapper"
5
7
 
6
8
  class TimexDatalinkClient
7
9
  class Protocol9
8
10
  class Alarm
11
+ include ActiveModel::Validations
9
12
  include Helpers::CharEncoders
10
13
  prepend Helpers::CrcPacketsWrapper
11
14
 
12
15
  CPACKET_ALARM = [0x50]
13
16
 
17
+ VALID_DAYS_IN_MONTH = {
18
+ 1 => 1..31,
19
+ 2 => 1..29,
20
+ 3 => 1..31,
21
+ 4 => 1..30,
22
+ 5 => 1..31,
23
+ 6 => 1..30,
24
+ 7 => 1..31,
25
+ 8 => 1..31,
26
+ 9 => 1..30,
27
+ 10 => 1..31,
28
+ 11 => 1..30,
29
+ 12 => 1..31
30
+ }.freeze
31
+
14
32
  attr_accessor :number, :audible, :time, :message, :month, :day
15
33
 
34
+ validates :number, inclusion: {
35
+ in: 1..10,
36
+ message: "value %{value} is invalid! Valid number values are 1..10."
37
+ }
38
+
39
+ validates :month, inclusion: {
40
+ in: 1..12,
41
+ allow_nil: true,
42
+ message: "%{value} is invalid! Valid months are 1..12 and nil."
43
+ }
44
+
45
+ validates :day, inclusion: {
46
+ if: ->(alarm) { alarm.month.nil? },
47
+ in: 1..31,
48
+ allow_nil: true,
49
+ message: "%{value} is invalid! Valid days are 1..31 and nil."
50
+ }
51
+
52
+ validates :day, inclusion: {
53
+ if: ->(alarm) { alarm.day && alarm.month },
54
+ in: ->(alarm) { VALID_DAYS_IN_MONTH[alarm.month] },
55
+ message: ->(alarm, _attributes) do
56
+ "#{alarm.day} is invalid for month #{alarm.month}! " \
57
+ "Valid days are #{VALID_DAYS_IN_MONTH[alarm.month]} and nil when month is #{alarm.month}."
58
+ end
59
+ }
60
+
16
61
  # Create an Alarm instance.
17
62
  #
18
63
  # @param number [Integer] Alarm number (from 1 to 10).
@@ -33,8 +78,11 @@ class TimexDatalinkClient
33
78
 
34
79
  # Compile packets for an alarm.
35
80
  #
81
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
36
82
  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
37
83
  def packets
84
+ validate!
85
+
38
86
  [
39
87
  [
40
88
  CPACKET_ALARM,
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/char_encoders"
4
6
 
5
7
  class TimexDatalinkClient
6
8
  class Protocol9
7
9
  class Eeprom
8
10
  class Chrono
11
+ include ActiveModel::Validations
9
12
  include Helpers::CharEncoders
10
13
 
11
14
  CHRONO_LABEL_LENGTH = 8
@@ -13,6 +16,11 @@ class TimexDatalinkClient
13
16
 
14
17
  attr_accessor :label, :laps
15
18
 
19
+ validates :laps, inclusion: {
20
+ in: 2..50,
21
+ message: "value %{value} is invalid! Valid laps values are 2..50."
22
+ }
23
+
16
24
  # Create a Chrono instance.
17
25
  #
18
26
  # @param label [String] Label for chrono.
@@ -25,8 +33,11 @@ class TimexDatalinkClient
25
33
 
26
34
  # Compile a packet for a chrono.
27
35
  #
36
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
28
37
  # @return [Array<Integer>] Array of integers that represent bytes.
29
38
  def packet
39
+ validate!
40
+
30
41
  label_characters
31
42
  end
32
43
 
@@ -1,16 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/crc_packets_wrapper"
4
6
 
5
7
  class TimexDatalinkClient
6
8
  class Protocol9
7
9
  class Time
10
+ include ActiveModel::Validations
8
11
  prepend Helpers::CrcPacketsWrapper
9
12
 
10
13
  CPACKET_TIME = [0x30]
11
14
 
12
15
  attr_accessor :zone, :is_24h, :time
13
16
 
17
+ validates :zone, inclusion: {
18
+ in: 1..2,
19
+ message: "%{value} is invalid! Valid zones are 1..2."
20
+ }
21
+
14
22
  # Create a Time instance.
15
23
  #
16
24
  # @param zone [Integer] Time zone number (1 or 2).
@@ -25,8 +33,11 @@ class TimexDatalinkClient
25
33
 
26
34
  # Compile packets for a time.
27
35
  #
36
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
28
37
  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
29
38
  def packets
39
+ validate!
40
+
30
41
  [
31
42
  [
32
43
  CPACKET_TIME,
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_model"
4
+
3
5
  require "timex_datalink_client/helpers/char_encoders"
4
6
  require "timex_datalink_client/helpers/crc_packets_wrapper"
5
7
 
6
8
  class TimexDatalinkClient
7
9
  class Protocol9
8
10
  class TimeName
11
+ include ActiveModel::Validations
9
12
  include Helpers::CharEncoders
10
13
  prepend Helpers::CrcPacketsWrapper
11
14
 
@@ -13,6 +16,11 @@ class TimexDatalinkClient
13
16
 
14
17
  attr_accessor :zone, :name
15
18
 
19
+ validates :zone, inclusion: {
20
+ in: 1..2,
21
+ message: "%{value} is invalid! Valid zones are 1..2."
22
+ }
23
+
16
24
  # Create a TimeName instance.
17
25
  #
18
26
  # @param zone [Integer] Time zone number (1 or 2).
@@ -25,8 +33,11 @@ class TimexDatalinkClient
25
33
 
26
34
  # Compile packets for a time name.
27
35
  #
36
+ # @raise [ActiveModel::ValidationError] One or more model values are invalid.
28
37
  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
29
38
  def packets
39
+ validate!
40
+
30
41
  [
31
42
  [
32
43
  CPACKET_NAME,
@@ -11,6 +11,12 @@ class TimexDatalinkClient
11
11
 
12
12
  CPACKET_TIMER = [0x43]
13
13
 
14
+ ACTION_AT_END_MAP = {
15
+ stop_timer: 0,
16
+ repeat_timer: 1,
17
+ start_chrono: 2
18
+ }.freeze
19
+
14
20
  attr_accessor :number, :label, :time, :action_at_end
15
21
 
16
22
  # Create a Timer instance.
@@ -18,7 +24,7 @@ class TimexDatalinkClient
18
24
  # @param number [Integer] Entry number for timer.
19
25
  # @param label [String] Label for timer.
20
26
  # @param time [Time] Time of timer.
21
- # @param action_at_end [Integer] Action at end of timer.
27
+ # @param action_at_end [:stop_timer, :repeat_timer, :start_chrono] Action at end of timer.
22
28
  # @return [Timer] Timer instance.
23
29
  def initialize(number:, label:, time:, action_at_end:)
24
30
  @number = number
@@ -38,7 +44,7 @@ class TimexDatalinkClient
38
44
  time.hour,
39
45
  time.min,
40
46
  time.sec,
41
- action_at_end,
47
+ action_at_end_value,
42
48
  label_characters
43
49
  ].flatten
44
50
  ]
@@ -46,6 +52,10 @@ class TimexDatalinkClient
46
52
 
47
53
  private
48
54
 
55
+ def action_at_end_value
56
+ ACTION_AT_END_MAP.fetch(action_at_end)
57
+ end
58
+
49
59
  def label_characters
50
60
  chars_for(label, length: 8, pad: true)
51
61
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class TimexDatalinkClient
4
- VERSION = "0.8.0"
4
+ VERSION = "0.10.0"
5
5
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timex_datalink_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.10.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-12-13 00:00:00.000000000 Z
11
+ date: 2022-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: crc
14
+ name: activemodel
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.4.2
19
+ version: 7.0.4
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.4.2
26
+ version: 7.0.4
27
27
  - !ruby/object:Gem::Dependency
28
- name: rubyserial
28
+ name: crc
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.6.0
33
+ version: 0.4.2
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.6.0
40
+ version: 0.4.2
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: mdb
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.5.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubyserial
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.6.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.6.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rspec
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -106,6 +120,7 @@ files:
106
120
  - lib/timex_datalink_client/helpers/crc_packets_wrapper.rb
107
121
  - lib/timex_datalink_client/helpers/four_byte_formatter.rb
108
122
  - lib/timex_datalink_client/helpers/length_packet_wrapper.rb
123
+ - lib/timex_datalink_client/helpers/lsb_msb_formatter.rb
109
124
  - lib/timex_datalink_client/notebook_adapter.rb
110
125
  - lib/timex_datalink_client/protocol_1/alarm.rb
111
126
  - lib/timex_datalink_client/protocol_1/eeprom.rb
@@ -167,7 +182,7 @@ files:
167
182
  - lib/timex_datalink_client/protocol_9/time_name.rb
168
183
  - lib/timex_datalink_client/protocol_9/timer.rb
169
184
  - lib/timex_datalink_client/version.rb
170
- homepage: https://github.com/synthead/timex_datalink_client/tree/v0.8.0
185
+ homepage: https://github.com/synthead/timex_datalink_client/tree/v0.10.0
171
186
  licenses:
172
187
  - MIT
173
188
  metadata: {}