-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #176 from synthead/add-protocol-7-phrase-model-class
Add protocol 7 phrase model class
- Loading branch information
Showing
6 changed files
with
213 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# frozen_string_literal: true | ||
|
||
require "timex_datalink_client/helpers/four_byte_formatter" | ||
|
||
class TimexDatalinkClient | ||
class Protocol7 | ||
class Eeprom | ||
class Phrase | ||
include Helpers::FourByteFormatter | ||
|
||
METADATA_BYTES_BASE = 0x0b | ||
METADATA_BYTES_SIZE = 5 | ||
|
||
HEADER_BOOL_TRUE_VALUE = 0x1a | ||
HEADER_BOOL_FALSE_VALUE = 0x00 | ||
HEADER_ONE_BYTE_VALUE_BASE = 0x0b | ||
HEADER_TWO_BYTE_VALUES_BASE = [0x1a, 0x24, 0x2e, 0x38, 0x47, 0x56, 0x60, 0x6a, 0x6f, 0x79, 0x83] | ||
HEADER_TWO_BYTE_LOOP_BASE = 0x8d | ||
|
||
HEADER_FOOTER = [ | ||
0xf0, 0x53, 0xfd, 0x4d, 0x03, 0xb0, 0x8d, 0xfe, 0x00, 0x00, 0xf0, 0x53, 0xfd, 0x4d, 0x03, 0xb0, 0x7b, 0xfe, | ||
0x00, 0x00, 0xf0, 0xfb, 0x63, 0x39, 0x3c, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0xf0, 0xfb, 0x61, 0x39, 0x3c, 0x70, | ||
0x94, 0xfd, 0x4b, 0x03, 0x7c, 0x44, 0x27, 0xfe, 0x00, 0xd3, 0xfb, 0xae, 0x30, 0x29, 0x33, 0x3c, 0xfb, 0x30, | ||
0x20, 0x07, 0x3c, 0x39, 0x24, 0xfe, 0xf1, 0xfb, 0x53, 0x03, 0xae, 0x9c, 0xe6, 0x8e, 0xfe, 0x00, 0xc1, 0x61, | ||
0x39, 0x3c, 0x44, 0xcc, 0xfd, 0x4b, 0xfe, 0x00, 0xff, 0xfb, 0x61, 0x3e, 0xfe, 0x41, 0xcb, 0x39, 0x3c, 0x44, | ||
0xcc, 0xfd, 0x4b, 0xfe, 0x00, 0x37, 0x39, 0x5a, 0xae, 0xfd, 0x1f, 0x4b, 0x8e, 0x81, 0xfe, 0x3f, 0x39, 0x5a, | ||
0x1c, 0x81, 0xc0, 0xff, 0x00, 0x00, 0x00 | ||
] | ||
|
||
PACKETS_TERMINATOR = 0x05 | ||
|
||
# Compile data for all phrases. | ||
# | ||
# @param phrases [Array<Phrase>] Phrases to compile data for. | ||
# @return [Array] Compiled data of all phrases. | ||
def self.packets(phrases) | ||
header(phrases) + formatted_phrases(phrases) + [PACKETS_TERMINATOR] | ||
end | ||
|
||
private_class_method def self.header(phrases) | ||
bool_value = phrases.empty? ? HEADER_BOOL_FALSE_VALUE : HEADER_BOOL_TRUE_VALUE | ||
|
||
one_byte_value = HEADER_ONE_BYTE_VALUE_BASE + phrases.count | ||
|
||
two_byte_values = HEADER_TWO_BYTE_VALUES_BASE.flat_map do |value_base| | ||
value = value_base + phrases.count * 2 | ||
value.divmod(256).reverse | ||
end | ||
|
||
loop_values = phrases.each_index.flat_map do |phrase_index| | ||
value = HEADER_TWO_BYTE_LOOP_BASE + phrases.count * 2 + phrase_index * 5 | ||
value.divmod(256).reverse | ||
end | ||
|
||
[ | ||
one_byte_value, | ||
0, | ||
bool_value, | ||
0, | ||
two_byte_values, | ||
loop_values, | ||
HEADER_FOOTER | ||
].flatten | ||
end | ||
|
||
private_class_method def self.formatted_phrases(phrases) | ||
return [] if phrases.empty? | ||
|
||
phrases_bytes = phrases.map(&:phrase) | ||
phrases.first.four_byte_format_for(phrases_bytes) | ||
end | ||
|
||
attr_accessor :phrase | ||
|
||
# Create a Phrase instance. | ||
# | ||
# @param phrase [Array<Integer>] Phrase for phrase. | ||
# @return [Phrase] Phrase instance. | ||
def initialize(phrase:) | ||
@phrase = phrase | ||
end | ||
end | ||
end | ||
end | ||
end |
77 changes: 77 additions & 0 deletions
77
spec/lib/timex_datalink_client/protocol_7/eeprom/phrase_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# frozen_string_literal: true | ||
|
||
require "spec_helper" | ||
|
||
describe TimexDatalinkClient::Protocol7::Eeprom::Phrase do | ||
let(:phrase) { [0xb1] } | ||
let(:phrase_instance) { described_class.new(phrase: phrase) } | ||
|
||
describe ".packets" do | ||
let(:phrases) { [phrase_instance] } | ||
|
||
subject(:packets) { described_class.packets(phrases) } | ||
|
||
it do | ||
should eq [ | ||
0x0c, 0x00, 0x1a, 0x00, 0x1c, 0x00, 0x26, 0x00, 0x30, 0x00, 0x3a, 0x00, 0x49, 0x00, 0x58, 0x00, 0x62, 0x00, | ||
0x6c, 0x00, 0x71, 0x00, 0x7b, 0x00, 0x85, 0x00, 0x8f, 0x00, 0xf0, 0x53, 0xfd, 0x4d, 0x03, 0xb0, 0x8d, 0xfe, | ||
0x00, 0x00, 0xf0, 0x53, 0xfd, 0x4d, 0x03, 0xb0, 0x7b, 0xfe, 0x00, 0x00, 0xf0, 0xfb, 0x63, 0x39, 0x3c, 0xc0, | ||
0xfe, 0x00, 0x00, 0x00, 0xf0, 0xfb, 0x61, 0x39, 0x3c, 0x70, 0x94, 0xfd, 0x4b, 0x03, 0x7c, 0x44, 0x27, 0xfe, | ||
0x00, 0xd3, 0xfb, 0xae, 0x30, 0x29, 0x33, 0x3c, 0xfb, 0x30, 0x20, 0x07, 0x3c, 0x39, 0x24, 0xfe, 0xf1, 0xfb, | ||
0x53, 0x03, 0xae, 0x9c, 0xe6, 0x8e, 0xfe, 0x00, 0xc1, 0x61, 0x39, 0x3c, 0x44, 0xcc, 0xfd, 0x4b, 0xfe, 0x00, | ||
0xff, 0xfb, 0x61, 0x3e, 0xfe, 0x41, 0xcb, 0x39, 0x3c, 0x44, 0xcc, 0xfd, 0x4b, 0xfe, 0x00, 0x37, 0x39, 0x5a, | ||
0xae, 0xfd, 0x1f, 0x4b, 0x8e, 0x81, 0xfe, 0x3f, 0x39, 0x5a, 0x1c, 0x81, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x30, | ||
0xb1, 0xff, 0x00, 0x00, 0x05 | ||
] | ||
end | ||
|
||
context "with no phrases" do | ||
let(:phrases) { [] } | ||
|
||
it do | ||
should eq [ | ||
0x0b, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x24, 0x00, 0x2e, 0x00, 0x38, 0x00, 0x47, 0x00, 0x56, 0x00, 0x60, 0x00, | ||
0x6a, 0x00, 0x6f, 0x00, 0x79, 0x00, 0x83, 0x00, 0xf0, 0x53, 0xfd, 0x4d, 0x03, 0xb0, 0x8d, 0xfe, 0x00, 0x00, | ||
0xf0, 0x53, 0xfd, 0x4d, 0x03, 0xb0, 0x7b, 0xfe, 0x00, 0x00, 0xf0, 0xfb, 0x63, 0x39, 0x3c, 0xc0, 0xfe, 0x00, | ||
0x00, 0x00, 0xf0, 0xfb, 0x61, 0x39, 0x3c, 0x70, 0x94, 0xfd, 0x4b, 0x03, 0x7c, 0x44, 0x27, 0xfe, 0x00, 0xd3, | ||
0xfb, 0xae, 0x30, 0x29, 0x33, 0x3c, 0xfb, 0x30, 0x20, 0x07, 0x3c, 0x39, 0x24, 0xfe, 0xf1, 0xfb, 0x53, 0x03, | ||
0xae, 0x9c, 0xe6, 0x8e, 0xfe, 0x00, 0xc1, 0x61, 0x39, 0x3c, 0x44, 0xcc, 0xfd, 0x4b, 0xfe, 0x00, 0xff, 0xfb, | ||
0x61, 0x3e, 0xfe, 0x41, 0xcb, 0x39, 0x3c, 0x44, 0xcc, 0xfd, 0x4b, 0xfe, 0x00, 0x37, 0x39, 0x5a, 0xae, 0xfd, | ||
0x1f, 0x4b, 0x8e, 0x81, 0xfe, 0x3f, 0x39, 0x5a, 0x1c, 0x81, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x05 | ||
] | ||
end | ||
end | ||
|
||
context "with two phrases" do | ||
let(:phrase_instance_2) { described_class.new(phrase: [0xb1, 0xb2, 0xb3]) } | ||
|
||
let(:phrases) { [phrase_instance, phrase_instance_2] } | ||
|
||
it do | ||
should eq [ | ||
0x0d, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x28, 0x00, 0x32, 0x00, 0x3c, 0x00, 0x4b, 0x00, 0x5a, 0x00, 0x64, 0x00, | ||
0x6e, 0x00, 0x73, 0x00, 0x7d, 0x00, 0x87, 0x00, 0x91, 0x00, 0x96, 0x00, 0xf0, 0x53, 0xfd, 0x4d, 0x03, 0xb0, | ||
0x8d, 0xfe, 0x00, 0x00, 0xf0, 0x53, 0xfd, 0x4d, 0x03, 0xb0, 0x7b, 0xfe, 0x00, 0x00, 0xf0, 0xfb, 0x63, 0x39, | ||
0x3c, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0xf0, 0xfb, 0x61, 0x39, 0x3c, 0x70, 0x94, 0xfd, 0x4b, 0x03, 0x7c, 0x44, | ||
0x27, 0xfe, 0x00, 0xd3, 0xfb, 0xae, 0x30, 0x29, 0x33, 0x3c, 0xfb, 0x30, 0x20, 0x07, 0x3c, 0x39, 0x24, 0xfe, | ||
0xf1, 0xfb, 0x53, 0x03, 0xae, 0x9c, 0xe6, 0x8e, 0xfe, 0x00, 0xc1, 0x61, 0x39, 0x3c, 0x44, 0xcc, 0xfd, 0x4b, | ||
0xfe, 0x00, 0xff, 0xfb, 0x61, 0x3e, 0xfe, 0x41, 0xcb, 0x39, 0x3c, 0x44, 0xcc, 0xfd, 0x4b, 0xfe, 0x00, 0x37, | ||
0x39, 0x5a, 0xae, 0xfd, 0x1f, 0x4b, 0x8e, 0x81, 0xfe, 0x3f, 0x39, 0x5a, 0x1c, 0x81, 0xc0, 0xff, 0x00, 0x00, | ||
0x00, 0x30, 0xb1, 0xfe, 0x00, 0x00, 0x03, 0xb1, 0xb2, 0xb3, 0xff, 0x05 | ||
] | ||
end | ||
end | ||
end | ||
|
||
describe "#phrase" do | ||
subject(:phrase_value) { phrase_instance.phrase } | ||
|
||
it { should eq([0xb1]) } | ||
|
||
context "when phrase is [0xb1, 0xb2, 0xb3]" do | ||
let(:phrase) { [0xb1, 0xb2, 0xb3] } | ||
|
||
it { should eq([0xb1, 0xb2, 0xb3]) } | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters