timex_datalink_client 0.4.1 → 0.5.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.
- checksums.yaml +4 -4
- data/lib/timex_datalink_client/helpers/cpacket_paginator.rb +2 -4
- data/lib/timex_datalink_client/protocol_1/alarm.rb +82 -0
- data/lib/timex_datalink_client/protocol_1/eeprom.rb +100 -0
- data/lib/timex_datalink_client/protocol_1/end.rb +10 -0
- data/lib/timex_datalink_client/protocol_1/start.rb +20 -0
- data/lib/timex_datalink_client/protocol_1/sync.rb +10 -0
- data/lib/timex_datalink_client/protocol_1/time.rb +61 -0
- data/lib/timex_datalink_client/protocol_1/time_name.rb +46 -0
- data/lib/timex_datalink_client/protocol_3/alarm.rb +59 -0
- data/lib/timex_datalink_client/protocol_3/eeprom.rb +95 -0
- data/lib/timex_datalink_client/protocol_3/end.rb +10 -0
- data/lib/timex_datalink_client/protocol_3/sound_options.rb +42 -0
- data/lib/timex_datalink_client/protocol_3/sound_theme.rb +65 -0
- data/lib/timex_datalink_client/protocol_3/start.rb +20 -0
- data/lib/timex_datalink_client/protocol_3/sync.rb +10 -0
- data/lib/timex_datalink_client/protocol_3/time.rb +77 -0
- data/lib/timex_datalink_client/protocol_3/wrist_app.rb +67 -0
- data/lib/timex_datalink_client/version.rb +1 -1
- data/lib/timex_datalink_client.rb +23 -12
- metadata +19 -10
- data/lib/timex_datalink_client/alarm.rb +0 -59
- data/lib/timex_datalink_client/eeprom.rb +0 -92
- data/lib/timex_datalink_client/sound_options.rb +0 -40
- data/lib/timex_datalink_client/sound_theme.rb +0 -62
- data/lib/timex_datalink_client/start.rb +0 -18
- data/lib/timex_datalink_client/time.rb +0 -75
- data/lib/timex_datalink_client/wrist_app.rb +0 -64
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 061a85e62bc26614e71a4fa43dc9c17cc6092a516a417d5545d7ecd029a34af6
         | 
| 4 | 
            +
              data.tar.gz: 4e3fc39203b45c38599c6980c72c42e6e05efdc87e7c7d5c9f4cc099e995d39e
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 40b7dbbfd0af7b4600b5d94623584615b193b2011b976ed229ee7ba084892ba05d31002150dd9decfafcaecb301d2fa44d1c9a5a03ecace2a20441edda50b6ca
         | 
| 7 | 
            +
              data.tar.gz: b902ecee9de6ebf920e86a08c57e9651730335492c1e05ccfe55d0169fbf7c714ac5ba02f8640983ea69bc5d34ae1269e8f1d97b9e36f4d3921e07cdea0f039c
         | 
| @@ -3,10 +3,8 @@ | |
| 3 3 | 
             
            class TimexDatalinkClient
         | 
| 4 4 | 
             
              class Helpers
         | 
| 5 5 | 
             
                module CpacketPaginator
         | 
| 6 | 
            -
                   | 
| 7 | 
            -
             | 
| 8 | 
            -
                  def paginate_cpackets(header:, cpackets:)
         | 
| 9 | 
            -
                    paginated_cpackets = cpackets.each_slice(ITEMS_PER_PACKET)
         | 
| 6 | 
            +
                  def paginate_cpackets(header:, length:, cpackets:)
         | 
| 7 | 
            +
                    paginated_cpackets = cpackets.each_slice(length)
         | 
| 10 8 |  | 
| 11 9 | 
             
                    paginated_cpackets.map.with_index(1) do |paginated_cpacket, index|
         | 
| 12 10 | 
             
                      header + [index] + paginated_cpacket
         | 
| @@ -0,0 +1,82 @@ | |
| 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 Protocol1
         | 
| 8 | 
            +
                class Alarm
         | 
| 9 | 
            +
                  include Helpers::CharEncoders
         | 
| 10 | 
            +
                  prepend Helpers::CrcPacketsWrapper
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  CPACKET_ALARM = [0x50]
         | 
| 13 | 
            +
                  CPACKET_ALARM_SILENT = [0x70, 0x00]
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  ALARM_SILENT_START_INDEX = 0x61
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  attr_accessor :number, :audible, :time, :message, :month, :day
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  # Create an Alarm instance.
         | 
| 20 | 
            +
                  #
         | 
| 21 | 
            +
                  # @param number [Integer] Alarm number (from 1 to 5).
         | 
| 22 | 
            +
                  # @param audible [Boolean] Toggle alarm sounds.
         | 
| 23 | 
            +
                  # @param time [::Time] Time of alarm.
         | 
| 24 | 
            +
                  # @param message [String] Alarm message text.
         | 
| 25 | 
            +
                  # @param month [Integer, nil] Month of alarm.
         | 
| 26 | 
            +
                  # @param day [Integer, nil] Day of alarm.
         | 
| 27 | 
            +
                  # @return [Alarm] Alarm instance.
         | 
| 28 | 
            +
                  def initialize(number:, audible:, time:, message:, month: nil, day: nil)
         | 
| 29 | 
            +
                    @number = number
         | 
| 30 | 
            +
                    @audible = audible
         | 
| 31 | 
            +
                    @time = time
         | 
| 32 | 
            +
                    @message = message
         | 
| 33 | 
            +
                    @month = month
         | 
| 34 | 
            +
                    @day = day
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  # Compile packets for an alarm.
         | 
| 38 | 
            +
                  #
         | 
| 39 | 
            +
                  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
         | 
| 40 | 
            +
                  def packets
         | 
| 41 | 
            +
                    [alarm_data_packet].tap do |packets|
         | 
| 42 | 
            +
                      packets << alarm_silent_packet unless audible
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  private
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  def alarm_data_packet
         | 
| 49 | 
            +
                    [
         | 
| 50 | 
            +
                      CPACKET_ALARM,
         | 
| 51 | 
            +
                      number,
         | 
| 52 | 
            +
                      time.hour,
         | 
| 53 | 
            +
                      time.min,
         | 
| 54 | 
            +
                      month.to_i,
         | 
| 55 | 
            +
                      day.to_i,
         | 
| 56 | 
            +
                      message_characters,
         | 
| 57 | 
            +
                      audible_integer
         | 
| 58 | 
            +
                    ].flatten
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  def alarm_silent_packet
         | 
| 62 | 
            +
                    [
         | 
| 63 | 
            +
                      CPACKET_ALARM_SILENT,
         | 
| 64 | 
            +
                      alarm_silent_index,
         | 
| 65 | 
            +
                      0
         | 
| 66 | 
            +
                    ].flatten
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  def message_characters
         | 
| 70 | 
            +
                    chars_for(message, length: 8, pad: true)
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  def audible_integer
         | 
| 74 | 
            +
                    audible ? 1 : 0
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  def alarm_silent_index
         | 
| 78 | 
            +
                    ALARM_SILENT_START_INDEX + number
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
            end
         | 
| @@ -0,0 +1,100 @@ | |
| 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 Protocol1
         | 
| 8 | 
            +
                class Eeprom
         | 
| 9 | 
            +
                  include Helpers::CpacketPaginator
         | 
| 10 | 
            +
                  prepend Helpers::CrcPacketsWrapper
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  CPACKET_SECT = [0x60]
         | 
| 13 | 
            +
                  CPACKET_DATA = [0x61]
         | 
| 14 | 
            +
                  CPACKET_END = [0x62]
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  CPACKET_DATA_LENGTH = 27
         | 
| 17 | 
            +
                  START_INDEX = 14
         | 
| 18 | 
            +
                  APPOINTMENT_NO_NOTIFICATION = 0xff
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  attr_accessor :appointments, :anniversaries, :phone_numbers, :lists, :appointment_notification
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  # Create an Eeprom instance.
         | 
| 23 | 
            +
                  #
         | 
| 24 | 
            +
                  # @param appointments [Array<Appointment>] Appointments to be added to EEPROM data.
         | 
| 25 | 
            +
                  # @param anniversaries [Array<Anniversary>] Anniversaries to be added to EEPROM data.
         | 
| 26 | 
            +
                  # @param phone_numbers [Array<PhoneNumber>] Phone numbers to be added to EEPROM data.
         | 
| 27 | 
            +
                  # @param lists [Array<List>] Lists to be added to EEPROM data.
         | 
| 28 | 
            +
                  # @param appointment_notification [Integer] Appointment notification (intervals of 15 minutes, 255 for no
         | 
| 29 | 
            +
                  #   notification)
         | 
| 30 | 
            +
                  # @return [Eeprom] Eeprom instance.
         | 
| 31 | 
            +
                  def initialize(appointments: [], anniversaries: [], phone_numbers: [], lists: [], appointment_notification: APPOINTMENT_NO_NOTIFICATION)
         | 
| 32 | 
            +
                    @appointments = appointments
         | 
| 33 | 
            +
                    @anniversaries = anniversaries
         | 
| 34 | 
            +
                    @phone_numbers = phone_numbers
         | 
| 35 | 
            +
                    @lists = lists
         | 
| 36 | 
            +
                    @appointment_notification = appointment_notification
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  # Compile packets for EEPROM data.
         | 
| 40 | 
            +
                  #
         | 
| 41 | 
            +
                  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
         | 
| 42 | 
            +
                  def packets
         | 
| 43 | 
            +
                    [header] + payloads + [CPACKET_END]
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  private
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  def header
         | 
| 49 | 
            +
                    [
         | 
| 50 | 
            +
                      CPACKET_SECT,
         | 
| 51 | 
            +
                      payloads.length
         | 
| 52 | 
            +
                    ].flatten
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  def payload
         | 
| 56 | 
            +
                    [
         | 
| 57 | 
            +
                      items_indexes,
         | 
| 58 | 
            +
                      items_lengths,
         | 
| 59 | 
            +
                      earliest_appointment_year,
         | 
| 60 | 
            +
                      appointment_notification,
         | 
| 61 | 
            +
                      all_packets
         | 
| 62 | 
            +
                    ].flatten
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  def payloads
         | 
