quelink-mg 0.1.0 → 0.2.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/.github/workflows/test.yml +30 -0
- data/.rubocop.yml +2 -2
- data/lib/quelink-mg/ack/gtcfg.rb +13 -0
- data/lib/quelink-mg/ack/gtcmd.rb +13 -0
- data/lib/quelink-mg/ack/gtfri.rb +13 -0
- data/lib/quelink-mg/ack/gtqss.rb +13 -0
- data/lib/quelink-mg/ack/gtrto.rb +14 -0
- data/lib/quelink-mg/ack/gtsri.rb +13 -0
- data/lib/quelink-mg/ack/gtudf.rb +13 -0
- data/lib/quelink-mg/at/base.rb +7 -0
- data/lib/quelink-mg/at/gtbsi.rb +2 -2
- data/lib/quelink-mg/at/gtcfg.rb +45 -0
- data/lib/quelink-mg/at/gtcmd.rb +31 -0
- data/lib/quelink-mg/at/gtfri.rb +44 -0
- data/lib/quelink-mg/at/gtqss.rb +36 -0
- data/lib/quelink-mg/at/gtrto.rb +30 -0
- data/lib/quelink-mg/at/gtsri.rb +37 -0
- data/lib/quelink-mg/at/gtudf.rb +33 -0
- data/lib/quelink-mg/resp/gtgsv.rb +26 -0
- data/lib/quelink-mg/resp/gtinf.rb +16 -0
- data/lib/quelink-mg/resp/gtsos.rb +15 -0
- data/lib/quelink-mg/resp/gtstt.rb +15 -0
- data/lib/quelink-mg/resp/gtupc.rb +14 -0
- data/lib/quelink_mg.rb +22 -0
- data/quelink-mg.gemspec +2 -2
- data/spec/quelink_mg/ack/gtcfg_spec.rb +14 -0
- data/spec/quelink_mg/ack/gtcmd_spec.rb +14 -0
- data/spec/quelink_mg/ack/gtfri_spec.rb +14 -0
- data/spec/quelink_mg/ack/gtqss_spec.rb +14 -0
- data/spec/quelink_mg/ack/gtrto_spec.rb +15 -0
- data/spec/quelink_mg/ack/gtsri_spec.rb +14 -0
- data/spec/quelink_mg/ack/gtudf_spec.rb +14 -0
- data/spec/quelink_mg/at/gtcfg_spec.rb +69 -0
- data/spec/quelink_mg/at/gtcmd_spec.rb +35 -0
- data/spec/quelink_mg/at/gtfri_spec.rb +62 -0
- data/spec/quelink_mg/at/gtqss_spec.rb +50 -0
- data/spec/quelink_mg/at/gtrto_spec.rb +32 -0
- data/spec/quelink_mg/at/gtsri_spec.rb +50 -0
- data/spec/quelink_mg/at/gtudf_spec.rb +45 -0
- data/spec/quelink_mg/resp/gtgsv_spec.rb +18 -0
- data/spec/quelink_mg/resp/gtinf_spec.rb +29 -0
- data/spec/quelink_mg/resp/gtsos_spec.rb +32 -0
- data/spec/quelink_mg/resp/gtstt_spec.rb +29 -0
- data/spec/quelink_mg/resp/gtupc_spec.rb +18 -0
- metadata +43 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 23b5c621bb4f754c02531d476777765aa72129b940f5970af5e91aba7ab383b2
|
|
4
|
+
data.tar.gz: 5bf16472b454c0fcca79673cf5ee5d52bfd7a19ef222cf670680bb5d3e8cf6e3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1654b91fe0307d6eb50f84b5cd557442a04bcc8b98f314b56f95e579583214ddd33166e874fab36ce486970074b3eaf8d1727a05e53a8526f58f620ae418570f
|
|
7
|
+
data.tar.gz: d24856838b17ef5c079ddedd9817e7a7053a0f6c4bd6f7fa6b20ca7e4d89080e1504ee874ceea21a6e7fba326c7e5ff82c7c4eaa39d598fd1de0e14bf3884c43
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Ruby
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master, staging ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master, staging ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-22.04
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v2
|
|
14
|
+
- uses: szenius/set-timezone@v1.0
|
|
15
|
+
with:
|
|
16
|
+
timezoneLinux: "Europe/Warsaw"
|
|
17
|
+
- name: Set up Ruby
|
|
18
|
+
uses: ruby/setup-ruby@v1
|
|
19
|
+
with:
|
|
20
|
+
ruby-version: 3.1.2
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: bundle install
|
|
23
|
+
env:
|
|
24
|
+
RAILS_ENV: test
|
|
25
|
+
- name: Run tests
|
|
26
|
+
run: bundle exec rspec
|
|
27
|
+
env:
|
|
28
|
+
RAILS_ENV: test
|
|
29
|
+
- name: Rubocop
|
|
30
|
+
run: rubocop
|
data/.rubocop.yml
CHANGED
|
@@ -7,7 +7,7 @@ AllCops:
|
|
|
7
7
|
Style/Documentation:
|
|
8
8
|
Enabled: false
|
|
9
9
|
Metrics/MethodLength:
|
|
10
|
-
Max:
|
|
10
|
+
Max: 18
|
|
11
11
|
Metrics/BlockLength:
|
|
12
12
|
Max: 40
|
|
13
13
|
Gemspec/DevelopmentDependencies:
|
|
@@ -15,7 +15,7 @@ Gemspec/DevelopmentDependencies:
|
|
|
15
15
|
RSpec/MultipleExpectations:
|
|
16
16
|
Enabled: false
|
|
17
17
|
RSpec/ExampleLength:
|
|
18
|
-
Max:
|
|
18
|
+
Max: 30
|
|
19
19
|
Layout/LineLength:
|
|
20
20
|
Exclude:
|
|
21
21
|
- spec/quelink_mg/resp/*_spec.rb
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module Ack
|
|
5
|
+
class Gtcfg < Base
|
|
6
|
+
GTCFG_ACK_KEYS = %w[protocol_version unique_id device_name serial_number send_time count_number].freeze
|
|
7
|
+
|
|
8
|
+
def hash
|
|
9
|
+
unify_keys(GTCFG_ACK_KEYS.zip(@response.split(',')).to_h)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module Ack
|
|
5
|
+
class Gtcmd < Base
|
|
6
|
+
GTCMD_ACK_KEYS = %w[protocol_version unique_id device_name serial_number send_time count_number].freeze
|
|
7
|
+
|
|
8
|
+
def hash
|
|
9
|
+
unify_keys(GTCMD_ACK_KEYS.zip(@response.split(',')).to_h)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module Ack
|
|
5
|
+
class Gtfri < Base
|
|
6
|
+
GTFRI_ACK_KEYS = %w[protocol_version unique_id device_name serial_number send_time count_number].freeze
|
|
7
|
+
|
|
8
|
+
def hash
|
|
9
|
+
unify_keys(GTFRI_ACK_KEYS.zip(@response.split(',')).to_h)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module Ack
|
|
5
|
+
class Gtqss < Base
|
|
6
|
+
GTQSS_ACK_KEYS = %w[protocol_version unique_id device_name serial_number send_time count_number].freeze
|
|
7
|
+
|
|
8
|
+
def hash
|
|
9
|
+
unify_keys(GTQSS_ACK_KEYS.zip(@response.split(',')).to_h)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module Ack
|
|
5
|
+
class Gtrto < Base
|
|
6
|
+
GTRTO_ACK_KEYS = %w[protocol_version unique_id device_name sub_command serial_number send_time
|
|
7
|
+
count_number].freeze
|
|
8
|
+
|
|
9
|
+
def hash
|
|
10
|
+
unify_keys(GTRTO_ACK_KEYS.zip(@response.split(',')).to_h)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module Ack
|
|
5
|
+
class Gtsri < Base
|
|
6
|
+
GTSRI_ACK_KEYS = %w[protocol_version unique_id device_name serial_number send_time count_number].freeze
|
|
7
|
+
|
|
8
|
+
def hash
|
|
9
|
+
unify_keys(GTSRI_ACK_KEYS.zip(@response.split(',')).to_h)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module Ack
|
|
5
|
+
class Gtudf < Base
|
|
6
|
+
GTUDF_ACK_KEYS = %w[protocol_version unique_id device_name serial_number send_time count_number].freeze
|
|
7
|
+
|
|
8
|
+
def hash
|
|
9
|
+
unify_keys(GTUDF_ACK_KEYS.zip(@response.split(',')).to_h)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
data/lib/quelink-mg/at/base.rb
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class InvalidATGTBSIException < StandardError; end
|
|
4
|
+
class InvalidATGTCFGException < StandardError; end
|
|
5
|
+
class InvalidATGTCMDException < StandardError; end
|
|
6
|
+
class InvalidATGTFRIException < StandardError; end
|
|
7
|
+
class InvalidATGTQSSException < StandardError; end
|
|
8
|
+
class InvalidATGTRTOException < StandardError; end
|
|
9
|
+
class InvalidATGTSRIException < StandardError; end
|
|
10
|
+
class InvalidATGTUDFException < StandardError; end
|
|
4
11
|
|
|
5
12
|
module QuelinkMg
|
|
6
13
|
module At
|
data/lib/quelink-mg/at/gtbsi.rb
CHANGED
|
@@ -22,9 +22,9 @@ module QuelinkMg
|
|
|
22
22
|
def validate_values
|
|
23
23
|
acceptable_values = {
|
|
24
24
|
network_mode: (0..3),
|
|
25
|
-
lte_mode: (0..
|
|
25
|
+
lte_mode: (0..5),
|
|
26
26
|
apn_authentication_methods: (0..3),
|
|
27
|
-
manual_netreg: (0..
|
|
27
|
+
manual_netreg: (0..1)
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
verify_params(acceptable_values, InvalidATGTBSIException)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module At
|
|
5
|
+
class Gtcfg < Base
|
|
6
|
+
def message
|
|
7
|
+
validate_values
|
|
8
|
+
|
|
9
|
+
"AT+GTCFG=#{joined_params}$"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
GTCFG_VALID_PARAMS = %i[password new_password device_name enable_odo odo_initial_mileage gps_on_need
|
|
15
|
+
gps_fix_delay report_item_mask reserved reserved event_mask epb_mode led_on
|
|
16
|
+
info_report_enable info_report_interval location_request_mask expiry_enable
|
|
17
|
+
expiry_time agps_mode gsm_report battery_switch_power_on battery_low_percentage
|
|
18
|
+
reserved reserved serial_number].freeze
|
|
19
|
+
|
|
20
|
+
def joined_params
|
|
21
|
+
GTCFG_VALID_PARAMS.map { |method| @params.fetch(method, nil) }.join(',')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def validate_values
|
|
25
|
+
acceptable_values = {
|
|
26
|
+
enable_odo: (0..1),
|
|
27
|
+
odo_initial_mileage: (0.0..4_294_967.0),
|
|
28
|
+
gps_on_need: (0..2),
|
|
29
|
+
gps_fix_delay: (5..60),
|
|
30
|
+
epb_mode: (0..1),
|
|
31
|
+
led_on: (0..2),
|
|
32
|
+
info_report_enable: (0..1),
|
|
33
|
+
info_report_interval: (30..86_400),
|
|
34
|
+
location_request_mask: (0..2),
|
|
35
|
+
expiry_enable: (0..1),
|
|
36
|
+
agps_mode: (0..1),
|
|
37
|
+
battery_switch_power_on: (0..1),
|
|
38
|
+
battery_low_percentage: (0..30)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
verify_params(acceptable_values, InvalidATGTCFGException)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module At
|
|
5
|
+
class Gtcmd < Base
|
|
6
|
+
def message
|
|
7
|
+
validate_values
|
|
8
|
+
|
|
9
|
+
"AT+GTCMD=#{joined_params}$"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
GTCMD_VALID_PARAMS = %i[password mode stored_cmd_id command_string
|
|
15
|
+
reserved reserved reserved reserved serial_number].freeze
|
|
16
|
+
|
|
17
|
+
def joined_params
|
|
18
|
+
GTCMD_VALID_PARAMS.map { |method| @params.fetch(method, nil) }.join(',')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def validate_values
|
|
22
|
+
acceptable_values = {
|
|
23
|
+
mode: (0..1),
|
|
24
|
+
stored_cmd_id: (0..31)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
verify_params(acceptable_values, InvalidATGTCMDException)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module At
|
|
5
|
+
class Gtfri < Base
|
|
6
|
+
def message
|
|
7
|
+
validate_values
|
|
8
|
+
|
|
9
|
+
"AT+GTFRI=#{joined_params}$"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
GTFRI_VALID_PARAMS = %i[password mode discard_no_fix reserved reserved begin_time end_time
|
|
15
|
+
check_interval send_interval ignition_check_interval ignition_send_interval
|
|
16
|
+
reserved distance mileage movement_detection_mode movement_speed movement_distance
|
|
17
|
+
movement_send_number corner eri_mask serial_number].freeze
|
|
18
|
+
|
|
19
|
+
def joined_params
|
|
20
|
+
GTFRI_VALID_PARAMS.map { |method| @params.fetch(method, nil) }.join(',')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def validate_values
|
|
24
|
+
acceptable_values = {
|
|
25
|
+
mode: (0..5),
|
|
26
|
+
discard_no_fix: (0..1),
|
|
27
|
+
check_interval: (1..86_400),
|
|
28
|
+
send_interval: (5..86_400),
|
|
29
|
+
ignition_check_interval: (5..86_400),
|
|
30
|
+
ignition_send_interval: (5..86_400),
|
|
31
|
+
distance: (50..65_535),
|
|
32
|
+
mileage: (50..65_535),
|
|
33
|
+
movement_detection_mode: (0..1),
|
|
34
|
+
movement_speed: (1..999),
|
|
35
|
+
movement_distance: (1..9999),
|
|
36
|
+
movement_send_number: (1..5),
|
|
37
|
+
corner: (0..180)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
verify_params(acceptable_values, InvalidATGTFRIException)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module At
|
|
5
|
+
class Gtqss < Base
|
|
6
|
+
def message
|
|
7
|
+
validate_values
|
|
8
|
+
|
|
9
|
+
"AT+GTQSS=#{joined_params}$"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
GTQSS_VALID_PARAMS = %i[password lte_apn lte_apn_user_name ltn_apn_password report_mode reserved
|
|
15
|
+
buffer_mode main_server_ip main_server_port backup_server_ip backup_server_port
|
|
16
|
+
sms_gateway heartbit_interval sack_enable reserved reserved serial_number].freeze
|
|
17
|
+
|
|
18
|
+
def joined_params
|
|
19
|
+
GTQSS_VALID_PARAMS.map { |method| @params.fetch(method, nil) }.join(',')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def validate_values
|
|
23
|
+
acceptable_values = {
|
|
24
|
+
report_mode: (0..7),
|
|
25
|
+
buffer_mode: (0..2),
|
|
26
|
+
main_server_port: (0..65_535),
|
|
27
|
+
backup_server_port: (0..65_535),
|
|
28
|
+
heartbit_interval: [0] + (5..360).to_a,
|
|
29
|
+
sack_enable: (0..2)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
verify_params(acceptable_values, InvalidATGTQSSException)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module At
|
|
5
|
+
class Gtrto < Base
|
|
6
|
+
def message
|
|
7
|
+
validate_values
|
|
8
|
+
|
|
9
|
+
"AT+GTRTO=#{joined_params}$"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
GTRTO_VALID_PARAMS = %i[password sub_command single_command_configuration reserved
|
|
15
|
+
reserved reserved sub_command_parameter serial_number].freeze
|
|
16
|
+
|
|
17
|
+
def joined_params
|
|
18
|
+
GTRTO_VALID_PARAMS.map { |method| @params.fetch(method, nil) }.join(',')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def validate_values
|
|
22
|
+
acceptable_values = {
|
|
23
|
+
sub_command: (0x0..0xF).to_a + [0x14, 0x1C]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
verify_params(acceptable_values, InvalidATGTRTOException)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module At
|
|
5
|
+
class Gtsri < Base
|
|
6
|
+
def message
|
|
7
|
+
validate_values
|
|
8
|
+
|
|
9
|
+
"AT+GTSRI=#{joined_params}$"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
GTSRI_VALID_PARAMS = %i[password report_mode reserved buffer_mode main_server_ip main_server_port
|
|
15
|
+
backup_server_ip backup_server_port sms_gateway heartbit_interval sack_enable
|
|
16
|
+
sms_ack_enable reserved reserved reserved serial_number].freeze
|
|
17
|
+
|
|
18
|
+
def joined_params
|
|
19
|
+
GTSRI_VALID_PARAMS.map { |method| @params.fetch(method, nil) }.join(',')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def validate_values
|
|
23
|
+
acceptable_values = {
|
|
24
|
+
report_mode: (0..7),
|
|
25
|
+
buffer_mode: (0..2),
|
|
26
|
+
main_server_port: (0..65_535),
|
|
27
|
+
backup_server_port: (0..65_535),
|
|
28
|
+
heartbit_interval: [0] + (5..360).to_a,
|
|
29
|
+
sack_enable: (0..2),
|
|
30
|
+
sms_ack_enable: (0..1)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
verify_params(acceptable_values, InvalidATGTSRIException)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module At
|
|
5
|
+
class Gtudf < Base
|
|
6
|
+
def message
|
|
7
|
+
validate_values
|
|
8
|
+
|
|
9
|
+
"AT+GTUDF=#{joined_params}$"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
GTUDF_VALID_PARAMS = %i[password mode group_id input_id_mask debounce_time inzizo_mask outzizo_mask
|
|
15
|
+
stocmd_id_mask stocmd_ack reserved reserved reserved reserved serial_number].freeze
|
|
16
|
+
|
|
17
|
+
def joined_params
|
|
18
|
+
GTUDF_VALID_PARAMS.map { |method| @params.fetch(method, nil) }.join(',')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def validate_values
|
|
22
|
+
acceptable_values = {
|
|
23
|
+
mode: (0..2),
|
|
24
|
+
group_id: (0..31),
|
|
25
|
+
debounce_time: (0..86_400),
|
|
26
|
+
stocmd_ack: (0..1)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
verify_params(acceptable_values, InvalidATGTUDFException)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module Resp
|
|
5
|
+
class Gtgsv < Base
|
|
6
|
+
GTGSV_RESP_KEYS_PREFIX = %w[protocol_version unique_id device_name sv_count].freeze
|
|
7
|
+
GTGSV_RESP_KEYS_SUFFIX = %w[send_time count_number].freeze
|
|
8
|
+
|
|
9
|
+
def hash
|
|
10
|
+
all_params = @response.split(',')
|
|
11
|
+
|
|
12
|
+
sv_out = all_params[3].to_i
|
|
13
|
+
|
|
14
|
+
sv_arr = []
|
|
15
|
+
sv_out.times do |i|
|
|
16
|
+
sv_arr << "sv_id_#{i}"
|
|
17
|
+
sv_arr << "sv_power_#{i}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
keys = [GTGSV_RESP_KEYS_PREFIX, sv_arr, GTGSV_RESP_KEYS_SUFFIX].inject(:+)
|
|
21
|
+
|
|
22
|
+
unify_keys(keys.zip(all_params).to_h)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module Resp
|
|
5
|
+
class Gtinf < Base
|
|
6
|
+
GTINF_RESP_KEYS = %w[protocol_version unique_id device_name state iccid csq_rssi
|
|
7
|
+
csq_ber external_power_supply mileage reserved battery_voltage charging
|
|
8
|
+
led_on gps_on_need reserved reserved last_gps_fix_utc_time battery_percentage reserved
|
|
9
|
+
temperature reserved reserved send_time count_number].freeze
|
|
10
|
+
|
|
11
|
+
def hash
|
|
12
|
+
unify_keys(GTINF_RESP_KEYS.zip(@response.split(',')).to_h)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module Resp
|
|
5
|
+
class Gtsos < Base
|
|
6
|
+
GTSOS_RESP_KEYS = %w[protocol_version unique_id device_name report_id report_type number
|
|
7
|
+
gps_accuracy speed azimuth altitude longitude latitude gps_utc_time mcc mnc lac
|
|
8
|
+
cel_id odo_mileage battery_percentage send_time count_number].freeze
|
|
9
|
+
|
|
10
|
+
def hash
|
|
11
|
+
unify_keys(GTSOS_RESP_KEYS.zip(@response.split(',')).to_h)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module Resp
|
|
5
|
+
class Gtstt < Base
|
|
6
|
+
GTSTT_RESP_KEYS = %w[protocol_version unique_id device_name state gps_accuracy
|
|
7
|
+
speed azimuth altitude last_longitude last_latitude gps_utc_time
|
|
8
|
+
mcc mnc lac cell_id odo_mileage send_time count_number].freeze
|
|
9
|
+
|
|
10
|
+
def hash
|
|
11
|
+
unify_keys(GTSTT_RESP_KEYS.zip(@response.split(',')).to_h)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QuelinkMg
|
|
4
|
+
module Resp
|
|
5
|
+
class Gtupc < Base
|
|
6
|
+
GTUPC_RESP_KEYS = %w[protocol_version unique_id device_name command_id result download_url send_time
|
|
7
|
+
count_number].freeze
|
|
8
|
+
|
|
9
|
+
def hash
|
|
10
|
+
unify_keys(GTUPC_RESP_KEYS.zip(@response.split(',')).to_h)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/quelink_mg.rb
CHANGED
|
@@ -8,10 +8,32 @@ require 'active_support/core_ext/time/zones'
|
|
|
8
8
|
|
|
9
9
|
require File.expand_path('quelink-mg/at/base.rb', __dir__)
|
|
10
10
|
require File.expand_path('quelink-mg/at/gtbsi.rb', __dir__)
|
|
11
|
+
require File.expand_path('quelink-mg/at/gtcfg.rb', __dir__)
|
|
12
|
+
require File.expand_path('quelink-mg/at/gtcmd.rb', __dir__)
|
|
13
|
+
require File.expand_path('quelink-mg/at/gtfri.rb', __dir__)
|
|
14
|
+
require File.expand_path('quelink-mg/at/gtqss.rb', __dir__)
|
|
15
|
+
require File.expand_path('quelink-mg/at/gtrto.rb', __dir__)
|
|
16
|
+
require File.expand_path('quelink-mg/at/gtsri.rb', __dir__)
|
|
17
|
+
require File.expand_path('quelink-mg/at/gtudf.rb', __dir__)
|
|
18
|
+
|
|
11
19
|
require File.expand_path('quelink-mg/resp/base.rb', __dir__)
|
|
12
20
|
require File.expand_path('quelink-mg/resp/gtfri.rb', __dir__)
|
|
21
|
+
require File.expand_path('quelink-mg/resp/gtgsv.rb', __dir__)
|
|
22
|
+
require File.expand_path('quelink-mg/resp/gtinf.rb', __dir__)
|
|
23
|
+
require File.expand_path('quelink-mg/resp/gtsos.rb', __dir__)
|
|
24
|
+
require File.expand_path('quelink-mg/resp/gtstt.rb', __dir__)
|
|
25
|
+
require File.expand_path('quelink-mg/resp/gtupc.rb', __dir__)
|
|
26
|
+
|
|
13
27
|
require File.expand_path('quelink-mg/ack/base.rb', __dir__)
|
|
14
28
|
require File.expand_path('quelink-mg/ack/gtbsi.rb', __dir__)
|
|
29
|
+
require File.expand_path('quelink-mg/ack/gtcfg.rb', __dir__)
|
|
30
|
+
require File.expand_path('quelink-mg/ack/gtcmd.rb', __dir__)
|
|
31
|
+
require File.expand_path('quelink-mg/ack/gtfri.rb', __dir__)
|
|
32
|
+
require File.expand_path('quelink-mg/ack/gtqss.rb', __dir__)
|
|
33
|
+
require File.expand_path('quelink-mg/ack/gtrto.rb', __dir__)
|
|
34
|
+
require File.expand_path('quelink-mg/ack/gtsri.rb', __dir__)
|
|
35
|
+
require File.expand_path('quelink-mg/ack/gtudf.rb', __dir__)
|
|
36
|
+
|
|
15
37
|
require File.expand_path('quelink-mg/configuration.rb', __dir__)
|
|
16
38
|
|
|
17
39
|
module QuelinkMg
|
data/quelink-mg.gemspec
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |s|
|
|
4
4
|
s.name = 'quelink-mg'
|
|
5
|
-
s.version = '0.
|
|
5
|
+
s.version = '0.2.0'
|
|
6
6
|
s.summary = 'Quelink devices command reader and writer'
|
|
7
7
|
s.description = 'Quelink devices command reader and writer'
|
|
8
8
|
s.authors = ['Stanislaw Zawadzki']
|
|
@@ -17,5 +17,5 @@ Gem::Specification.new do |s|
|
|
|
17
17
|
s.add_development_dependency 'rspec', '~> 3.9'
|
|
18
18
|
s.add_development_dependency 'rubocop', '~> 1.0'
|
|
19
19
|
s.add_development_dependency 'rubocop-rspec', '~> 2.2'
|
|
20
|
-
|
|
20
|
+
s.metadata['rubygems_mfa_required'] = 'false'
|
|
21
21
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::Ack::Gtcfg do
|
|
6
|
+
it 'parses valid response' do
|
|
7
|
+
response = 'D40102,868239051011356,,0040,20210816045509,004F'
|
|
8
|
+
parsed_response = described_class.new(response:).hash
|
|
9
|
+
expect(parsed_response['protocol_version']).to eq 'D40102'
|
|
10
|
+
expect(parsed_response['unique_id']).to eq 868_239_051_011_356
|
|
11
|
+
expect(parsed_response['send_time']).to eq Time.zone.strptime('20210816045509',
|
|
12
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::Ack::Gtcmd do
|
|
6
|
+
it 'parses valid response' do
|
|
7
|
+
response = 'D40102,868239051011356,,0040,20210816045509,004F'
|
|
8
|
+
parsed_response = described_class.new(response:).hash
|
|
9
|
+
expect(parsed_response['protocol_version']).to eq 'D40102'
|
|
10
|
+
expect(parsed_response['unique_id']).to eq 868_239_051_011_356
|
|
11
|
+
expect(parsed_response['send_time']).to eq Time.zone.strptime('20210816045509',
|
|
12
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::Ack::Gtfri do
|
|
6
|
+
it 'parses valid response' do
|
|
7
|
+
response = 'D40102,868239051011356,,0040,20210816045509,004F'
|
|
8
|
+
parsed_response = described_class.new(response:).hash
|
|
9
|
+
expect(parsed_response['protocol_version']).to eq 'D40102'
|
|
10
|
+
expect(parsed_response['unique_id']).to eq 868_239_051_011_356
|
|
11
|
+
expect(parsed_response['send_time']).to eq Time.zone.strptime('20210816045509',
|
|
12
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::Ack::Gtqss do
|
|
6
|
+
it 'parses valid response' do
|
|
7
|
+
response = 'D40102,868239051011356,,0040,20210816045509,004F'
|
|
8
|
+
parsed_response = described_class.new(response:).hash
|
|
9
|
+
expect(parsed_response['protocol_version']).to eq 'D40102'
|
|
10
|
+
expect(parsed_response['unique_id']).to eq 868_239_051_011_356
|
|
11
|
+
expect(parsed_response['send_time']).to eq Time.zone.strptime('20210816045509',
|
|
12
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::Ack::Gtrto do
|
|
6
|
+
it 'parses valid response' do
|
|
7
|
+
response = 'D40102,868239051011356,,READ,0040,20210816045509,004F'
|
|
8
|
+
parsed_response = described_class.new(response:).hash
|
|
9
|
+
expect(parsed_response['protocol_version']).to eq 'D40102'
|
|
10
|
+
expect(parsed_response['unique_id']).to eq 868_239_051_011_356
|
|
11
|
+
expect(parsed_response['sub_command']).to eq 'READ'
|
|
12
|
+
expect(parsed_response['send_time']).to eq Time.zone.strptime('20210816045509',
|
|
13
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::Ack::Gtsri do
|
|
6
|
+
it 'parses valid response' do
|
|
7
|
+
response = 'D40102,868239051011356,,0040,20210816045509,004F'
|
|
8
|
+
parsed_response = described_class.new(response:).hash
|
|
9
|
+
expect(parsed_response['protocol_version']).to eq 'D40102'
|
|
10
|
+
expect(parsed_response['unique_id']).to eq 868_239_051_011_356
|
|
11
|
+
expect(parsed_response['send_time']).to eq Time.zone.strptime('20210816045509',
|
|
12
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::Ack::Gtudf do
|
|
6
|
+
it 'parses valid response' do
|
|
7
|
+
response = 'D40102,868239051011356,,0040,20210816045509,004F'
|
|
8
|
+
parsed_response = described_class.new(response:).hash
|
|
9
|
+
expect(parsed_response['protocol_version']).to eq 'D40102'
|
|
10
|
+
expect(parsed_response['unique_id']).to eq 868_239_051_011_356
|
|
11
|
+
expect(parsed_response['send_time']).to eq Time.zone.strptime('20210816045509',
|
|
12
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'quelink-mg/at/gtcfg'
|
|
5
|
+
|
|
6
|
+
RSpec.describe QuelinkMg::At::Gtcfg do
|
|
7
|
+
it 'creates command when params are valid' do
|
|
8
|
+
params =
|
|
9
|
+
{
|
|
10
|
+
password: 'gl310m',
|
|
11
|
+
new_password: 'gl310m',
|
|
12
|
+
device_name: 'gl310m',
|
|
13
|
+
enable_odo: 0,
|
|
14
|
+
odo_initial_mileage: 0.0,
|
|
15
|
+
gps_on_need: 1,
|
|
16
|
+
gps_fix_delay: 5,
|
|
17
|
+
report_item_mask: '001F',
|
|
18
|
+
event_mask: '0FFF',
|
|
19
|
+
epb_mode: 0,
|
|
20
|
+
led_on: 1,
|
|
21
|
+
info_report_enable: 1,
|
|
22
|
+
info_report_interval: 300,
|
|
23
|
+
location_request_mask: 2,
|
|
24
|
+
expiry_enable: 0,
|
|
25
|
+
expiry_time: 20_491_231_235_959,
|
|
26
|
+
agps_mode: 0,
|
|
27
|
+
gsm_report: '0000',
|
|
28
|
+
battery_switch_power_on: 0,
|
|
29
|
+
battery_low_percentage: 10,
|
|
30
|
+
serial_number: 'FFFF'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
expect(described_class.new(params:).message).to eq 'AT+GTCFG=gl310m,gl310m,gl310m,0,0.0,1,5,001F,,,0FFF,0,1,1,' \
|
|
34
|
+
'300,2,0,20491231235959,0,0000,0,10,,,FFFF$'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'raises error on missing params' do
|
|
38
|
+
expect { described_class.new(params: {}).message }.to raise_error(InvalidATGTCFGException)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'raises error on improper params' do
|
|
42
|
+
params =
|
|
43
|
+
{
|
|
44
|
+
password: 'gl310m',
|
|
45
|
+
new_password: 'gl310m',
|
|
46
|
+
device_name: 'gl310m',
|
|
47
|
+
enable_odo: 0,
|
|
48
|
+
odo_initial_mileage: 0.0,
|
|
49
|
+
gps_on_need: 1,
|
|
50
|
+
gps_fix_delay: 5,
|
|
51
|
+
report_item_mask: '001F',
|
|
52
|
+
event_mask: '0FFF',
|
|
53
|
+
epb_mode: 0,
|
|
54
|
+
led_on: 3,
|
|
55
|
+
info_report_enable: 1,
|
|
56
|
+
info_report_interval: 300,
|
|
57
|
+
location_request_mask: 2,
|
|
58
|
+
expiry_enable: 0,
|
|
59
|
+
expiry_time: 20_491_231_235_959,
|
|
60
|
+
agps_mode: 0,
|
|
61
|
+
gsm_report: '0000',
|
|
62
|
+
battery_switch_power_on: 0,
|
|
63
|
+
battery_low_percentage: 10,
|
|
64
|
+
serial_number: 'FFFF'
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
expect { described_class.new(params:).message }.to raise_error(InvalidATGTCFGException)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::At::Gtcmd do
|
|
6
|
+
it 'creates command when params are valid' do
|
|
7
|
+
params =
|
|
8
|
+
{
|
|
9
|
+
password: 'gl310m',
|
|
10
|
+
mode: 1,
|
|
11
|
+
stored_cmd_id: 0,
|
|
12
|
+
command_string: 'AT+CFUN=4',
|
|
13
|
+
serial_number: 'FFFF'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
expect(described_class.new(params:).message).to eq 'AT+GTCMD=gl310m,1,0,AT+CFUN=4,,,,,FFFF$'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'raises error on missing params' do
|
|
20
|
+
expect { described_class.new(params: {}).message }.to raise_error(InvalidATGTCMDException)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'raises error on improper params' do
|
|
24
|
+
params =
|
|
25
|
+
{
|
|
26
|
+
password: 'gl310m',
|
|
27
|
+
mode: 10,
|
|
28
|
+
stored_cmd_id: 0,
|
|
29
|
+
command_string: 'AT+CFUN=4',
|
|
30
|
+
serial_number: 'FFFF'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
expect { described_class.new(params:).message }.to raise_error(InvalidATGTCMDException)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::At::Gtfri do
|
|
6
|
+
it 'creates command when params are valid' do
|
|
7
|
+
params =
|
|
8
|
+
{
|
|
9
|
+
password: 'gl310m',
|
|
10
|
+
mode: 1,
|
|
11
|
+
discard_no_fix: 0,
|
|
12
|
+
begin_time: '0000',
|
|
13
|
+
end_time: '0000',
|
|
14
|
+
check_interval: 1,
|
|
15
|
+
send_interval: 5,
|
|
16
|
+
ignition_check_interval: 180,
|
|
17
|
+
ignition_send_interval: 180,
|
|
18
|
+
distance: 65_535,
|
|
19
|
+
mileage: 500,
|
|
20
|
+
movement_detection_mode: 0,
|
|
21
|
+
movement_speed: 10,
|
|
22
|
+
movement_distance: 1000,
|
|
23
|
+
movement_send_number: 5,
|
|
24
|
+
corner: 10,
|
|
25
|
+
eri_mask: '00',
|
|
26
|
+
serial_number: 'FFFF'
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
expect(described_class.new(params:).message).to eq 'AT+GTFRI=gl310m,1,0,,,0000,0000,1,5,180,180,,65535,' \
|
|
30
|
+
'500,0,10,1000,5,10,00,FFFF$'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'raises error on missing params' do
|
|
34
|
+
expect { described_class.new(params: {}).message }.to raise_error(InvalidATGTFRIException)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'raises error on improper params' do
|
|
38
|
+
params =
|
|
39
|
+
{
|
|
40
|
+
password: 'gl310m',
|
|
41
|
+
mode: 1,
|
|
42
|
+
discard_no_fix: 0,
|
|
43
|
+
begin_time: '0000',
|
|
44
|
+
end_time: '0000',
|
|
45
|
+
check_interval: 1,
|
|
46
|
+
send_interval: 5,
|
|
47
|
+
ignition_check_interval: 180,
|
|
48
|
+
ignition_send_interval: 180,
|
|
49
|
+
distance: 65_535,
|
|
50
|
+
mileage: 500,
|
|
51
|
+
movement_detection_mode: 0,
|
|
52
|
+
movement_speed: 2000,
|
|
53
|
+
movement_distance: 1000,
|
|
54
|
+
movement_send_number: 5,
|
|
55
|
+
corner: 10,
|
|
56
|
+
eri_mask: '00',
|
|
57
|
+
serial_number: 'FFFF'
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
expect { described_class.new(params:).message }.to raise_error(InvalidATGTFRIException)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::At::Gtqss do
|
|
6
|
+
it 'creates command when params are valid' do
|
|
7
|
+
params =
|
|
8
|
+
{
|
|
9
|
+
password: 'gl310m',
|
|
10
|
+
lte_apn: 'net',
|
|
11
|
+
report_mode: 3,
|
|
12
|
+
buffer_mode: 1,
|
|
13
|
+
main_server_ip: '218.17.46.11',
|
|
14
|
+
main_server_port: 91,
|
|
15
|
+
backup_server_ip: '213.175.74.200',
|
|
16
|
+
backup_server_port: 5682,
|
|
17
|
+
sms_gateway: 13_824_347_475,
|
|
18
|
+
heartbit_interval: 0,
|
|
19
|
+
sack_enable: 0,
|
|
20
|
+
serial_number: 'FFFF'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
expect(described_class.new(params:).message).to eq 'AT+GTQSS=gl310m,net,,,3,,1,218.17.46.11,91,213.175.74.200,' \
|
|
24
|
+
'5682,13824347475,0,0,,,FFFF$'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'raises error on missing params' do
|
|
28
|
+
expect { described_class.new(params: {}).message }.to raise_error(InvalidATGTQSSException)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'raises error on improper params' do
|
|
32
|
+
params =
|
|
33
|
+
{
|
|
34
|
+
password: 'gl310m',
|
|
35
|
+
lte_apn: 'net',
|
|
36
|
+
report_mode: 3,
|
|
37
|
+
buffer_mode: 1,
|
|
38
|
+
main_server_ip: '218.17.46.11',
|
|
39
|
+
main_server_port: 91,
|
|
40
|
+
backup_server_ip: '213.175.74.200',
|
|
41
|
+
backup_server_port: 5682,
|
|
42
|
+
sms_gateway: 13_824_347_475,
|
|
43
|
+
heartbit_interval: 400,
|
|
44
|
+
sack_enable: 0,
|
|
45
|
+
serial_number: 'FFFF'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
expect { described_class.new(params:).message }.to raise_error(InvalidATGTQSSException)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::At::Gtrto do
|
|
6
|
+
it 'creates command when params are valid' do
|
|
7
|
+
params =
|
|
8
|
+
{
|
|
9
|
+
password: 'gl310m',
|
|
10
|
+
sub_command: 0,
|
|
11
|
+
serial_number: 'FFFF'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
expect(described_class.new(params:).message).to eq 'AT+GTRTO=gl310m,0,,,,,,FFFF$'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'raises error on missing params' do
|
|
18
|
+
expect { described_class.new(params: {}).message }.to raise_error(InvalidATGTRTOException)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'raises error on improper params' do
|
|
22
|
+
params =
|
|
23
|
+
{
|
|
24
|
+
password: 'gl310m',
|
|
25
|
+
sub_command: 0xFF,
|
|
26
|
+
serial_number: 'FFFF'
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
expect { described_class.new(params:).message }.to raise_error(InvalidATGTRTOException)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::At::Gtsri do
|
|
6
|
+
it 'creates command when params are valid' do
|
|
7
|
+
params =
|
|
8
|
+
{
|
|
9
|
+
password: 'gl310m',
|
|
10
|
+
report_mode: 3,
|
|
11
|
+
buffer_mode: 1,
|
|
12
|
+
main_server_ip: '218.17.46.11',
|
|
13
|
+
main_server_port: 95,
|
|
14
|
+
backup_server_ip: '213.175.74.200',
|
|
15
|
+
backup_server_port: 5682,
|
|
16
|
+
sms_gateway: 13_824_347_475,
|
|
17
|
+
heartbit_interval: 5,
|
|
18
|
+
sack_enable: 1,
|
|
19
|
+
sms_ack_enable: 1,
|
|
20
|
+
serial_number: 'FFFF'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
expect(described_class.new(params:).message).to eq 'AT+GTSRI=gl310m,3,,1,218.17.46.11,95,213.175.74.200,' \
|
|
24
|
+
'5682,13824347475,5,1,1,,,,FFFF$'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'raises error on missing params' do
|
|
28
|
+
expect { described_class.new(params: {}).message }.to raise_error(InvalidATGTSRIException)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'raises error on improper params' do
|
|
32
|
+
params =
|
|
33
|
+
{
|
|
34
|
+
password: 'gl310m',
|
|
35
|
+
report_mode: 3,
|
|
36
|
+
buffer_mode: 1,
|
|
37
|
+
main_server_ip: '218.17.46.11',
|
|
38
|
+
main_server_port: 95,
|
|
39
|
+
backup_server_ip: '213.175.74.200',
|
|
40
|
+
backup_server_port: 5682,
|
|
41
|
+
sms_gateway: 13_824_347_475,
|
|
42
|
+
heartbit_interval: 5,
|
|
43
|
+
sack_enable: 10,
|
|
44
|
+
sms_ack_enable: 8,
|
|
45
|
+
serial_number: 'FFFF'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
expect { described_class.new(params:).message }.to raise_error(InvalidATGTSRIException)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::At::Gtudf do
|
|
6
|
+
it 'creates command when params are valid' do
|
|
7
|
+
params =
|
|
8
|
+
{
|
|
9
|
+
password: 'gl310m',
|
|
10
|
+
mode: 1,
|
|
11
|
+
group_id: 0,
|
|
12
|
+
input_id_mask: 1_000_000_000,
|
|
13
|
+
debounce_time: 0,
|
|
14
|
+
inzizo_mask: 0,
|
|
15
|
+
outzizo_mask: 0,
|
|
16
|
+
stocmd_id_mask: 1,
|
|
17
|
+
stocmd_ack: 0,
|
|
18
|
+
serial_number: 'FFFF'
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
expect(described_class.new(params:).message).to eq 'AT+GTUDF=gl310m,1,0,1000000000,0,0,0,1,0,,,,,FFFF$'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'raises error on missing params' do
|
|
25
|
+
expect { described_class.new(params: {}).message }.to raise_error(InvalidATGTUDFException)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'raises error on improper params' do
|
|
29
|
+
params =
|
|
30
|
+
{
|
|
31
|
+
password: 'gl310m',
|
|
32
|
+
mode: 1,
|
|
33
|
+
group_id: 0,
|
|
34
|
+
input_id_mask: 1_000_000_000,
|
|
35
|
+
debounce_time: 0,
|
|
36
|
+
inzizo_mask: 0,
|
|
37
|
+
outzizo_mask: 0,
|
|
38
|
+
stocmd_id_mask: 1,
|
|
39
|
+
stocmd_ack: 6,
|
|
40
|
+
serial_number: 'FFFF'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
expect { described_class.new(params:).message }.to raise_error(InvalidATGTUDFException)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::Resp::Gtgsv do
|
|
6
|
+
it 'parses valid response' do
|
|
7
|
+
response = 'F50701,860201061504521,,11,2,11,3,10,4,0,5,22,6,30,9,14,12,34,17,35,19,30,23,20,28,13,20230806094936,3E2C$'
|
|
8
|
+
|
|
9
|
+
parsed_response = described_class.new(response:).hash
|
|
10
|
+
expect(parsed_response).not_to eq({})
|
|
11
|
+
expect(parsed_response['sv_count']).to eq 11
|
|
12
|
+
expect(parsed_response['sv_id_3']).to eq 5
|
|
13
|
+
expect(parsed_response['sv_power_3']).to eq 22
|
|
14
|
+
expect(parsed_response['send_time']).to eq Time.zone.strptime('20230806094936',
|
|
15
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
16
|
+
expect(parsed_response['count_number']).to eq '3E2C$'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::Resp::Gtinf do
|
|
6
|
+
it 'parses valid response' do
|
|
7
|
+
response = 'D40102,0860201061504521,gl310m,42,89860117851087152093,16,99,1,0.1,,4.18,1,1,0,,,20230811034659,100,,36.7,,,20230811114700,00A0$'
|
|
8
|
+
|
|
9
|
+
parsed_response = described_class.new(response:).hash
|
|
10
|
+
expect(parsed_response).not_to eq({})
|
|
11
|
+
expect(parsed_response['state']).to eq 42
|
|
12
|
+
expect(parsed_response['iccid']).to eq 89_860_117_851_087_152_093
|
|
13
|
+
expect(parsed_response['csq_rssi']).to eq 16
|
|
14
|
+
expect(parsed_response['csq_ber']).to eq 99
|
|
15
|
+
expect(parsed_response['external_power_supply']).to eq 1
|
|
16
|
+
expect(parsed_response['mileage']).to eq 0.1
|
|
17
|
+
expect(parsed_response['battery_voltage']).to eq 4.18
|
|
18
|
+
expect(parsed_response['charging']).to eq 1
|
|
19
|
+
expect(parsed_response['led_on']).to eq 1
|
|
20
|
+
expect(parsed_response['gps_on_need']).to eq 0
|
|
21
|
+
expect(parsed_response['last_gps_fix_utc_time']).to eq Time.zone.strptime('20230811034659',
|
|
22
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
23
|
+
expect(parsed_response['battery_percentage']).to eq 100
|
|
24
|
+
expect(parsed_response['temperature']).to eq 36.7
|
|
25
|
+
expect(parsed_response['send_time']).to eq Time.zone.strptime('20230811114700',
|
|
26
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
27
|
+
expect(parsed_response['count_number']).to eq '00A0$'
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::Resp::Gtsos do
|
|
6
|
+
it 'parses valid response' do
|
|
7
|
+
response = 'D40102,015181001707687,,0,0,1,1,0.0,265,116.7,114.015807,22.537240,20230806074855,0460,0000,27BD,0DFC,,100,20230806074855,00F8$'
|
|
8
|
+
|
|
9
|
+
parsed_response = described_class.new(response:).hash
|
|
10
|
+
expect(parsed_response).not_to eq({})
|
|
11
|
+
expect(parsed_response['report_id']).to eq 0
|
|
12
|
+
expect(parsed_response['report_type']).to eq 0
|
|
13
|
+
expect(parsed_response['number']).to eq 1
|
|
14
|
+
expect(parsed_response['gps_accuracy']).to eq 1
|
|
15
|
+
expect(parsed_response['speed']).to eq 0.0
|
|
16
|
+
expect(parsed_response['azimuth']).to eq 265
|
|
17
|
+
expect(parsed_response['altitude']).to eq 116.7
|
|
18
|
+
expect(parsed_response['longitude']).to eq 114.015807
|
|
19
|
+
expect(parsed_response['latitude']).to eq 22.53724
|
|
20
|
+
expect(parsed_response['gps_utc_time']).to eq Time.zone.strptime('20230806074855',
|
|
21
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
22
|
+
expect(parsed_response['mcc']).to eq 460
|
|
23
|
+
expect(parsed_response['mnc']).to eq 0
|
|
24
|
+
expect(parsed_response['lac']).to eq '27BD'
|
|
25
|
+
expect(parsed_response['cel_id']).to eq '0DFC'
|
|
26
|
+
expect(parsed_response['odo_mileage']).to eq ''
|
|
27
|
+
expect(parsed_response['battery_percentage']).to eq 100
|
|
28
|
+
expect(parsed_response['send_time']).to eq Time.zone.strptime('20230806074855',
|
|
29
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
30
|
+
expect(parsed_response['count_number']).to eq '00F8$'
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::Resp::Gtstt do
|
|
6
|
+
it 'parses valid response' do
|
|
7
|
+
response = 'D40102,015181001707687,gl310m,41,1,0.0,40,212.0,114.016205,22.539455,20230811055755,0460,0001,253D,AEC3,0.2,20230811135756,012E$'
|
|
8
|
+
|
|
9
|
+
parsed_response = described_class.new(response:).hash
|
|
10
|
+
expect(parsed_response).not_to eq({})
|
|
11
|
+
expect(parsed_response['state']).to eq 41
|
|
12
|
+
expect(parsed_response['gps_accuracy']).to eq 1
|
|
13
|
+
expect(parsed_response['speed']).to eq 0.0
|
|
14
|
+
expect(parsed_response['azimuth']).to eq 40
|
|
15
|
+
expect(parsed_response['altitude']).to eq 212.0
|
|
16
|
+
expect(parsed_response['last_longitude']).to eq 114.016205
|
|
17
|
+
expect(parsed_response['last_latitude']).to eq 22.539455
|
|
18
|
+
expect(parsed_response['gps_utc_time']).to eq Time.zone.strptime('20230811055755',
|
|
19
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
20
|
+
expect(parsed_response['mcc']).to eq 460
|
|
21
|
+
expect(parsed_response['mnc']).to eq 1
|
|
22
|
+
expect(parsed_response['lac']).to eq '253D'
|
|
23
|
+
expect(parsed_response['cell_id']).to eq 'AEC3'
|
|
24
|
+
expect(parsed_response['odo_mileage']).to eq 0.2
|
|
25
|
+
expect(parsed_response['send_time']).to eq Time.zone.strptime('20230811135756',
|
|
26
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
27
|
+
expect(parsed_response['count_number']).to eq '012E$'
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe QuelinkMg::Resp::Gtupc do
|
|
6
|
+
it 'parses valid response' do
|
|
7
|
+
response = 'D40102,015181001707687,gl310m,0,100,https://www.example.com/UPC_1.ini,20230811142238,0155$'
|
|
8
|
+
|
|
9
|
+
parsed_response = described_class.new(response:).hash
|
|
10
|
+
expect(parsed_response).not_to eq({})
|
|
11
|
+
expect(parsed_response['command_id']).to eq 0
|
|
12
|
+
expect(parsed_response['result']).to eq 100
|
|
13
|
+
expect(parsed_response['download_url']).to eq 'https://www.example.com/UPC_1.ini'
|
|
14
|
+
expect(parsed_response['send_time']).to eq Time.zone.strptime('20230811142238',
|
|
15
|
+
QuelinkMg::Resp::Base::QUELINK_DATE_FORMAT)
|
|
16
|
+
expect(parsed_response['count_number']).to eq '0155$'
|
|
17
|
+
end
|
|
18
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: quelink-mg
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stanislaw Zawadzki
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-09-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -86,27 +86,67 @@ executables: []
|
|
|
86
86
|
extensions: []
|
|
87
87
|
extra_rdoc_files: []
|
|
88
88
|
files:
|
|
89
|
+
- ".github/workflows/test.yml"
|
|
89
90
|
- ".rubocop.yml"
|
|
90
91
|
- Gemfile
|
|
91
92
|
- Gemfile.lock
|
|
92
93
|
- README.md
|
|
93
94
|
- lib/quelink-mg/ack/base.rb
|
|
94
95
|
- lib/quelink-mg/ack/gtbsi.rb
|
|
96
|
+
- lib/quelink-mg/ack/gtcfg.rb
|
|
97
|
+
- lib/quelink-mg/ack/gtcmd.rb
|
|
98
|
+
- lib/quelink-mg/ack/gtfri.rb
|
|
99
|
+
- lib/quelink-mg/ack/gtqss.rb
|
|
100
|
+
- lib/quelink-mg/ack/gtrto.rb
|
|
101
|
+
- lib/quelink-mg/ack/gtsri.rb
|
|
102
|
+
- lib/quelink-mg/ack/gtudf.rb
|
|
95
103
|
- lib/quelink-mg/at/base.rb
|
|
96
104
|
- lib/quelink-mg/at/gtbsi.rb
|
|
105
|
+
- lib/quelink-mg/at/gtcfg.rb
|
|
106
|
+
- lib/quelink-mg/at/gtcmd.rb
|
|
107
|
+
- lib/quelink-mg/at/gtfri.rb
|
|
108
|
+
- lib/quelink-mg/at/gtqss.rb
|
|
109
|
+
- lib/quelink-mg/at/gtrto.rb
|
|
110
|
+
- lib/quelink-mg/at/gtsri.rb
|
|
111
|
+
- lib/quelink-mg/at/gtudf.rb
|
|
97
112
|
- lib/quelink-mg/configuration.rb
|
|
98
113
|
- lib/quelink-mg/resp/base.rb
|
|
99
114
|
- lib/quelink-mg/resp/gtfri.rb
|
|
115
|
+
- lib/quelink-mg/resp/gtgsv.rb
|
|
116
|
+
- lib/quelink-mg/resp/gtinf.rb
|
|
117
|
+
- lib/quelink-mg/resp/gtsos.rb
|
|
118
|
+
- lib/quelink-mg/resp/gtstt.rb
|
|
119
|
+
- lib/quelink-mg/resp/gtupc.rb
|
|
100
120
|
- lib/quelink_mg.rb
|
|
101
121
|
- quelink-mg.gemspec
|
|
102
122
|
- spec/quelink_mg/ack/gtbsi_spec.rb
|
|
123
|
+
- spec/quelink_mg/ack/gtcfg_spec.rb
|
|
124
|
+
- spec/quelink_mg/ack/gtcmd_spec.rb
|
|
125
|
+
- spec/quelink_mg/ack/gtfri_spec.rb
|
|
126
|
+
- spec/quelink_mg/ack/gtqss_spec.rb
|
|
127
|
+
- spec/quelink_mg/ack/gtrto_spec.rb
|
|
128
|
+
- spec/quelink_mg/ack/gtsri_spec.rb
|
|
129
|
+
- spec/quelink_mg/ack/gtudf_spec.rb
|
|
103
130
|
- spec/quelink_mg/at/gtbsi_spec.rb
|
|
131
|
+
- spec/quelink_mg/at/gtcfg_spec.rb
|
|
132
|
+
- spec/quelink_mg/at/gtcmd_spec.rb
|
|
133
|
+
- spec/quelink_mg/at/gtfri_spec.rb
|
|
134
|
+
- spec/quelink_mg/at/gtqss_spec.rb
|
|
135
|
+
- spec/quelink_mg/at/gtrto_spec.rb
|
|
136
|
+
- spec/quelink_mg/at/gtsri_spec.rb
|
|
137
|
+
- spec/quelink_mg/at/gtudf_spec.rb
|
|
104
138
|
- spec/quelink_mg/resp/gtfri_spec.rb
|
|
139
|
+
- spec/quelink_mg/resp/gtgsv_spec.rb
|
|
140
|
+
- spec/quelink_mg/resp/gtinf_spec.rb
|
|
141
|
+
- spec/quelink_mg/resp/gtsos_spec.rb
|
|
142
|
+
- spec/quelink_mg/resp/gtstt_spec.rb
|
|
143
|
+
- spec/quelink_mg/resp/gtupc_spec.rb
|
|
105
144
|
- spec/spec_helper.rb
|
|
106
145
|
homepage:
|
|
107
146
|
licenses:
|
|
108
147
|
- MIT
|
|
109
|
-
metadata:
|
|
148
|
+
metadata:
|
|
149
|
+
rubygems_mfa_required: 'false'
|
|
110
150
|
post_install_message:
|
|
111
151
|
rdoc_options: []
|
|
112
152
|
require_paths:
|