bodytrace 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +91 -0
- data/LICENSE +21 -0
- data/README.md +139 -0
- data/Rakefile +0 -0
- data/bodytrace.gemspec +21 -0
- data/lib/generators/body_trace/USAGE +5 -0
- data/lib/generators/body_trace/install_generator.rb +36 -0
- data/lib/generators/body_trace/templates/bodytrace_measurement.rb.erb +59 -0
- data/lib/generators/body_trace/templates/bodytrace_measurements_controller.rb.erb +99 -0
- data/lib/generators/body_trace/templates/device.rb.erb +84 -0
- data/lib/generators/body_trace/templates/migrations/create_bodytrace_measurements.rb.erb +21 -0
- data/lib/generators/body_trace/templates/migrations/create_devices.rb.erb +16 -0
- metadata +85 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8c83b17d0b9e9d38190e259d567720ad84117b7b
|
4
|
+
data.tar.gz: 9dd92a538fd94bd0617820308167a08301d8b42c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9964d0e5104089418f6bbabe1098d8da2f5774aea07d0a8ee52148442258197017d864fd8a066c0bf3710b5753024389466b58f94a6788c465dae554136710f6
|
7
|
+
data.tar.gz: 8e9369229dbf7a2f05998e78eb2c0e370f213795d4f10ed5f37ab35d9fef21413c93720672c882a58c2c67b83b44379d13cc8181c7793b028cd037e998652623
|
data/.gitignore
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
*.rbc
|
2
|
+
capybara-*.html
|
3
|
+
.rspec
|
4
|
+
/log
|
5
|
+
/tmp
|
6
|
+
/db/*.sqlite3
|
7
|
+
/public/system
|
8
|
+
/coverage/
|
9
|
+
/spec/tmp
|
10
|
+
**.orig
|
11
|
+
rerun.txt
|
12
|
+
pickle-email-*.html
|
13
|
+
config/initializers/secret_token.rb
|
14
|
+
config/secrets.yml
|
15
|
+
|
16
|
+
## Environment normalisation:
|
17
|
+
/.bundle
|
18
|
+
/vendor/bundle
|
19
|
+
|
20
|
+
# these should all be checked in to normalise the environment:
|
21
|
+
# Gemfile.lock, .ruby-version, .ruby-gemset
|
22
|
+
|
23
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
24
|
+
.rvmrc
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
bodytrace (1.1.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
actionmailer (4.1.4)
|
10
|
+
actionpack (= 4.1.4)
|
11
|
+
actionview (= 4.1.4)
|
12
|
+
mail (~> 2.5.4)
|
13
|
+
actionpack (4.1.4)
|
14
|
+
actionview (= 4.1.4)
|
15
|
+
activesupport (= 4.1.4)
|
16
|
+
rack (~> 1.5.2)
|
17
|
+
rack-test (~> 0.6.2)
|
18
|
+
actionview (4.1.4)
|
19
|
+
activesupport (= 4.1.4)
|
20
|
+
builder (~> 3.1)
|
21
|
+
erubis (~> 2.7.0)
|
22
|
+
activemodel (4.1.4)
|
23
|
+
activesupport (= 4.1.4)
|
24
|
+
builder (~> 3.1)
|
25
|
+
activerecord (4.1.4)
|
26
|
+
activemodel (= 4.1.4)
|
27
|
+
activesupport (= 4.1.4)
|
28
|
+
arel (~> 5.0.0)
|
29
|
+
activesupport (4.1.4)
|
30
|
+
i18n (~> 0.6, >= 0.6.9)
|
31
|
+
json (~> 1.7, >= 1.7.7)
|
32
|
+
minitest (~> 5.1)
|
33
|
+
thread_safe (~> 0.1)
|
34
|
+
tzinfo (~> 1.1)
|
35
|
+
arel (5.0.1.20140414130214)
|
36
|
+
builder (3.2.2)
|
37
|
+
erubis (2.7.0)
|
38
|
+
hike (1.2.3)
|
39
|
+
i18n (0.6.9)
|
40
|
+
json (1.8.1)
|
41
|
+
mail (2.5.4)
|
42
|
+
mime-types (~> 1.16)
|
43
|
+
treetop (~> 1.4.8)
|
44
|
+
mime-types (1.25.1)
|
45
|
+
minitest (5.3.5)
|
46
|
+
multi_json (1.10.1)
|
47
|
+
polyglot (0.3.5)
|
48
|
+
rack (1.5.2)
|
49
|
+
rack-test (0.6.2)
|
50
|
+
rack (>= 1.0)
|
51
|
+
rails (4.1.4)
|
52
|
+
actionmailer (= 4.1.4)
|
53
|
+
actionpack (= 4.1.4)
|
54
|
+
actionview (= 4.1.4)
|
55
|
+
activemodel (= 4.1.4)
|
56
|
+
activerecord (= 4.1.4)
|
57
|
+
activesupport (= 4.1.4)
|
58
|
+
bundler (>= 1.3.0, < 2.0)
|
59
|
+
railties (= 4.1.4)
|
60
|
+
sprockets-rails (~> 2.0)
|
61
|
+
railties (4.1.4)
|
62
|
+
actionpack (= 4.1.4)
|
63
|
+
activesupport (= 4.1.4)
|
64
|
+
rake (>= 0.8.7)
|
65
|
+
thor (>= 0.18.1, < 2.0)
|
66
|
+
rake (10.3.2)
|
67
|
+
sprockets (2.12.1)
|
68
|
+
hike (~> 1.2)
|
69
|
+
multi_json (~> 1.0)
|
70
|
+
rack (~> 1.0)
|
71
|
+
tilt (~> 1.1, != 1.3.0)
|
72
|
+
sprockets-rails (2.1.3)
|
73
|
+
actionpack (>= 3.0)
|
74
|
+
activesupport (>= 3.0)
|
75
|
+
sprockets (~> 2.8)
|
76
|
+
thor (0.19.1)
|
77
|
+
thread_safe (0.3.4)
|
78
|
+
tilt (1.4.1)
|
79
|
+
treetop (1.4.15)
|
80
|
+
polyglot
|
81
|
+
polyglot (>= 0.3.1)
|
82
|
+
tzinfo (1.2.1)
|
83
|
+
thread_safe (~> 0.1)
|
84
|
+
|
85
|
+
PLATFORMS
|
86
|
+
ruby
|
87
|
+
|
88
|
+
DEPENDENCIES
|
89
|
+
bodytrace!
|
90
|
+
rails (>= 4.0.0)
|
91
|
+
rake
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Mohammad Aboelnour
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
BodyTrace
|
2
|
+
=========
|
3
|
+
|
4
|
+
BodyTrace is a Ruby gem enabling receiving and storing requests from [BodyTrace](http://bodytrace.com/medical/)'s digital scale:
|
5
|
+

|
6
|
+
|
7
|
+
###Installation
|
8
|
+
run:
|
9
|
+
```
|
10
|
+
gem install bodytrace
|
11
|
+
```
|
12
|
+
or add to your Gemfile:
|
13
|
+
```
|
14
|
+
gem 'bodytrace'
|
15
|
+
```
|
16
|
+
|
17
|
+
###Usage
|
18
|
+
this gem generate a platform to catch/store BodyTrace's digital scale POST requests in this format:
|
19
|
+
>{"deviceId":XXXXXXXXXXXXX,"ts":1380562575798,"batteryVoltage":5522,"rssi":91,"values
|
20
|
+
":{"unit":1,"weight":69800,"tare":0}}
|
21
|
+
|
22
|
+
Where:
|
23
|
+
|
24
|
+
* deviceId: [IMEI](http://en.wikipedia.org/wiki/International_Mobile_Station_Equipment_Identity) serial number (without leading zeros and the last digit)
|
25
|
+
|
26
|
+
* ts: timestamp when the measurement was taken represented in milliseconds since UNIX Epoch, UTC
|
27
|
+
|
28
|
+
* batteryVoltage: battery voltage (mV) - functional battery voltage range: 4.7-6.0 V (could
|
29
|
+
go a little over 6.0 V)
|
30
|
+
|
31
|
+
* rssi: signal strength in (- dBm) - can be converted into "percentage" by this formula:
|
32
|
+
min(0, max(1, (115 - rssi) / 52)) * 100
|
33
|
+
|
34
|
+
* values/unit: measurement unit the scale was in at the time of taking the measurement
|
35
|
+
|
36
|
+
* values/weight: weight value (in grams - regardless of unit)
|
37
|
+
* values/tare: It shows the difference between the zero point setting before the weigh-in and after. If it is greater than + 0.1 kg, that means that the scale has a calibration error and the value sent as the weight value was offset by the amount indicated in the tare value.
|
38
|
+
|
39
|
+
---
|
40
|
+
|
41
|
+
run:
|
42
|
+
```
|
43
|
+
rails g body_trace:install user_name password BodytraceMeasurement Device User
|
44
|
+
```
|
45
|
+
|
46
|
+
where:
|
47
|
+
####user_name [Required]:
|
48
|
+
> http authentication user_name required to parse BodyTrace requests.
|
49
|
+
|
50
|
+
####password [Required]:
|
51
|
+
> http authentication password required to parse BodyTrace requests.
|
52
|
+
|
53
|
+
####BodytraceMeasurement [Optional & default: BodytraceMeasurement]
|
54
|
+
> Name of the model which will hold requests data comes from BodyTrace API.
|
55
|
+
|
56
|
+
####Device [Optional & default: Device]:
|
57
|
+
> Name of the model which will hold information about "which user uses which scale device"
|
58
|
+
|
59
|
+
####User [Optional & default: User]:
|
60
|
+
> Name of already existing "user" model that will be used to link with a scale device.
|
61
|
+
|
62
|
+
|
63
|
+
this will generate:
|
64
|
+
```
|
65
|
+
route resources :bodytrace_measurements, only: [:create]
|
66
|
+
create app/models/bodytrace_measurement.rb
|
67
|
+
create app/models/device.rb
|
68
|
+
create app/controllers/bodytrace_measurements_controller.rb
|
69
|
+
create db/migrate/20140707135956_create_bodytrace_measurements.rb
|
70
|
+
create db/migrate/20140707135957_create_devices.rb
|
71
|
+
|
72
|
+
```
|
73
|
+
|
74
|
+
---
|
75
|
+
Then run:
|
76
|
+
```
|
77
|
+
rake db:migrate
|
78
|
+
```
|
79
|
+
---
|
80
|
+
|
81
|
+
And finally:
|
82
|
+
|
83
|
+
Provide [BodyTrace Team](http://www.bodytrace.com/contact.html) with a URL to [POST] Requests on it. In above example URL will be:
|
84
|
+
```
|
85
|
+
[POST] sitename.com/bodytrace_measurements
|
86
|
+
```
|
87
|
+
and provide them with user_name and password you generated for HTTP basic authentication.
|
88
|
+
|
89
|
+
---
|
90
|
+
|
91
|
+
###list of supported Requests / Responses :
|
92
|
+
|
93
|
+
Request: # heartbeat message
|
94
|
+
> {"deviceId":XXXXXXXXXXXXX,"ts":1391436314212,"batteryVoltage":5603,"rssi":80,"values":{}}
|
95
|
+
|
96
|
+
Response:
|
97
|
+
> 204 - No content
|
98
|
+
|
99
|
+
---
|
100
|
+
|
101
|
+
Request: # real error-free request
|
102
|
+
> {"deviceId":XXXXXXXXXXXXX,"ts":1380562575798,"batteryVoltage":5522,"rssi":91,"values":{"unit":1,"weight":69800}}
|
103
|
+
|
104
|
+
Response:
|
105
|
+
> 200 - OK
|
106
|
+
|
107
|
+
---------------
|
108
|
+
|
109
|
+
Request: # receiving "deviceId" not registered with a user
|
110
|
+
> {"deviceId":XXXXXXXXXXXXX,"ts":1380562575798,"batteryVoltage":5522,"rssi":91,"values":{"unit":1,"weight":69800}
|
111
|
+
|
112
|
+
Response:
|
113
|
+
> 404 - Not Found
|
114
|
+
|
115
|
+
---------------
|
116
|
+
|
117
|
+
Request: # missing parameter request, missing "deviceId"
|
118
|
+
> {"ts":1380562575798,"batteryVoltage":5522,"rssi":91,"values":{"unit":1,"weight":69800}}
|
119
|
+
|
120
|
+
Response:
|
121
|
+
> 422 - unprocessable entity
|
122
|
+
|
123
|
+
---------------
|
124
|
+
|
125
|
+
Request: # missing parameter request, missing "values" paramter
|
126
|
+
>{"deviceId":XXXXXXXXXXXXX,"ts":1380562575798,"batteryVoltage":5522,"rssi":91}}
|
127
|
+
|
128
|
+
Response:
|
129
|
+
> 422 - unprocessable entity
|
130
|
+
|
131
|
+
---------------
|
132
|
+
|
133
|
+
Request: # syntax-error in the request parameters, missing '}'
|
134
|
+
> {"deviceId":XXXXXXXXXXXXX,"ts":1380562575798,"batteryVoltage":5522,"rssi":91,"values":{"unit":1,"weight":69800}
|
135
|
+
|
136
|
+
Response:
|
137
|
+
> 400 - Bad Request
|
138
|
+
|
139
|
+
---------------
|
data/Rakefile
ADDED
File without changes
|
data/bodytrace.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "bodytrace"
|
5
|
+
s.version = "1.2.1"
|
6
|
+
s.platform = "ruby"
|
7
|
+
s.authors = ["Mohammad Aboelnour"]
|
8
|
+
s.email = ["mhm.aboelnour@gmail.com"]
|
9
|
+
s.homepage = "https://github.com/maboelnour/bodytrace"
|
10
|
+
s.summary = %q{A rails gem for BodyTrace}
|
11
|
+
s.description = %q{This gem will install a platform to handle BodyTrace requests}
|
12
|
+
s.files = `git ls-files`.split("\n")
|
13
|
+
s.test_files = `git ls-files -- {requests,support}/*`.split("\n")
|
14
|
+
s.require_paths = ["lib"]
|
15
|
+
|
16
|
+
s.add_development_dependency 'rails', '>= 4.0.0'
|
17
|
+
s.add_development_dependency 'rake'
|
18
|
+
# s.add_development_dependency 'rspec-rails'
|
19
|
+
# s.add_development_dependency 'factory_girl_rails'
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module BodyTrace
|
2
|
+
class InstallGenerator < Rails::Generators::Base
|
3
|
+
include Rails::Generators::Migration
|
4
|
+
|
5
|
+
source_root File.expand_path('../templates', __FILE__)
|
6
|
+
argument :user_name, type: :string
|
7
|
+
argument :password, type: :string
|
8
|
+
argument :measurement_model, type: :string, default: "BodytraceMeasurement"
|
9
|
+
argument :device_model, type: :string, default: "Device"
|
10
|
+
argument :user_model, type: :string, default: "User"
|
11
|
+
|
12
|
+
def setup_routes
|
13
|
+
route "resources :#{measurement_model.underscore.pluralize}, only: [:create]"
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup_models
|
17
|
+
template "bodytrace_measurement.rb.erb", "app/models/#{measurement_model.underscore}.rb"
|
18
|
+
template "device.rb.erb", "app/models/#{device_model.underscore}.rb"
|
19
|
+
end
|
20
|
+
|
21
|
+
def setup_controllers
|
22
|
+
template "bodytrace_measurements_controller.rb.erb", "app/controllers/#{measurement_model.underscore.pluralize}_controller.rb"
|
23
|
+
end
|
24
|
+
|
25
|
+
def setup_migrations
|
26
|
+
migration_template "migrations/create_bodytrace_measurements.rb.erb", "db/migrate/create_#{measurement_model.underscore.pluralize}.rb"
|
27
|
+
migration_template "migrations/create_devices.rb.erb", "db/migrate/create_#{device_model.underscore.pluralize}.rb"
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.next_migration_number(path)
|
31
|
+
sleep 1
|
32
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Table name: bodytrace_measurements
|
4
|
+
#
|
5
|
+
# id :integer not null, primary key
|
6
|
+
# bodytrace_device_id :integer
|
7
|
+
# unix_timestamp :integer
|
8
|
+
# battery_voltage :integer
|
9
|
+
# signal_strength :integer
|
10
|
+
# scale_unit :integer
|
11
|
+
# grams :integer
|
12
|
+
# json_object :text
|
13
|
+
# user_id :integer
|
14
|
+
# created_at :datetime
|
15
|
+
# updated_at :datetime
|
16
|
+
#
|
17
|
+
|
18
|
+
|
19
|
+
class <%= measurement_model %> < ActiveRecord::Base
|
20
|
+
|
21
|
+
##
|
22
|
+
# => +-----+--------+---------------------+-----+
|
23
|
+
# | ... |user_id | bodytrace_device_id | ... |
|
24
|
+
# +-----+--------+---------------------+-----+
|
25
|
+
# | | | | |
|
26
|
+
# | | | | |
|
27
|
+
# | | | | |
|
28
|
+
# | | | | |
|
29
|
+
# | | | | |
|
30
|
+
# | | | | |
|
31
|
+
# +-----+--------+---------------------+-----+
|
32
|
+
# ^
|
33
|
+
# |
|
34
|
+
# index
|
35
|
+
#
|
36
|
+
# Insertion: only @ 1 scenario: when getting POST request with json params.
|
37
|
+
# Updating: no scenarios.
|
38
|
+
# Deleting: no scenarios.
|
39
|
+
##
|
40
|
+
validates :bodytrace_device_id, :unix_timestamp, :battery_voltage,
|
41
|
+
:signal_strength, :scale_unit, :grams, presence: { message: "%{value}: is required and it's submitted as blank!" }
|
42
|
+
belongs_to :user
|
43
|
+
|
44
|
+
##
|
45
|
+
# => the "no_assigned_user" scope fetches the bodytrace_measurement which it's
|
46
|
+
# "bodytrace_device_id" not owned by any user by checking if user_id IS NULL
|
47
|
+
##
|
48
|
+
UNITS = ["kg", "lb", "st"]
|
49
|
+
scope :no_assigned_<%= user_model.underscore %>, -> { where('<%= user_model.underscore %>_id IS NULL') }
|
50
|
+
|
51
|
+
def <%= user_model.underscore %>
|
52
|
+
<%= user_model %>.find self.<%= user_model.underscore %>_id unless (<%= user_model.underscore %>_id == -1 || <%= user_model.underscore %>_id.nil?)
|
53
|
+
end
|
54
|
+
|
55
|
+
def scale_unit
|
56
|
+
UNITS[read_attribute(:scale_unit)]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
@@ -0,0 +1,99 @@
|
|
1
|
+
class <%= measurement_model.pluralize %>Controller < ApplicationController
|
2
|
+
|
3
|
+
http_basic_authenticate_with name: "<%= user_name %>", password: "<%= password %>"
|
4
|
+
skip_before_action :verify_authenticity_token
|
5
|
+
|
6
|
+
##
|
7
|
+
# => This action catchs the HTTP POST request from "BodyTrac" server and parse the passed JSON object.
|
8
|
+
#
|
9
|
+
# => JSON structure is: {"deviceId":***,"ts":***,"batteryVoltage":***,"rssi":**,
|
10
|
+
# "values":{"unit":***,"weight":***}}
|
11
|
+
# where: -deviceId : IMEI (without leading zeros and the last digit).
|
12
|
+
# -ts: timestamp when the measurement was taken (milliseconds since UNIX Epoch, UTC)
|
13
|
+
# -batteryVoltage: battery voltage (mV) - functional battery voltage range: 4.7-6.0 V (could go a little over 6.0 V)
|
14
|
+
# -rssi: signal strength in (- dBm) - can be converted into "percentage" by this formula: min(0, max(1, (115 - rssi) / 52)) * 100
|
15
|
+
# -values/unit: measurement unit the scale was in at the time of taking the measurement
|
16
|
+
# -values/weight: weight value (in grams - regardless of unit)
|
17
|
+
# -values/tare: The tare value can be used to compensate for this calibration errors.
|
18
|
+
# It shows the difference between the zero point setting before the weigh-in and after.
|
19
|
+
# If it is greater than + 0.1 kg, that means that the scale was not stored on a flat surface and
|
20
|
+
# the value shown on the display (and sent as the weight value) was offset by the amount indicated in the tare value.
|
21
|
+
#
|
22
|
+
#
|
23
|
+
# => Workflow:
|
24
|
+
# - Getting the POST request with the Json params.
|
25
|
+
# - Check if "values" hash exists if not: -log error & -send error email & respond with "422 - Unprocessable Entity"
|
26
|
+
# - Check if "values" hash is empty: if empty: -it's a heartbeat message, if not it's a real request
|
27
|
+
# - Check if any params is missing then: -log error & -send error email & respond with "422 - Unprocessable Entity"
|
28
|
+
# - Check if "deviceId" is registered with a user.
|
29
|
+
# => In case of "deviceId" Not Found:
|
30
|
+
# - storing the request with the json params in <%= measurement_model %> with
|
31
|
+
# <%=user_model.underscore%>_id = nil
|
32
|
+
# - make a comment on the request active_admin page, indicates that the "deviceId"
|
33
|
+
# hasn't registered user
|
34
|
+
# - respond with "404 - NOT FOUND"
|
35
|
+
# => In case of "deviceId" Found:
|
36
|
+
# - check if "tare" value over "100" or under "-100" if true then adjust the weight.
|
37
|
+
# - storing the request with the json params in <%= measurement_model %> with user_id = registered user_id
|
38
|
+
# - respond with "200 - OK"
|
39
|
+
##
|
40
|
+
|
41
|
+
def create
|
42
|
+
I18n.locale = :en
|
43
|
+
|
44
|
+
unless request[:values].nil?
|
45
|
+
|
46
|
+
unless request[:values].empty? # checks it the request is a heartbeat message or not
|
47
|
+
user_id = -1
|
48
|
+
device = <%= device_model %>.find_by(bodytrace_device_id: request[:deviceId]) # check if device registered with a user or not?
|
49
|
+
user_id = device.<%= user_model.underscore %>.id unless device.nil?
|
50
|
+
|
51
|
+
calculated_grams = request[:values][:weight]
|
52
|
+
|
53
|
+
calculated_grams -= request[:values][:tare] if request[:values][:tare].to_i > 100 || request[:values][:tare].to_i < -100
|
54
|
+
|
55
|
+
bodytrace_measurement = <%= measurement_model %>.new(bodytrace_device_id: request[:deviceId],
|
56
|
+
unix_timestamp: request[:ts], battery_voltage: request[:batteryVoltage],
|
57
|
+
signal_strength: request[:rssi], scale_unit: request[:values][:unit],
|
58
|
+
grams: calculated_grams, json_object: request.raw_post, <%= user_model.underscore %>_id: user_id)
|
59
|
+
|
60
|
+
begin
|
61
|
+
bodytrace_measurement.save!
|
62
|
+
if user_id == -1 # render 404 if "devicId" not registered with a user, else render 200
|
63
|
+
render nothing: true, status: 404
|
64
|
+
else
|
65
|
+
render nothing: true, status: 200
|
66
|
+
end
|
67
|
+
rescue StandardError => e # error in saving the request due to some params are missing
|
68
|
+
log_error request.raw_post, e
|
69
|
+
end
|
70
|
+
|
71
|
+
else # it's a heartbeat message
|
72
|
+
log_heartbeat_message(request.raw_post)
|
73
|
+
end
|
74
|
+
|
75
|
+
else # Values param which contains the wieght grams is missing so it's error
|
76
|
+
log_error(request.raw_post, "\"Values\" param is missing!")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# => this method logs a given error in the console, and send error email with error message
|
82
|
+
# => params:
|
83
|
+
# - params: POST request params.
|
84
|
+
# - message: error_message printed in the email.
|
85
|
+
##
|
86
|
+
private
|
87
|
+
def log_error params, message
|
88
|
+
logger.error "\n\n######## Can't save <%= measurement_model %> due to some missing params\n"+
|
89
|
+
"================\n#{params.inspect}\n Respond with [422 unprocessable entity] \n"+
|
90
|
+
"#{message}\n================\n"
|
91
|
+
render nothing: true, status: 422 # 422: The request was well-formed but was unable to be followed due to semantic errors
|
92
|
+
end
|
93
|
+
|
94
|
+
def log_heartbeat_message params
|
95
|
+
logger.info "\n\n######## recieved a heartbeat message\n"+
|
96
|
+
"================\n#{params.inspect}\n Respond with [200 OK]\n================\n"
|
97
|
+
render nothing: true, status: 204
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Table name: devices
|
4
|
+
#
|
5
|
+
# id :integer not null, primary key
|
6
|
+
# user_id :integer
|
7
|
+
# bodytrace_device_id :integer
|
8
|
+
# imei_device_serial :string(255)
|
9
|
+
# created_at :datetime
|
10
|
+
# updated_at :datetime
|
11
|
+
#
|
12
|
+
|
13
|
+
class <%= device_model %> < ActiveRecord::Base
|
14
|
+
|
15
|
+
##
|
16
|
+
# => +-----+--------+---------------------+--------------------+
|
17
|
+
# | ... |user_id | bodytrace_device_id | imei_device_serial |
|
18
|
+
# +-----+--------+---------------------+--------------------+
|
19
|
+
# | | | | |
|
20
|
+
# | | | | |
|
21
|
+
# | | | | |
|
22
|
+
# | | | | |
|
23
|
+
# | | | | |
|
24
|
+
# | | | | |
|
25
|
+
# +-----+--------+---------------------+--------------------+
|
26
|
+
# ^ ^
|
27
|
+
# | |
|
28
|
+
# index , uniq uniq
|
29
|
+
#
|
30
|
+
# Insertion: only @ 1 scenario: when linking user with a device.
|
31
|
+
# Updating: only @ 1 scenario: when updating user with a device.
|
32
|
+
# Deleting: only @ 1 scenario: when unlinking user with a device.
|
33
|
+
# Triggers: - @insertion:
|
34
|
+
# get bodytrace measurement with the 'bodytrace_device_id' and if found update # bodytrace_measurements.<%= user_model.underscore %>_id =
|
35
|
+
# self.<%= user_model.underscore %>_id
|
36
|
+
##
|
37
|
+
|
38
|
+
validates :<%= user_model.underscore %>_id, presence: true
|
39
|
+
validates :imei_device_serial, presence: true
|
40
|
+
validates :imei_device_serial, length: { is: 15 }
|
41
|
+
validates :<%= user_model.underscore %>_id, :imei_device_serial, uniqueness: true
|
42
|
+
|
43
|
+
belongs_to :<%= user_model.underscore %>
|
44
|
+
|
45
|
+
before_save :normalize_imei_device_serial
|
46
|
+
after_save :update_bodytrace_measurements
|
47
|
+
before_destroy :clear_bodytrace_measurements
|
48
|
+
|
49
|
+
##
|
50
|
+
# => this method normalize the imei device serial (which used to link user with the bodyTrace device)
|
51
|
+
# and saves the normalized number to "bodytrace_device_id"
|
52
|
+
# => the normalization proccess:
|
53
|
+
# - removing any leading zeros.
|
54
|
+
# - removing the last digit.
|
55
|
+
##
|
56
|
+
private
|
57
|
+
def normalize_imei_device_serial
|
58
|
+
# converting to integer revmoving any leading zeros
|
59
|
+
# integer division by 10 removing the last digit.
|
60
|
+
self.bodytrace_device_id = (self.imei_device_serial.to_i)/10
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# => this method traverse <%= measurement_model.pluralize %>s with self device_id to set user_id
|
65
|
+
# => this scenario happens if BodyTrace sent requests before we link the user with the device
|
66
|
+
##
|
67
|
+
private
|
68
|
+
def update_bodytrace_measurements
|
69
|
+
measurements = <%= measurement_model %>.where(bodytrace_device_id: self.bodytrace_device_id)
|
70
|
+
measurements.each do |m|
|
71
|
+
m.<%= user_model.underscore %>_id = self.<%= user_model.underscore %>_id
|
72
|
+
m.save!
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
def clear_bodytrace_measurements
|
78
|
+
measurements = <%= measurement_model %>.where(bodytrace_device_id: self.bodytrace_device_id)
|
79
|
+
measurements.each do |m|
|
80
|
+
m.<%= user_model.underscore %>_id = -1
|
81
|
+
m.save!
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Create<%= measurement_model.pluralize %> < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
create_table :<%= measurement_model.underscore.pluralize %> do |t|
|
4
|
+
t.integer :bodytrace_device_id, :limit => 5
|
5
|
+
t.integer :unix_timestamp, :limit => 5
|
6
|
+
t.integer :battery_voltage
|
7
|
+
t.integer :signal_strength
|
8
|
+
t.integer :scale_unit, limit: 2
|
9
|
+
t.integer :grams
|
10
|
+
t.text :json_object
|
11
|
+
t.references :<%= user_model.underscore %>, index: true
|
12
|
+
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def down
|
18
|
+
drop_table :<%= measurement_model.underscore.pluralize %>
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Create<%= device_model.pluralize %> < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
create_table :<%= device_model.underscore.pluralize %> do |t|
|
4
|
+
t.references :<%= user_model.underscore %>
|
5
|
+
t.integer :bodytrace_device_id, limit: 5, index: true
|
6
|
+
t.string :imei_device_serial
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def down
|
13
|
+
drop_table :<%= device_model.underscore.pluralize %>
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bodytrace
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mohammad Aboelnour
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.0.0
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: This gem will install a platform to handle BodyTrace requests
|
42
|
+
email:
|
43
|
+
- mhm.aboelnour@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- Gemfile
|
50
|
+
- Gemfile.lock
|
51
|
+
- LICENSE
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- bodytrace.gemspec
|
55
|
+
- lib/generators/body_trace/USAGE
|
56
|
+
- lib/generators/body_trace/install_generator.rb
|
57
|
+
- lib/generators/body_trace/templates/bodytrace_measurement.rb.erb
|
58
|
+
- lib/generators/body_trace/templates/bodytrace_measurements_controller.rb.erb
|
59
|
+
- lib/generators/body_trace/templates/device.rb.erb
|
60
|
+
- lib/generators/body_trace/templates/migrations/create_bodytrace_measurements.rb.erb
|
61
|
+
- lib/generators/body_trace/templates/migrations/create_devices.rb.erb
|
62
|
+
homepage: https://github.com/maboelnour/bodytrace
|
63
|
+
licenses: []
|
64
|
+
metadata: {}
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 2.2.2
|
82
|
+
signing_key:
|
83
|
+
specification_version: 4
|
84
|
+
summary: A rails gem for BodyTrace
|
85
|
+
test_files: []
|