| 66 | 
            +
                    paginate_cpackets(header: CPACKET_DATA, length: CPACKET_DATA_LENGTH, cpackets: payload)
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  def all_items
         | 
| 70 | 
            +
                    [appointments, lists, phone_numbers, anniversaries]
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  def all_packets
         | 
| 74 | 
            +
                    all_items.flatten.map(&:packet).flatten
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  def items_indexes
         | 
| 78 | 
            +
                    index = START_INDEX
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                    all_items.each_with_object([]) do |items, indexes|
         | 
| 81 | 
            +
                      indexes.concat(index.divmod(256))
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                      index += items.sum { |item| item.packet.length }
         | 
| 84 | 
            +
                    end
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  def items_lengths
         | 
| 88 | 
            +
                    all_items.map(&:length)
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                  def earliest_appointment_year
         | 
| 92 | 
            +
                    earliest_appointment = appointments.min_by(&:time)
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                    return 0 unless earliest_appointment
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                    earliest_appointment.time.year % 100
         | 
| 97 | 
            +
                  end
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
              end
         | 
| 100 | 
            +
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "timex_datalink_client/helpers/crc_packets_wrapper"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class TimexDatalinkClient
         | 
| 6 | 
            +
              class Protocol1
         | 
| 7 | 
            +
                class Start
         | 
| 8 | 
            +
                  prepend Helpers::CrcPacketsWrapper
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  CPACKET_START = [0x20, 0x00, 0x00, 0x01]
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  # Compile packets for data start command.
         | 
| 13 | 
            +
                  #
         | 
| 14 | 
            +
                  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
         | 
| 15 | 
            +
                  def packets
         | 
| 16 | 
            +
                    [CPACKET_START]
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
| @@ -0,0 +1,61 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "timex_datalink_client/helpers/crc_packets_wrapper"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class TimexDatalinkClient
         | 
| 6 | 
            +
              class Protocol1
         | 
| 7 | 
            +
                class Time
         | 
| 8 | 
            +
                  prepend Helpers::CrcPacketsWrapper
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  CPACKET_TIME = [0x30]
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  attr_accessor :zone, :is_24h, :time
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  # Create a Time instance.
         | 
| 15 | 
            +
                  #
         | 
| 16 | 
            +
                  # @param zone [Integer] Time zone number (1 or 2).
         | 
| 17 | 
            +
                  # @param is_24h [Boolean] Toggle 24 hour time.
         | 
| 18 | 
            +
                  # @param time [::Time] Time to set.
         | 
| 19 | 
            +
                  # @return [Time] Time instance.
         | 
| 20 | 
            +
                  def initialize(zone:, is_24h:, time:)
         | 
| 21 | 
            +
                    @zone = zone
         | 
| 22 | 
            +
                    @is_24h = is_24h
         | 
| 23 | 
            +
                    @time = time
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  # Compile packets for a time.
         | 
| 27 | 
            +
                  #
         | 
| 28 | 
            +
                  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
         | 
| 29 | 
            +
                  def packets
         | 
| 30 | 
            +
                    [
         | 
| 31 | 
            +
                      [
         | 
| 32 | 
            +
                        CPACKET_TIME,
         | 
| 33 | 
            +
                        zone,
         | 
| 34 | 
            +
                        time.hour,
         | 
| 35 | 
            +
                        time.min,
         | 
| 36 | 
            +
                        time.month,
         | 
| 37 | 
            +
                        time.day,
         | 
| 38 | 
            +
                        year_mod_1900,
         | 
| 39 | 
            +
                        wday_from_monday,
         | 
| 40 | 
            +
                        time.sec,
         | 
| 41 | 
            +
                        is_24h_value
         | 
| 42 | 
            +
                      ].flatten
         | 
| 43 | 
            +
                    ]
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  private
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  def year_mod_1900
         | 
| 49 | 
            +
                    time.year % 100
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  def wday_from_monday
         | 
| 53 | 
            +
                    (time.wday + 6) % 7
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  def is_24h_value
         | 
| 57 | 
            +
                    is_24h ? 2 : 1
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
            end
         | 
| @@ -0,0 +1,46 @@ | |
| 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 Protocol1
         | 
| 8 | 
            +
                class TimeName
         | 
| 9 | 
            +
                  include Helpers::CharEncoders
         | 
| 10 | 
            +
                  prepend Helpers::CrcPacketsWrapper
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  CPACKET_NAME = [0x31]
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  attr_accessor :zone, :name
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  # Create a TimeName instance.
         | 
| 17 | 
            +
                  #
         | 
| 18 | 
            +
                  # @param zone [Integer] Time zone number (1 or 2).
         | 
| 19 | 
            +
                  # @param name [String] Name of time zone (3 chars max)
         | 
| 20 | 
            +
                  # @return [TimeName] TimeName instance.
         | 
| 21 | 
            +
                  def initialize(zone:, name:)
         | 
| 22 | 
            +
                    @zone = zone
         | 
| 23 | 
            +
                    @name = name
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  # Compile packets for a time name.
         | 
