fluent-plugin-everysense 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +36 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +84 -0
- data/Rakefile +10 -0
- data/fluent-plugin-everysense.gemspec +27 -0
- data/lib/fluent/plugin/everysense_proxy.rb +136 -0
- data/lib/fluent/plugin/in_everysense.rb +86 -0
- data/lib/fluent/plugin/out_everysense.rb +58 -0
- data/tutorial/ja/json_over_http_api_tutorial.md +119 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b65915adad0fd2a9922936d6902098e070d9a4a5
|
4
|
+
data.tar.gz: e1cbc37c6759f0ee1ce2f3c0f0ce7c0544bf0e8e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3df7f3708cfc8f66f89e9c0fc6d71b43599599fa67740870a935921fc2f4ac6415595818ea4bc0b0d5b869d7553fe0d436d356d00ea88a1282cac57aaca96f26
|
7
|
+
data.tar.gz: ac200dd0e86b6d0b2563ca31606a836d2f427f7cf9936b0371293dabc633fa0eb07162ca2dd13cc591daa0c91bb8dc5258db4a797d4374698d9ecc637ffc5fc6
|
data/.gitignore
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/spec/examples.txt
|
9
|
+
/test/tmp/
|
10
|
+
/test/version_tmp/
|
11
|
+
/tmp/
|
12
|
+
|
13
|
+
## Specific to RubyMotion:
|
14
|
+
.dat*
|
15
|
+
.repl_history
|
16
|
+
build/
|
17
|
+
|
18
|
+
## Documentation cache and generated files:
|
19
|
+
/.yardoc/
|
20
|
+
/_yardoc/
|
21
|
+
/doc/
|
22
|
+
/rdoc/
|
23
|
+
|
24
|
+
## Environment normalization:
|
25
|
+
/.bundle/
|
26
|
+
/vendor/bundle
|
27
|
+
/lib/bundler/man/
|
28
|
+
|
29
|
+
# for a library or gem, you might want to ignore these files since the code is
|
30
|
+
# intended to run in multiple environments; otherwise, check them in:
|
31
|
+
# Gemfile.lock
|
32
|
+
# .ruby-version
|
33
|
+
# .ruby-gemset
|
34
|
+
|
35
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
36
|
+
.rvmrc
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Toyokazu Akiyama
|
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,84 @@
|
|
1
|
+
# fluent-plugin-everysense
|
2
|
+
Fluent Input/Output Plugin for EverySense platform
|
3
|
+
|
4
|
+
## What is EverySense?
|
5
|
+
|
6
|
+
Collecting personal data is one of the key points in IoT applications. However, it is basically difficult to search people who can provide own sensor data and to motivate people for providing own data to the world. [EverySense](http://every-sense.com/) is a platform to exchange sensor data which can define own recipe to search the data provider matching the condition. It also provide "point" mechanism to motivate people for providing own data. The "point" can be exchanged with the other sensor data or goods like general creadit card point.
|
7
|
+
|
8
|
+
This plugin provides input/output function to [EverySense platform](https://service.every-sense.com/). Data from fluentd event can be uploaded to EverySense and the data provided from EverySense can be posted into fluentd network.
|
9
|
+
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
```
|
14
|
+
gem install fluent-plugin-everysense
|
15
|
+
```
|
16
|
+
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
fluent-plugin-everysense has Input and Output Plugins for EverySense platform.
|
21
|
+
|
22
|
+
|
23
|
+
### Input Plugin (Fluent::EverySenseInput)
|
24
|
+
|
25
|
+
Input Plugin can be used via source directive in the configuration.
|
26
|
+
|
27
|
+
```
|
28
|
+
<source>
|
29
|
+
@type everysense
|
30
|
+
format json
|
31
|
+
tag tag_name
|
32
|
+
login_name your_login_name
|
33
|
+
password your_password
|
34
|
+
device_id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx
|
35
|
+
polling_interval 15
|
36
|
+
</source>
|
37
|
+
```
|
38
|
+
|
39
|
+
- **format** (required): type of parser can be specified to parse input data
|
40
|
+
- **tag** (required): tag name appended to the input data inside fluentd network
|
41
|
+
- **login_name** (required): login_name to login https://service.every-sense.com/
|
42
|
+
- **password** (required): password for the login_name
|
43
|
+
- **device_id** (required): the target device id to obtain input data
|
44
|
+
- **polling_interval**: interval to poll EverySense JSON over HTTP API
|
45
|
+
|
46
|
+
|
47
|
+
### Output Plugin (Fluent::EverySenseOutput)
|
48
|
+
|
49
|
+
Output Plugin can be used via match directive.
|
50
|
+
|
51
|
+
```
|
52
|
+
<match tag_name>
|
53
|
+
@type everysense
|
54
|
+
login_name your_login_name
|
55
|
+
password your_password
|
56
|
+
format json
|
57
|
+
device_id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx
|
58
|
+
</match>
|
59
|
+
```
|
60
|
+
|
61
|
+
- **format** (required): type of formatter can be specified to parse input data
|
62
|
+
- **login_name** (required): login_name to login https://service.every-sense.com/
|
63
|
+
- **password** (required): password for the login_name
|
64
|
+
- **device_id** (required): the target device id to submit sensor data
|
65
|
+
|
66
|
+
|
67
|
+
## TODO
|
68
|
+
|
69
|
+
Recipe related function is not implemented yet.
|
70
|
+
|
71
|
+
|
72
|
+
## Contributing
|
73
|
+
|
74
|
+
1. Fork it ( http://github.com/toyokazu/fluent-plugin-everysense/fork )
|
75
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
76
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
77
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
78
|
+
5. Create new Pull Request
|
79
|
+
|
80
|
+
|
81
|
+
## License
|
82
|
+
|
83
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
84
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "fluent-plugin-everysense"
|
7
|
+
spec.version = "0.0.1"
|
8
|
+
spec.authors = ["Toyokazu Akiyama"]
|
9
|
+
spec.email = ["toyokazu@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{Fluent Input/Output plugin for EverySense Framework}
|
12
|
+
spec.description = %q{Fluent Input/Output plugin for EverySense Framework}
|
13
|
+
spec.homepage = "https://github.com/toyokazu/fluent-plugin-everysense"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.gsub(/images\/[\w\.]+\n/, "").split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.required_ruby_version = '>= 2.0.0'
|
22
|
+
|
23
|
+
spec.add_dependency 'fluentd', '>= 0.10.0'
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
module Fluent
|
2
|
+
module EverySenseProxy
|
3
|
+
require 'uri'
|
4
|
+
require 'net/http'
|
5
|
+
require 'json'
|
6
|
+
require 'time'
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
base.desc 'EverySense API URI'
|
10
|
+
base.config_param :url, :string, :default => 'https://api.every-sense.com:8001/'
|
11
|
+
base.desc 'login_name for EverySense API'
|
12
|
+
base.config_param :login_name, :string, :default => nil # TODO: mandatory option
|
13
|
+
base.desc 'password for EverySense API'
|
14
|
+
base.config_param :password, :string, :default => nil # TODO: mandatory option
|
15
|
+
base.config_param :device_id, :string, :default => nil # TODO: mandatory option
|
16
|
+
base.config_param :recipe_id, :string, :default => nil
|
17
|
+
base.config_param :format, :string, :default => 'json'
|
18
|
+
#base.config_param :keep_alive, :integer, :default => 2
|
19
|
+
base.config_param :from, :string, :default => Time.now.iso8601
|
20
|
+
end
|
21
|
+
|
22
|
+
def start_proxy
|
23
|
+
$log.debug "start everysense proxy #{@uri}"
|
24
|
+
|
25
|
+
@uri = URI.parse(@url)
|
26
|
+
@https = Net::HTTP.new(@uri.host, @uri.port)
|
27
|
+
@https.use_ssl = (@uri.scheme == 'https')
|
28
|
+
@session_key = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def shutdown_proxy
|
32
|
+
delete_session
|
33
|
+
end
|
34
|
+
|
35
|
+
def error_handler(response, message)
|
36
|
+
if response.code != "200"
|
37
|
+
$log.error :error => message
|
38
|
+
$log.debug "code: #{response.code}"
|
39
|
+
$log.debug "message: #{response.message}"
|
40
|
+
$log.debug "body: #{response.body}"
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
return true
|
44
|
+
end
|
45
|
+
|
46
|
+
def valid_session?
|
47
|
+
!@session_key.nil? # TODO validate @session_key using EverySense API
|
48
|
+
end
|
49
|
+
|
50
|
+
def validate_device
|
51
|
+
if @device_id.nil?
|
52
|
+
$log.error :error => 'Invalid device id.'
|
53
|
+
return false
|
54
|
+
end
|
55
|
+
return true
|
56
|
+
end
|
57
|
+
|
58
|
+
def validate_recipe
|
59
|
+
if @recipe_id.nil?
|
60
|
+
$log.error :error => 'Invalid recipe id.'
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
return true
|
64
|
+
end
|
65
|
+
|
66
|
+
def create_session_request
|
67
|
+
session_req = Net::HTTP::Post.new(@uri + '/session')
|
68
|
+
session_req.body = {login_name: @login_name, password: @password}.to_json
|
69
|
+
session_req.content_type = 'application/json'
|
70
|
+
session_req
|
71
|
+
end
|
72
|
+
|
73
|
+
def create_session
|
74
|
+
return @session_key if valid_session?
|
75
|
+
@session_req ||= create_session_request
|
76
|
+
session_res = @https.request(@session_req)
|
77
|
+
return nil if !error_handler(session_res, 'create_session failed.')
|
78
|
+
@session_key = JSON.parse(session_res.body)["session_key"]
|
79
|
+
end
|
80
|
+
|
81
|
+
def delete_session_request
|
82
|
+
Net::HTTP::Delete.new(@uri + "/session/#{@session_key}")
|
83
|
+
end
|
84
|
+
|
85
|
+
def delete_session
|
86
|
+
return if !valid_session?
|
87
|
+
del_session_res = @https.request(delete_session_request)
|
88
|
+
error_handler(del_session_res, 'delete_session failed.')
|
89
|
+
end
|
90
|
+
|
91
|
+
def put_message_request(message)
|
92
|
+
put_message_req = Net::HTTP::Post.new(@uri + "/device_data/#{@device_id}")
|
93
|
+
put_message_req.body = message
|
94
|
+
put_message_req.content_type = "application/#{@format}"
|
95
|
+
put_message_req
|
96
|
+
end
|
97
|
+
|
98
|
+
def put_message(message)
|
99
|
+
return if !validate_device
|
100
|
+
put_message_res = @https.request(put_message_request(message))
|
101
|
+
error_handler(put_message_res, "put_message: '#{message}' failed.")
|
102
|
+
end
|
103
|
+
|
104
|
+
def get_message_request
|
105
|
+
get_message_req = @uri + "/device_data/#{@device_id}?session_key=#{@session_key}&from=#{URI.encode_www_form_component(@from)}&to=#{URI.encode_www_form_component(Time.now.iso8601)}"
|
106
|
+
@from = (Time.now + 1).iso8601
|
107
|
+
get_message_req
|
108
|
+
end
|
109
|
+
|
110
|
+
def get_message
|
111
|
+
if !valid_session?
|
112
|
+
return nil if create_session.nil?
|
113
|
+
$log.debug "session #{@session_key} created."
|
114
|
+
end
|
115
|
+
return nil if !validate_device
|
116
|
+
get_message_res = @https.get(get_message_request)
|
117
|
+
return nil if !error_handler(get_message_res,"get_message failed.")
|
118
|
+
get_message_res.body
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_recipe_request
|
122
|
+
@uri + "/recipe_data/#{@recipe_id}"
|
123
|
+
end
|
124
|
+
|
125
|
+
def get_recipe
|
126
|
+
if !valid_session?
|
127
|
+
return nil if create_session.nil?
|
128
|
+
$log.debug "session #{@session_key} created."
|
129
|
+
end
|
130
|
+
return nil if !validate_recipe
|
131
|
+
get_recipe_res = @https.get(get_recipe_request)
|
132
|
+
return nil if !error_handler(get_recipe_res, "get_recipe failed.")
|
133
|
+
get_recipe_res.body
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Fluent
|
2
|
+
class EverySenseInput < Input
|
3
|
+
require 'fluent/plugin/everysense_proxy'
|
4
|
+
include EverySenseProxy
|
5
|
+
|
6
|
+
Plugin.register_input('everysense', self)
|
7
|
+
|
8
|
+
desc 'Tag name assigned to inputs'
|
9
|
+
config_param :tag, :string, :default => nil # TODO: mandatory option
|
10
|
+
desc 'Polling interval to get message from EverySense API'
|
11
|
+
config_param :polling_interval, :integer, :default => 15
|
12
|
+
config_param :recv_time, :bool, :default => false
|
13
|
+
config_param :recv_time_key, :string, :default => "recv_time"
|
14
|
+
|
15
|
+
# Define `router` method of v0.12 to support v0.10 or earlier
|
16
|
+
unless method_defined?(:router)
|
17
|
+
define_method("router") { Fluent::Engine }
|
18
|
+
end
|
19
|
+
|
20
|
+
def configure(conf)
|
21
|
+
super
|
22
|
+
configure_parser(conf)
|
23
|
+
end
|
24
|
+
|
25
|
+
def configure_parser(conf)
|
26
|
+
@parser = Plugin.new_parser(@format)
|
27
|
+
@parser.configure(conf)
|
28
|
+
end
|
29
|
+
|
30
|
+
def start
|
31
|
+
raise StandardError.new if @tag.nil?
|
32
|
+
super
|
33
|
+
start_proxy
|
34
|
+
@proxy_thread = Thread.new do
|
35
|
+
while (true)
|
36
|
+
begin
|
37
|
+
message = get_message
|
38
|
+
$log.debug "get_message: #{message}"
|
39
|
+
emit(message) if !message.nil?
|
40
|
+
sleep @polling_interval
|
41
|
+
rescue Exception => e
|
42
|
+
$log.error :error => e.to_s
|
43
|
+
$log.debug(e.backtrace.join("\n"))
|
44
|
+
#$log.debug_backtrace(e.backtrace)
|
45
|
+
sleep @polling_interval
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_recv_time(record)
|
52
|
+
if @recv_time
|
53
|
+
# recv_time is recorded in ms
|
54
|
+
record.merge({@recv_time_key => Time.now.instance_eval { self.to_i * 1000 + (usec/1000) }})
|
55
|
+
else
|
56
|
+
record
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def parse(message)
|
61
|
+
@parser.parse(message) do |time, record|
|
62
|
+
if time.nil?
|
63
|
+
$log.debug "Since time_key field is nil, Fluent::Engine.now is used."
|
64
|
+
time = Fluent::Engine.now
|
65
|
+
end
|
66
|
+
$log.debug "#{time}, #{add_recv_time(record)}"
|
67
|
+
return [time, add_recv_time(record)]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def emit(message)
|
72
|
+
begin
|
73
|
+
router.emit(@tag, *parse(message))
|
74
|
+
rescue Exception => e
|
75
|
+
$log.error :error => e.to_s
|
76
|
+
$log.debug_backtrace(e.backtrace)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def shutdown
|
81
|
+
super
|
82
|
+
@proxy_thread.kill
|
83
|
+
shutdown_proxy
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Fluent
|
2
|
+
class EverySenseOutput < Output
|
3
|
+
require 'fluent/plugin/everysense_proxy'
|
4
|
+
include EverySenseProxy
|
5
|
+
|
6
|
+
Plugin.register_output('everysense', self)
|
7
|
+
|
8
|
+
# config_param defines a parameter. You can refer a parameter via @path instance variable
|
9
|
+
# Without :default, a parameter is required.
|
10
|
+
#desc 'Flush interval to put message to EverySense API'
|
11
|
+
#config_param :flush_interval, :integer, :default => 15
|
12
|
+
|
13
|
+
# This method is called before starting.
|
14
|
+
# 'conf' is a Hash that includes configuration parameters.
|
15
|
+
# If the configuration is invalid, raise Fluent::ConfigError.
|
16
|
+
def configure(conf)
|
17
|
+
super
|
18
|
+
configure_formatter(conf)
|
19
|
+
end
|
20
|
+
|
21
|
+
def configure_formatter(conf)
|
22
|
+
@formatter = Plugin.new_formatter(@format)
|
23
|
+
@formatter.configure(conf)
|
24
|
+
end
|
25
|
+
|
26
|
+
# This method is called when starting.
|
27
|
+
# Open sockets or files here.
|
28
|
+
def start
|
29
|
+
super
|
30
|
+
start_proxy
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_send_time(record)
|
34
|
+
if @send_time
|
35
|
+
# send_time is recorded in ms
|
36
|
+
record.merge({@send_time_key => Time.now.instance_eval { self.to_i * 1000 + (usec/1000) }})
|
37
|
+
else
|
38
|
+
record
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def emit(tag, es, chain)
|
43
|
+
chain.next
|
44
|
+
es.each {|time,record|
|
45
|
+
$log.debug "#{tag}, #{@formatter.format_record(add_send_time(record)).chomp}\n"
|
46
|
+
put_message(@formatter.format_record(add_send_time(record)))
|
47
|
+
}
|
48
|
+
$log.flush
|
49
|
+
end
|
50
|
+
|
51
|
+
# This method is called when shutting down.
|
52
|
+
# Shutdown the thread and close sockets or files here.
|
53
|
+
def shutdown
|
54
|
+
super
|
55
|
+
shutdown_proxy
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# Ruby を使って EverySense の API で遊んでみよう!
|
2
|
+
|
3
|
+
Ruby のインタラクティブシェル irb あるいは pry などを利用して EverySense の API で遊んでみましょう。以下では最も標準的な API である JSON over HTTPゲートウェイについて触れています。irb を起動して以下のコードを貼り付けてみましょう。ただし、login_name および password は以下のURIからご自身で登録したものに書き換えて下さい。
|
4
|
+
|
5
|
+
https://service.every-sense.com/
|
6
|
+
|
7
|
+
以下ではまずデバイスのデータをアップロード、ダウンロードする方法から触れますので、ファームオーナー(「センサー情報を提供される方」)でアカウント登録をしてください。
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
require 'uri'
|
11
|
+
require 'net/http'
|
12
|
+
require 'json'
|
13
|
+
|
14
|
+
uri = URI.parse('https://api.every-sense.com:8001/')
|
15
|
+
https = Net::HTTP.new(uri.host, uri.port)
|
16
|
+
https.use_ssl = true
|
17
|
+
session_req = Net::HTTP::Post.new(uri + '/session')
|
18
|
+
session_req.body = {login_name: 'your_name', password: 'your_password'}.to_json
|
19
|
+
session_req.content_type = 'application/json'
|
20
|
+
session_res = https.request(session_req)
|
21
|
+
|
22
|
+
session_res.code
|
23
|
+
session_res.message
|
24
|
+
session_res.body
|
25
|
+
```
|
26
|
+
|
27
|
+
最後の3行では以下の様な結果が出力されましたか?
|
28
|
+
|
29
|
+
```
|
30
|
+
irb(main):013:0* session_res.code
|
31
|
+
=> "200"
|
32
|
+
irb(main):014:0> session_res.message
|
33
|
+
=> "OK"
|
34
|
+
irb(main):015:0> session_res.body
|
35
|
+
=> "{\"code\":0,\"session_key\":\"YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYYY\"}"
|
36
|
+
```
|
37
|
+
|
38
|
+
ここで取得したsession_keyは、デバイスのデータ(/device_data)およびレシピのデータ(/recipe_data)を読み出す際に必要となります。
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
session_key = JSON.parse(session_res.body)["session_key"]
|
42
|
+
```
|
43
|
+
|
44
|
+
次にデバイスのデータのアップロード、ダウンロードについて試してみるため、テスト用のデバイス Test_Device を登録してください。デバイスの登録は以下から行えます。
|
45
|
+
|
46
|
+
https://service.every-sense.com/ja/devices
|
47
|
+
|
48
|
+
デバイスクラスとしてTest_Deviceを選択し、「追加」します。
|
49
|
+
登録できると、UUIDが表示されます。
|
50
|
+
XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
51
|
+
|
52
|
+
デバイスのデータのアップロード、ダウンロードをする際にUUIDが必要になります。
|
53
|
+
|
54
|
+
まずはアップロードから試してみましょう。なんと、アップロードには認証は不要です。ということは、デバイスのUUIDを知っている人は誰でもアップロードできてしまう??皆さんUUIDの取り扱いには注意しましょう。
|
55
|
+
|
56
|
+
URIにデバイスのUUIDを指定して、アップロードしたいデータをPOSTします。ここでは content_type に 'application/json' を指定して、JSON形式のデータをアップロードしてみます。
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
upload_req = Net::HTTP::Post.new(uri + '/device_data/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX')
|
60
|
+
upload_req.body = {test_data: {data1: "hoge", data2: 123}}.to_json
|
61
|
+
upload_req.content_type = 'application/json'
|
62
|
+
upload_res = https.request(upload_req)
|
63
|
+
upload_res.body
|
64
|
+
```
|
65
|
+
|
66
|
+
最後の応答に以下のように 'code: 0' が返されていればアップロード成功です。
|
67
|
+
|
68
|
+
```
|
69
|
+
irb(main):023:0> upload_res.body
|
70
|
+
=> "{\"code\":0}"
|
71
|
+
```
|
72
|
+
|
73
|
+
データの取得にはログインID (UUID) + パスワードあるいは、session_keyが要求されます。以下では session_key を利用しています。
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
get_res = https.get(uri + "/device_data/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX?session_key=#{session_key}")
|
77
|
+
get_res.body
|
78
|
+
```
|
79
|
+
|
80
|
+
しばらくはキャッシュされているので、getすると同じデータがダウンロードされます。そのため、
|
81
|
+
実際には from, to でデータが登録された期間を指定して必要なデータをすることになります。
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
get_res = https.get(uri + "/device_data/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX?session_key=#{session_key}&from=2016-03-06-06:20&to=2016-03-06-07:00")
|
85
|
+
get_res.body
|
86
|
+
```
|
87
|
+
|
88
|
+
from, to の時刻はUTCで指定してください。
|
89
|
+
|
90
|
+
次に「センサー情報収集」のため、レストランオーナーとしてレシピを登録、確認する方法について見ていきます。レストランオーナーになるためには、service.every-sense.com の右上の設定メニューから「レストランオーナー」の登録を行った上で、「オーナー切替」で「レストランオーナー」として作業してください。
|
91
|
+
|
92
|
+
https://service.every-sense.com/
|
93
|
+
|
94
|
+
ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ
|
95
|
+
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
recipe_data = https.get(uri + "/recipe_data/ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ.xml?session_key=#{session_key}&from=2016-03-06-07:00&to=2016-03-06-07:50")
|
99
|
+
recipe_data.body
|
100
|
+
```
|
101
|
+
|
102
|
+
# session_keyについて
|
103
|
+
|
104
|
+
device_dataにはlogin_name、passwordでもアクセスできますが、毎回提示すると login_name、passwordが奪われる可能性が高くなるため、代わりにsession_keyを用いてアクセスします。ただし、session_keyが他人に奪われると不正にアクセスされる可能性があるため、利用が終わったらsession_keyを無効化するようにしましょう。以下の手順でsession_keyを無効化できます。
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
del_session_req = Net::HTTP::Delete.new(uri + "/session/#{session_key}")
|
108
|
+
del_session_res = https.request(del_session_req)
|
109
|
+
del_session_res.body
|
110
|
+
```
|
111
|
+
|
112
|
+
以下のように 'code: 0' が返されていれば削除成功です。
|
113
|
+
|
114
|
+
```
|
115
|
+
irb(main):037:0> del_session_res.body
|
116
|
+
=> "{\"code\":0}"
|
117
|
+
```
|
118
|
+
|
119
|
+
現状はsession_keyにはかなり長い時間の有効期間が与えられているようで、1日たってもアクセスできました (^^;;
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-everysense
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Toyokazu Akiyama
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-03-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fluentd
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.10.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.10.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.10'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.10'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
description: Fluent Input/Output plugin for EverySense Framework
|
56
|
+
email:
|
57
|
+
- toyokazu@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- fluent-plugin-everysense.gemspec
|
68
|
+
- lib/fluent/plugin/everysense_proxy.rb
|
69
|
+
- lib/fluent/plugin/in_everysense.rb
|
70
|
+
- lib/fluent/plugin/out_everysense.rb
|
71
|
+
- tutorial/ja/json_over_http_api_tutorial.md
|
72
|
+
homepage: https://github.com/toyokazu/fluent-plugin-everysense
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 2.0.0
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 2.4.5.1
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: Fluent Input/Output plugin for EverySense Framework
|
96
|
+
test_files: []
|