| 27 | 
            +
                  #
         | 
| 28 | 
            +
                  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
         | 
| 29 | 
            +
                  def packets
         | 
| 30 | 
            +
                    [
         | 
| 31 | 
            +
                      [
         | 
| 32 | 
            +
                        CPACKET_NAME,
         | 
| 33 | 
            +
                        zone,
         | 
| 34 | 
            +
                        name_characters
         | 
| 35 | 
            +
                      ].flatten
         | 
| 36 | 
            +
                    ]
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  private
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  def name_characters
         | 
| 42 | 
            +
                    chars_for(name, length: 3, pad: true)
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
            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 Protocol3
         | 
| 8 | 
            +
                class Alarm
         | 
| 9 | 
            +
                  include Helpers::CharEncoders
         | 
| 10 | 
            +
                  prepend Helpers::CrcPacketsWrapper
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  CPACKET_ALARM = [0x50]
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  attr_accessor :number, :audible, :time, :message
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  # Create an Alarm instance.
         | 
| 17 | 
            +
                  #
         | 
| 18 | 
            +
                  # @param number [Integer] Alarm number (from 1 to 5).
         | 
| 19 | 
            +
                  # @param audible [Boolean] Toggle alarm sounds.
         | 
| 20 | 
            +
                  # @param time [::Time] Time of alarm.
         | 
| 21 | 
            +
                  # @param message [String] Alarm message text.
         | 
| 22 | 
            +
                  # @return [Alarm] Alarm instance.
         | 
| 23 | 
            +
                  def initialize(number:, audible:, time:, message:)
         | 
| 24 | 
            +
                    @number = number
         | 
| 25 | 
            +
                    @audible = audible
         | 
| 26 | 
            +
                    @time = time
         | 
| 27 | 
            +
                    @message = message
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  # Compile packets for an alarm.
         | 
| 31 | 
            +
                  #
         | 
| 32 | 
            +
                  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
         | 
| 33 | 
            +
                  def packets
         | 
| 34 | 
            +
                    [
         | 
| 35 | 
            +
                      [
         | 
| 36 | 
            +
                        CPACKET_ALARM,
         | 
| 37 | 
            +
                        number,
         | 
| 38 | 
            +
                        time.hour,
         | 
| 39 | 
            +
                        time.min,
         | 
| 40 | 
            +
                        0,
         | 
| 41 | 
            +
                        0,
         | 
| 42 | 
            +
                        message_characters,
         | 
| 43 | 
            +
                        audible_integer
         | 
| 44 | 
            +
                      ].flatten
         | 
| 45 | 
            +
                    ]
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  private
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  def message_characters
         | 
| 51 | 
            +
                    chars_for(message, length: 8, pad: true)
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  def audible_integer
         | 
| 55 | 
            +
                    audible ? 1 : 0
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
            end
         | 
| @@ -0,0 +1,95 @@ | |
| 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 Protocol3
         | 
| 8 | 
            +
                class Eeprom
         | 
| 9 | 
            +
                  include Helpers::CpacketPaginator
         | 
| 10 | 
            +
                  prepend Helpers::CrcPacketsWrapper
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  CPACKET_CLEAR = [0x93, 0x01]
         | 
| 13 | 
            +
                  CPACKET_SECT = [0x90, 0x01]
         | 
| 14 | 
            +
                  CPACKET_DATA = [0x91, 0x01]
         | 
| 15 | 
            +
                  CPACKET_END = [0x92, 0x01]
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  CPACKET_DATA_LENGTH = 32
         | 
| 18 | 
            +
                  START_ADDRESS = 0x0236
         | 
| 19 | 
            +
                  APPOINTMENT_NO_NOTIFICATION = 0xff
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  attr_accessor :appointments, :anniversaries, :phone_numbers, :lists, :appointment_notification
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  # Create an Eeprom instance.
         | 
| 24 | 
            +
                  #
         | 
| 25 | 
            +
                  # @param appointments [Array<Appointment>] Appointments to be added to EEPROM data.
         | 
| 26 | 
            +
                  # @param anniversaries [Array<Anniversary>] Anniversaries to be added to EEPROM data.
         | 
| 27 | 
            +
                  # @param phone_numbers [Array<PhoneNumber>] Phone numbers to be added to EEPROM data.
         | 
| 28 | 
            +
                  # @param lists [Array<List>] Lists to be added to EEPROM data.
         | 
| 29 | 
            +
                  # @param appointment_notification [Integer] Appointment notification (intervals of 15 minutes, 255 for no
         | 
| 30 | 
            +
                  #   notification)
         | 
| 31 | 
            +
                  # @return [Eeprom] Eeprom instance.
         | 
| 32 | 
            +
                  def initialize(appointments: [], anniversaries: [], phone_numbers: [], lists: [], appointment_notification: APPOINTMENT_NO_NOTIFICATION)
         | 
| 33 | 
            +
                    @appointments = appointments
         | 
| 34 | 
            +
                    @anniversaries = anniversaries
         | 
| 35 | 
            +
                    @phone_numbers = phone_numbers
         | 
| 36 | 
            +
                    @lists = lists
         | 
| 37 | 
            +
                    @appointment_notification = appointment_notification
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  # Compile packets for EEPROM data.
         | 
| 41 | 
            +
                  #
         | 
| 42 | 
            +
                  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
         | 
| 43 | 
            +
                  def packets
         | 
| 44 | 
            +
                    [CPACKET_CLEAR, header] + payloads + [CPACKET_END]
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  private
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  def header
         | 
| 50 | 
            +
                    [
         | 
| 51 | 
            +
                      CPACKET_SECT,
         | 
| 52 | 
            +
                      payloads.length,
         | 
| 53 | 
            +
                      items_addresses,
         | 
| 54 | 
            +
                      items_lengths,
         | 
| 55 | 
            +
                      earliest_appointment_year,
         | 
| 56 | 
            +
                      appointment_notification
         | 
| 57 | 
            +
                    ].flatten
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  def payloads
         | 
| 61 | 
            +
                    paginate_cpackets(header: CPACKET_DATA, length: CPACKET_DATA_LENGTH, cpackets: all_packets)
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  def all_items
         | 
| 65 | 
            +
                    [appointments, lists, phone_numbers, anniversaries]
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  def all_packets
         | 
| 69 | 
            +
                    all_items.flatten.map(&:packet).flatten
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  def items_addresses
         | 
| 73 | 
            +
                    address = START_ADDRESS
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                    all_items.each_with_object([]) do |items, addresses|
         | 
| 76 | 
            +
                      addresses.concat(address.divmod(256))
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                      address += items.sum { |item| item.packet.length }
         | 
| 79 | 
            +
                    end
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  def items_lengths
         | 
| 83 | 
            +
                    all_items.map(&:length)
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                  def earliest_appointment_year
         | 
| 87 | 
            +
                    earliest_appointment = appointments.min_by(&:time)
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                    return 0 unless earliest_appointment
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                    earliest_appointment.time.year % 100
         | 
| 92 | 
            +
                  end
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
              end
         | 
| 95 | 
            +
            end
         | 
| @@ -0,0 +1,42 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "timex_datalink_client/helpers/crc_packets_wrapper"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class TimexDatalinkClient
         | 
| 6 | 
            +
              class Protocol3
         | 
| 7 | 
            +
                class SoundOptions
         | 
| 8 | 
            +
                  prepend Helpers::CrcPacketsWrapper
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  CPACKET_BEEPS = [0x71]
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  attr_accessor :hourly_chime, :button_beep
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  # Create a SoundOptions instance.
         | 
| 15 | 
            +
                  #
         | 
| 16 | 
            +
                  # @param hourly_chime [Boolean] Toggle hourly chime sounds.
         | 
| 17 | 
            +
                  # @param button_beep [Boolean] Toggle button beep sounds.
         | 
| 18 | 
            +
                  # @return [SoundOptions] SoundOptions instance.
         | 
| 19 | 
            +
                  def initialize(hourly_chime:, button_beep:)
         | 
| 20 | 
            +
                    @hourly_chime = hourly_chime
         | 
| 21 | 
            +
                    @button_beep = button_beep
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  # Compile packets for sound options.
         | 
| 25 | 
            +
                  #
         | 
| 26 | 
            +
                  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
         | 
| 27 | 
            +
                  def packets
         | 
| 28 | 
            +
                    [
         | 
| 29 | 
            +
                      CPACKET_BEEPS + [hourly_chime_integer, button_beep_integer]
         | 
| 30 | 
            +
                    ]
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  def hourly_chime_integer
         | 
| 34 | 
            +
                    hourly_chime ? 1 : 0
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  def button_beep_integer
         | 
| 38 | 
            +
                    button_beep ? 1 : 0
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
            end
         | 
| @@ -0,0 +1,65 @@ | |
| 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 Protocol3
         | 
| 8 | 
            +
                class SoundTheme
         | 
| 9 | 
            +
                  include Helpers::CpacketPaginator
         | 
| 10 | 
            +
                  prepend Helpers::CrcPacketsWrapper
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  CPACKET_SECT = [0x90, 0x03]
         | 
| 13 | 
            +
                  CPACKET_DATA = [0x91, 0x03]
         | 
| 14 | 
            +
                  CPACKET_END = [0x92, 0x03]
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  CPACKET_DATA_LENGTH = 32
         | 
| 17 | 
            +
                  SOUND_DATA_HEADER = "\x25\x04\x19\x69"
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  attr_accessor :spc_file
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  # Create a SoundTheme instance.
         | 
| 22 | 
            +
                  #
         | 
| 23 | 
            +
                  # @param sound_theme_data [String, nil] Sound theme data.
         | 
| 24 | 
            +
                  # @param spc_file [String, nil] Path to SPC file.
         | 
| 25 | 
            +
                  # @return [SoundTheme] SoundTheme instance.
         | 
| 26 | 
            +
                  def initialize(sound_theme_data: nil, spc_file: nil)
         | 
| 27 | 
            +
                    @sound_theme_data = sound_theme_data
         | 
| 28 | 
            +
                    @spc_file = spc_file
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  # Compile packets for a sound theme.
         | 
| 32 | 
            +
                  #
         | 
| 33 | 
            +
                  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
         | 
| 34 | 
            +
                  def packets
         | 
| 35 | 
            +
                    [load_sect] + payloads + [CPACKET_END]
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  private
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  def load_sect
         | 
| 41 | 
            +
                    CPACKET_SECT + [payloads.length, offset]
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  def payloads
         | 
| 45 | 
            +
                    paginate_cpackets(header: CPACKET_DATA, length: CPACKET_DATA_LENGTH, cpackets: sound_theme_data.bytes)
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  def sound_theme_data
         | 
| 49 | 
            +
                    @sound_theme_data || spc_file_data_without_header
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  def spc_file_data
         | 
| 53 | 
            +
                    File.open(spc_file, "rb").read
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  def spc_file_data_without_header
         | 
| 57 | 
            +
                    spc_file_data.delete_prefix(SOUND_DATA_HEADER)
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  def offset
         | 
| 61 | 
            +
                    0x100 - sound_theme_data.bytesize
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "timex_datalink_client/helpers/crc_packets_wrapper"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class TimexDatalinkClient
         | 
| 6 | 
            +
              class Protocol3
         | 
| 7 | 
            +
                class Start
         | 
| 8 | 
            +
                  prepend Helpers::CrcPacketsWrapper
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  CPACKET_START = [0x20, 0x00, 0x00, 0x03]
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  # Compile packets for data start command.
         | 
| 13 | 
            +
                  #
         | 
| 14 | 
            +
                  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
         | 
| 15 | 
            +
                  def packets
         | 
| 16 | 
            +
                    [CPACKET_START]
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
| @@ -0,0 +1,77 @@ | |
| 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 Protocol3
         | 
| 8 | 
            +
                class Time
         | 
| 9 | 
            +
                  include Helpers::CharEncoders
         | 
| 10 | 
            +
                  prepend Helpers::CrcPacketsWrapper
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  CPACKET_TIME = [0x32]
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  attr_accessor :zone, :is_24h, :date_format, :time
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  # Create a Time instance.
         | 
| 17 | 
            +
                  #
         | 
| 18 | 
            +
                  # @param zone [Integer] Time zone number (1 or 2).
         | 
| 19 | 
            +
                  # @param is_24h [Boolean] Toggle 24 hour time.
         | 
| 20 | 
            +
                  # @param date_format [Integer] Date format.
         | 
| 21 | 
            +
                  # @param time [::Time] Time to set (including time zone).
         | 
| 22 | 
            +
                  # @param name [String, nil] Name of time zone (defaults to zone from time; 3 chars max)
         | 
| 23 | 
            +
                  # @return [Time] Time instance.
         | 
| 24 | 
            +
                  def initialize(zone:, is_24h:, date_format:, time:, name: nil)
         | 
| 25 | 
            +
                    @zone = zone
         | 
| 26 | 
            +
                    @is_24h = is_24h
         | 
| 27 | 
            +
                    @date_format = date_format
         | 
| 28 | 
            +
                    @time = time
         | 
| 29 | 
            +
                    @name = name
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  # Compile packets for a time.
         | 
| 33 | 
            +
                  #
         | 
| 34 | 
            +
                  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
         | 
| 35 | 
            +
                  def packets
         | 
| 36 | 
            +
                    [
         | 
| 37 | 
            +
                      [
         | 
| 38 | 
            +
                        CPACKET_TIME,
         | 
| 39 | 
            +
                        zone,
         | 
| 40 | 
            +
                        time.sec,
         | 
| 41 | 
            +
                        time.hour,
         | 
| 42 | 
            +
                        time.min,
         | 
| 43 | 
            +
                        time.month,
         | 
| 44 | 
            +
                        time.day,
         | 
| 45 | 
            +
                        year_mod_1900,
         | 
| 46 | 
            +
                        name_characters,
         | 
| 47 | 
            +
                        wday_from_monday,
         | 
| 48 | 
            +
                        is_24h_value,
         | 
| 49 | 
            +
                        date_format
         | 
| 50 | 
            +
                      ].flatten
         | 
| 51 | 
            +
                    ]
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  private
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  def name
         | 
| 57 | 
            +
                    @name || time.zone.downcase
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  def name_characters
         | 
| 61 | 
            +
                    chars_for(name, length: 3, pad: true)
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  def year_mod_1900
         | 
| 65 | 
            +
                    time.year % 100
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  def wday_from_monday
         | 
| 69 | 
            +
                    (time.wday + 6) % 7
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  def is_24h_value
         | 
| 73 | 
            +
                    is_24h ? 2 : 1
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
            end
         | 
| @@ -0,0 +1,67 @@ | |
| 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 Protocol3
         | 
| 8 | 
            +
                class WristApp
         | 
| 9 | 
            +
                  include Helpers::CpacketPaginator
         | 
| 10 | 
            +
                  prepend Helpers::CrcPacketsWrapper
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  CPACKET_CLEAR = [0x93, 0x02]
         | 
| 13 | 
            +
                  CPACKET_SECT = [0x90, 0x02]
         | 
| 14 | 
            +
                  CPACKET_DATA = [0x91, 0x02]
         | 
| 15 | 
            +
                  CPACKET_END = [0x92, 0x02]
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  CPACKET_DATA_LENGTH = 32
         | 
| 18 | 
            +
                  WRIST_APP_DELIMITER = /\xac.*\r\n/n
         | 
| 19 | 
            +
                  WRIST_APP_CODE_INDEX = 8
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  attr_accessor :zap_file
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  # Create a WristApp instance.
         | 
| 24 | 
            +
                  #
         | 
| 25 | 
            +
                  # @param wrist_app_data [String, nil] WristApp data.
         | 
| 26 | 
            +
                  # @param zap_file [String, nil] Path to ZAP file.
         | 
| 27 | 
            +
                  # @return [WristApp] WristApp instance.
         | 
| 28 | 
            +
                  def initialize(wrist_app_data: nil, zap_file: nil)
         | 
| 29 | 
            +
                    @wrist_app_data = wrist_app_data
         | 
| 30 | 
            +
                    @zap_file = zap_file
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  # Compile packets for an alarm.
         | 
| 34 | 
            +
                  #
         | 
| 35 | 
            +
                  # @return [Array<Array<Integer>>] Two-dimensional array of integers that represent bytes.
         | 
| 36 | 
            +
                  def packets
         | 
| 37 | 
            +
                    [CPACKET_CLEAR, cpacket_sect] + payloads + [CPACKET_END]
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  private
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  def cpacket_sect
         | 
| 43 | 
            +
                    CPACKET_SECT + [payloads.length, 1]
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  def payloads
         | 
| 47 | 
            +
                    paginate_cpackets(header: CPACKET_DATA, length: CPACKET_DATA_LENGTH, cpackets: wrist_app_data.bytes)
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  def wrist_app_data
         | 
| 51 | 
            +
                    @wrist_app_data || zap_file_data_binary
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  def zap_file_data
         | 
| 55 | 
            +
                    File.open(zap_file, "rb").read
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  def zap_file_data_ascii
         | 
| 59 | 
            +
                    zap_file_data.split(WRIST_APP_DELIMITER)[WRIST_APP_CODE_INDEX]
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                  def zap_file_data_binary
         | 
| 63 | 
            +
                    [zap_file_data_ascii].pack("H*")
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
            end
         | 
| @@ -1,20 +1,30 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require "timex_datalink_client/ | 
| 4 | 
            -
            require "timex_datalink_client/ | 
| 3 | 
            +
            require "timex_datalink_client/version"
         | 
| 4 | 
            +
            require "timex_datalink_client/notebook_adapter"
         | 
| 5 | 
            +
             | 
| 5 6 | 
             
            require "timex_datalink_client/eeprom/anniversary"
         | 
| 6 7 | 
             
            require "timex_datalink_client/eeprom/appointment"
         | 
| 7 8 | 
             
            require "timex_datalink_client/eeprom/list"
         | 
| 8 9 | 
             
            require "timex_datalink_client/eeprom/phone_number"
         | 
| 9 | 
            -
             | 
| 10 | 
            -
            require "timex_datalink_client/ | 
| 11 | 
            -
            require "timex_datalink_client/ | 
| 12 | 
            -
            require "timex_datalink_client/ | 
| 13 | 
            -
            require "timex_datalink_client/start"
         | 
| 14 | 
            -
            require "timex_datalink_client/sync"
         | 
| 15 | 
            -
            require "timex_datalink_client/time"
         | 
| 16 | 
            -
            require "timex_datalink_client/ | 
| 17 | 
            -
             | 
| 10 | 
            +
             | 
| 11 | 
            +
            require "timex_datalink_client/protocol_1/alarm"
         | 
| 12 | 
            +
            require "timex_datalink_client/protocol_1/eeprom"
         | 
| 13 | 
            +
            require "timex_datalink_client/protocol_1/end"
         | 
| 14 | 
            +
            require "timex_datalink_client/protocol_1/start"
         | 
| 15 | 
            +
            require "timex_datalink_client/protocol_1/sync"
         | 
| 16 | 
            +
            require "timex_datalink_client/protocol_1/time"
         | 
| 17 | 
            +
            require "timex_datalink_client/protocol_1/time_name"
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            require "timex_datalink_client/protocol_3/alarm"
         | 
| 20 | 
            +
            require "timex_datalink_client/protocol_3/eeprom"
         | 
| 21 | 
            +
            require "timex_datalink_client/protocol_3/end"
         | 
| 22 | 
            +
            require "timex_datalink_client/protocol_3/sound_options"
         | 
| 23 | 
            +
            require "timex_datalink_client/protocol_3/sound_theme"
         | 
| 24 | 
            +
            require "timex_datalink_client/protocol_3/start"
         | 
| 25 | 
            +
            require "timex_datalink_client/protocol_3/sync"
         | 
| 26 | 
            +
            require "timex_datalink_client/protocol_3/time"
         | 
| 27 | 
            +
            require "timex_datalink_client/protocol_3/wrist_app"
         | 
| 18 28 |  | 
| 19 29 | 
             
            class TimexDatalinkClient
         | 
| 20 30 | 
             
              attr_accessor :serial_device, :models, :byte_sleep, :packet_sleep, :verbose
         | 
| @@ -22,7 +32,8 @@ class TimexDatalinkClient | |
| 22 32 | 
             
              # Create a TimexDatalinkClient instance.
         | 
| 23 33 | 
             
              #
         | 
| 24 34 | 
             
              # @param serial_device [String] Path to serial device.
         | 
| 25 | 
            -
              # @param models [Array<Alarm, Eeprom, End, SoundOptions, | 
| 35 | 
            +
              # @param models [Array<Protocol3::Alarm, Protocol3::Eeprom, Protocol3::End, Protocol3::SoundOptions,
         | 
| 36 | 
            +
              #   Protocol3::SoundTheme, Protocol3::Start, Protocol3::Sync, Protocol3::Time, Protocol3::WristApp>] Models to compile
         | 
| 26 37 | 
             
              #   data for.
         | 
| 27 38 | 
             
              # @param byte_sleep [Integer, nil] Time to sleep after sending byte.
         | 
| 28 39 | 
             
              # @param packet_sleep [Integer, nil] Time to sleep after sending packet of bytes.
         | 
    
        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. | 
| 4 | 
            +
              version: 0.5.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-09- | 
| 11 | 
            +
            date: 2022-09-12 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: crc
         | 
| @@ -87,8 +87,6 @@ extensions: [] | |
| 87 87 | 
             
            extra_rdoc_files: []
         | 
| 88 88 | 
             
            files:
         | 
| 89 89 | 
             
            - lib/timex_datalink_client.rb
         | 
| 90 | 
            -
            - lib/timex_datalink_client/alarm.rb
         | 
| 91 | 
            -
            - lib/timex_datalink_client/eeprom.rb
         | 
| 92 90 | 
             
            - lib/timex_datalink_client/eeprom/anniversary.rb
         | 
| 93 91 | 
             
            - lib/timex_datalink_client/eeprom/appointment.rb
         | 
| 94 92 | 
             
            - lib/timex_datalink_client/eeprom/list.rb
         | 
| @@ -99,14 +97,25 @@ files: | |
| 99 97 | 
             
            - lib/timex_datalink_client/helpers/crc_packets_wrapper.rb
         | 
| 100 98 | 
             
            - lib/timex_datalink_client/helpers/length_packet_wrapper.rb
         | 
| 101 99 | 
             
            - lib/timex_datalink_client/notebook_adapter.rb
         | 
| 102 | 
            -
            - lib/timex_datalink_client/ | 
| 103 | 
            -
            - lib/timex_datalink_client/ | 
| 104 | 
            -
            - lib/timex_datalink_client/ | 
| 100 | 
            +
            - lib/timex_datalink_client/protocol_1/alarm.rb
         | 
| 101 | 
            +
            - lib/timex_datalink_client/protocol_1/eeprom.rb
         | 
| 102 | 
            +
            - lib/timex_datalink_client/protocol_1/end.rb
         | 
| 103 | 
            +
            - lib/timex_datalink_client/protocol_1/start.rb
         | 
| 104 | 
            +
            - lib/timex_datalink_client/protocol_1/sync.rb
         | 
| 105 | 
            +
            - lib/timex_datalink_client/protocol_1/time.rb
         | 
| 106 | 
            +
            - lib/timex_datalink_client/protocol_1/time_name.rb
         | 
| 107 | 
            +
            - lib/timex_datalink_client/protocol_3/alarm.rb
         | 
| 108 | 
            +
            - lib/timex_datalink_client/protocol_3/eeprom.rb
         | 
| 109 | 
            +
            - lib/timex_datalink_client/protocol_3/end.rb
         | 
| 110 | 
            +
            - lib/timex_datalink_client/protocol_3/sound_options.rb
         | 
| 111 | 
            +
            - lib/timex_datalink_client/protocol_3/sound_theme.rb
         | 
| 112 | 
            +
            - lib/timex_datalink_client/protocol_3/start.rb
         | 
| 113 | 
            +
            - lib/timex_datalink_client/protocol_3/sync.rb
         | 
| 114 | 
            +
            - lib/timex_datalink_client/protocol_3/time.rb
         | 
| 115 | 
            +
            - lib/timex_datalink_client/protocol_3/wrist_app.rb
         | 
| 105 116 | 
             
            - lib/timex_datalink_client/sync.rb
         | 
| 106 | 
            -
            - lib/timex_datalink_client/time.rb
         | 
| 107 117 | 
             
            - lib/timex_datalink_client/version.rb
         | 
| 108 | 
            -
             | 
| 109 | 
            -
            homepage: https://github.com/synthead/timex_datalink_client/tree/v0.4.1
         | 
| 118 | 
            +
            homepage: https://github.com/synthead/timex_datalink_client/tree/v0.5.0
         | 
| 110 119 | 
             
            licenses:
         | 
| 111 120 | 
             
            - MIT
         | 
| 112 121 | 
             
            metadata: {}
         | 
| @@ -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,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,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,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
         |