simbiotes 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +194 -0
- data/Rakefile +33 -0
- data/lib/generators/simbiotes/create_model/USAGE +8 -0
- data/lib/generators/simbiotes/create_model/create_model_generator.rb +50 -0
- data/lib/generators/simbiotes/create_model/templates/simbiotes_logs_model.rb.erb +7 -0
- data/lib/generators/simbiotes/create_model/templates/simbiotes_model.rb.erb +27 -0
- data/lib/generators/simbiotes/create_model/templates/simbiotes_module.rb.erb +10 -0
- data/lib/generators/simbiotes/create_table/USAGE +9 -0
- data/lib/generators/simbiotes/create_table/create_table_generator.rb +52 -0
- data/lib/generators/simbiotes/create_table/templates/create_logs_table.rb.erb +14 -0
- data/lib/generators/simbiotes/create_table/templates/create_table.rb.erb +16 -0
- data/lib/generators/simbiotes/initializer/USAGE +8 -0
- data/lib/generators/simbiotes/initializer/initializer_generator.rb +18 -0
- data/lib/generators/simbiotes/initializer/templates/simbiotes.rb.erb +7 -0
- data/lib/generators/simbiotes/initializer/templates/simbiotes_targets.rb.erb +3 -0
- data/lib/generators/simbiotes/install/USAGE +11 -0
- data/lib/generators/simbiotes/install/install_generator.rb +11 -0
- data/lib/generators/simbiotes/migration/USAGE +10 -0
- data/lib/generators/simbiotes/migration/migration_generator.rb +54 -0
- data/lib/generators/simbiotes/migration/templates/create_logs_table.rb.erb +14 -0
- data/lib/generators/simbiotes/migration/templates/migrate_table.rb.erb +12 -0
- data/lib/generators/simbiotes/model/USAGE +11 -0
- data/lib/generators/simbiotes/model/model_generator.rb +58 -0
- data/lib/generators/simbiotes/script/USAGE +8 -0
- data/lib/generators/simbiotes/script/script_generator.rb +38 -0
- data/lib/generators/simbiotes/script/templates/comm_server.rake +19 -0
- data/lib/generators/simbiotes/script/templates/publish_script.rake +6 -0
- data/lib/generators/simbiotes/script/templates/script.rb.erb +12 -0
- data/lib/generators/simbiotes/script/templates/server.rb +8 -0
- data/lib/generators/simbiotes/script/templates/server_control.rb +7 -0
- data/lib/simbiotes/client.rb +20 -0
- data/lib/simbiotes/configuration.rb +18 -0
- data/lib/simbiotes/extract.rb +75 -0
- data/lib/simbiotes/insert.rb +89 -0
- data/lib/simbiotes/parse.rb +20 -0
- data/lib/simbiotes/portal.rb +127 -0
- data/lib/simbiotes/railtie.rb +14 -0
- data/lib/simbiotes/server.rb +66 -0
- data/lib/simbiotes/version.rb +3 -0
- data/lib/simbiotes.rb +52 -0
- data/lib/tasks/simbiotes_tasks.rake +4 -0
- metadata +155 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
module Simbiotes
|
2
|
+
class ModelGenerator < Rails::Generators::Base
|
3
|
+
source_root File.expand_path('../templates', __FILE__)
|
4
|
+
argument :parent, :type => :string
|
5
|
+
argument :name, :type => :string
|
6
|
+
argument :attributes, :type => :hash, :required => false
|
7
|
+
|
8
|
+
def run_generators
|
9
|
+
generate "simbiotes:create_table", arguments
|
10
|
+
if @c == nil
|
11
|
+
generate "simbiotes:create_model", "#{parent} #{name}"
|
12
|
+
else
|
13
|
+
generate "simbiotes:create_model", thorify
|
14
|
+
generate "simbiotes:initializer", "true"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def arguments
|
21
|
+
if attributes == nil
|
22
|
+
return get_attributes
|
23
|
+
else
|
24
|
+
return parent.to_s + " " + name.to_s + " " + stringify
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def stringify
|
29
|
+
string = String.new
|
30
|
+
attributes.each do |k,v|
|
31
|
+
string = string + k + ":" + v + " "
|
32
|
+
end
|
33
|
+
string
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_attributes
|
37
|
+
@c = Simbiotes.get_attributes(parent, name)
|
38
|
+
if @c[:kind] == "script"
|
39
|
+
generate "simbiotes:script", "#{parent} #{name}"
|
40
|
+
end
|
41
|
+
string = String.new
|
42
|
+
@c[:attributes].each do |k,v|
|
43
|
+
if v[:type] == "enum"
|
44
|
+
string = string + k.gsub(" ", "_").downcase + ":" + "integer" + " "
|
45
|
+
else
|
46
|
+
string = string + k.gsub(" ", "_").downcase + ":" + v[:type] + " "
|
47
|
+
end
|
48
|
+
end
|
49
|
+
return parent.to_s + " " + name.to_s + " " + string
|
50
|
+
end
|
51
|
+
|
52
|
+
def thorify
|
53
|
+
string = String.new
|
54
|
+
string = parent.to_s + " " + name.to_s + " " + "true"
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Simbiotes
|
2
|
+
class ScriptGenerator < Rails::Generators::Base
|
3
|
+
source_root File.expand_path('../templates', __FILE__)
|
4
|
+
argument :parent, :type => :string, :required => false
|
5
|
+
argument :name, :type => :string, :required => false
|
6
|
+
|
7
|
+
def create_script
|
8
|
+
if name != nil
|
9
|
+
@c = Simbiotes::Portal.get_attributes(parent, name)
|
10
|
+
template "script.rb.erb", "lib/scripts/simbiotes/#{parent_file_name}/#{file_name}.rb"
|
11
|
+
end
|
12
|
+
copy_file "server.rb", "lib/scripts/server.rb"
|
13
|
+
copy_file "server_control.rb", "lib/scripts/server_control.rb"
|
14
|
+
copy_file "comm_server.rake", "lib/tasks/comm_server.rake"
|
15
|
+
copy_file "publish_script.rake", "lib/tasks/publish_script.rake"
|
16
|
+
FileUtils.chmod 0775, "lib/scripts/server_control.rb"
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def file_name
|
22
|
+
name.underscore
|
23
|
+
end
|
24
|
+
|
25
|
+
def class_name
|
26
|
+
name.classify
|
27
|
+
end
|
28
|
+
|
29
|
+
def parent_class_name
|
30
|
+
parent.classify
|
31
|
+
end
|
32
|
+
|
33
|
+
def parent_file_name
|
34
|
+
parent.underscore
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
namespace :comms do
|
2
|
+
desc "Start local communication server"
|
3
|
+
task start: :environment do
|
4
|
+
system("ruby", "#{Rails.root}/lib/scripts/server_control.rb", "start")
|
5
|
+
puts $?
|
6
|
+
end
|
7
|
+
|
8
|
+
desc "Stop local communication server"
|
9
|
+
task stop: :environment do
|
10
|
+
system("ruby", "#{Rails.root}/lib/scripts/server_control.rb", "stop")
|
11
|
+
puts $?
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Restart local communication server"
|
15
|
+
task restart: :environment do
|
16
|
+
system("ruby", "#{Rails.root}/lib/scripts/server_control.rb", "restart")
|
17
|
+
puts $?
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#######
|
2
|
+
# This script will be deployed to your device.
|
3
|
+
# The $global variables below represent the values your script will receive/needs to provide to/from its various interfaces and inputs.
|
4
|
+
# Your script should change the value of these variables to what they should be, and they will then get passed back.
|
5
|
+
# You can also add additional global variables. If you do, these will be passed back to the script along with the
|
6
|
+
# interface and input variables the next time the script is invoked. These are useful for keeping state across script
|
7
|
+
# invocations.
|
8
|
+
<% @c[:attributes].each do |k,v|%>
|
9
|
+
$<%= k.gsub(" ","_") %><% end %><% @c[:inputs].each do |k,v|%>
|
10
|
+
$<%= "#{k.gsub(" ","_")}_#{v.gsub(" ","_")}" %><% end %>
|
11
|
+
|
12
|
+
# put your logic here.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# This class connects to the local server (see Server class). Messages sent to the local server are forwarded. The server class handles messages
|
2
|
+
# received from the remote server.
|
3
|
+
|
4
|
+
require "socket"
|
5
|
+
module Simbiotes
|
6
|
+
class Client
|
7
|
+
def initialize( server = 'localhost', port = Simbiotes.configuration.local_port )
|
8
|
+
@server = server
|
9
|
+
@port = port
|
10
|
+
end
|
11
|
+
|
12
|
+
def send(msg)
|
13
|
+
connection = TCPSocket.open(@server, @port)
|
14
|
+
connection.puts( msg )
|
15
|
+
connection.close
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Simbiotes
|
2
|
+
class Configuration
|
3
|
+
|
4
|
+
attr_accessor :public_key, :private_key, :local_logging, :targets, :local_port, :server, :server_port, :portal
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@public_key = nil
|
8
|
+
@private_key = nil
|
9
|
+
@local_logging = true
|
10
|
+
@targets = nil
|
11
|
+
@local_port = 8001
|
12
|
+
@server = "rgs.microarx.com"
|
13
|
+
@server_port = 8000
|
14
|
+
@portal = "http://www.simbiotes.com/"
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Simbiotes
|
4
|
+
|
5
|
+
class Extract
|
6
|
+
|
7
|
+
def self.send(object)
|
8
|
+
interfaces = Hash.new
|
9
|
+
puts object.previous_changes
|
10
|
+
object.previous_changes.each do |k,v|
|
11
|
+
if Simbiotes.configuration.targets[object.class.parent.to_s][object.class.name.demodulize.to_s].include?(k) || Simbiotes.configuration.targets[object.class.parent.to_s][object.class.name.demodulize.to_s].include?(k.titleize)
|
12
|
+
interfaces[k] = v[1].to_s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
if interfaces != {}
|
16
|
+
Extract.fire(object, interfaces, "set-request")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.get(object, time0= nil, time1= nil)
|
21
|
+
object.accessed_fields.each do |field|
|
22
|
+
v = Array.new
|
23
|
+
if time0 != nil
|
24
|
+
Extract.fire(object, field, object.send(field), "get", time0, time1)
|
25
|
+
else
|
26
|
+
Extract.fire(object, field, object.send(field), "get")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.fire(object, interfaces, a, time0= nil, time1= nil)
|
32
|
+
if Simbiotes.configuration.targets[object.class.parent.to_s] != nil
|
33
|
+
msg = {
|
34
|
+
"action" => a,
|
35
|
+
"instance" => object.simbiotes_instance,
|
36
|
+
"driver" => object.class.name.to_s,
|
37
|
+
"interface" => interfaces,
|
38
|
+
}
|
39
|
+
if time0 != nil
|
40
|
+
msg["time0"] = time0
|
41
|
+
msg["time1"] = time1
|
42
|
+
end
|
43
|
+
c = Simbiotes::Client.new
|
44
|
+
c.send(msg.to_json)
|
45
|
+
object.skip_extract = true
|
46
|
+
interfaces.each do |key, value|
|
47
|
+
object.send(("#{key}_ack=").to_sym, false)
|
48
|
+
object.send(("#{key}_complete=").to_sym, false)
|
49
|
+
object.send(("#{key}_action=").to_sym, a)
|
50
|
+
end
|
51
|
+
object.save
|
52
|
+
object.skip_extract = false
|
53
|
+
Extract.save_log(object, interfaces, a)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
def self.save_log(object, interfaces, a)
|
60
|
+
interfaces.each do |key, value|
|
61
|
+
klass = "#{object.class.name.underscore}_#{key}_log".classify.constantize
|
62
|
+
r = klass.new
|
63
|
+
r.send(("#{key}_action=").to_sym, a)
|
64
|
+
r.send(("#{key}=".to_sym), value)
|
65
|
+
r.send(("#{key}_ack=").to_sym, false)
|
66
|
+
r.send(("#{key}_complete=").to_sym, false)
|
67
|
+
r.send(("#{object.class.name.demodulize.underscore.gsub("/","_")}_id=").to_sym, object.id)
|
68
|
+
puts r.inspect
|
69
|
+
r.save
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# This class takes ruby hashes and saves them to the appropriate database table.
|
2
|
+
# All model methods that have corresponding IoT interfaces have six database fields associated with them.
|
3
|
+
# The first is a field named the same as the method. The second is name_ack, and third is name_complete, the fourth is name_timestamp, the fifth is name_status, the sixth is name_action.
|
4
|
+
# In the hash, instance is the record id (not necessarily the id column), driver is the model, interface is the method.
|
5
|
+
# Data should be saved both to the model's database table and to the corresponding log table (name_method_logs).
|
6
|
+
|
7
|
+
module Simbiotes
|
8
|
+
class Insert
|
9
|
+
def initialize(hash = {"action" => "set-complete", "instance" => 1, "driver" => "test_driver", "interface" => "control", "value" => 72, "timestamp" => "1000000000000", "status" => "ok"})
|
10
|
+
@action = hash["action"]
|
11
|
+
@id = hash["instance"]
|
12
|
+
@class = hash["driver"]
|
13
|
+
@methods = hash["interface"]
|
14
|
+
@value = hash["value"]
|
15
|
+
@timestamp = hash["timestamp"]
|
16
|
+
@status = hash["status"]
|
17
|
+
find_record
|
18
|
+
@methods.each do |k,v|
|
19
|
+
@record.send(("#{k}_action=").to_sym, @action)
|
20
|
+
@record.send("#{k}=".to_sym, @value)
|
21
|
+
@record.send("#{k}_timestamp=".to_sym, @timestamp)
|
22
|
+
@record.send("#{k}_status=".to_sym, @status)
|
23
|
+
end
|
24
|
+
if @action == "set-complete"
|
25
|
+
set_complete
|
26
|
+
elsif @action == "set-request-ack"
|
27
|
+
set_ack
|
28
|
+
elsif @action == "get-ack"
|
29
|
+
get_ack
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def find_record
|
34
|
+
begin
|
35
|
+
klass = @class.classify.constantize
|
36
|
+
@record = klass.find_by(simbiotes_instance: @id)
|
37
|
+
rescue => e
|
38
|
+
puts e
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def set_ack
|
43
|
+
@methods.each do |k,v|
|
44
|
+
@record.send("#{k}_ack=".to_sym, true)
|
45
|
+
@record.send("#{k}_complete=".to_sym, false)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def set_complete
|
50
|
+
@methods.each do |k,v|
|
51
|
+
@record.send("#{k}_ack=".to_sym, true)
|
52
|
+
@record.send("#{k}_complete=".to_sym, true)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_ack
|
57
|
+
@methods.each do |k,v|
|
58
|
+
@record.send("#{k}_ack=".to_sym, true)
|
59
|
+
@record.send("#{k}_complete=".to_sym, false)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def save
|
64
|
+
@record.skip_extract = true
|
65
|
+
@record.save
|
66
|
+
@record.skip_extract = false
|
67
|
+
end
|
68
|
+
|
69
|
+
def action
|
70
|
+
@action.to_s
|
71
|
+
end
|
72
|
+
|
73
|
+
def save_log
|
74
|
+
@methods.each do |k,v|
|
75
|
+
klass = "#{@class}_#{k}_log".classify.constantize
|
76
|
+
r = klass.new
|
77
|
+
r.send(("#{k}_action=").to_sym, @action)
|
78
|
+
r.send("#{k}=".to_sym, v)
|
79
|
+
r.send("#{k}_timestamp=".to_sym, @timestamp)
|
80
|
+
r.send("#{k}_status=".to_sym, @status)
|
81
|
+
r.send("#{k}_ack=".to_sym, @record.send("#{k}_ack"))
|
82
|
+
r.send("#{k}_complete=".to_sym, @record.send("#{k}_complete"))
|
83
|
+
r.send("#{@class.classify.demodulize.underscore.gsub("/","_")}_id=".to_sym, @record.id)
|
84
|
+
r.save
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# This class is responsible for parsing JSON messages and configuration files into ruby hashes.
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Simbiotes
|
6
|
+
class Parse
|
7
|
+
|
8
|
+
def self.message(string)
|
9
|
+
JSON.parse(string)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.config(string)
|
13
|
+
JSON.parse(string)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.portal(string)
|
17
|
+
JSON.parse(string)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
|
2
|
+
require 'httparty'
|
3
|
+
require 'rest-client'
|
4
|
+
|
5
|
+
module Simbiotes
|
6
|
+
class Portal
|
7
|
+
|
8
|
+
def self.get_attributes(parent_name, model_name)
|
9
|
+
configuration = Portal.retrieve_configuration
|
10
|
+
attributes = Portal.parse_drivers_and_scripts(configuration, parent_name, model_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.parse_drivers_and_scripts(hash, parent_name, model_name)
|
14
|
+
attributes_hash = nil
|
15
|
+
hash["workers"][parent_name]["drivers"].each do |k,v|
|
16
|
+
name = v["metadata"]["common name"].classify
|
17
|
+
if name == model_name.classify
|
18
|
+
attributes_hash = Hash.new
|
19
|
+
attributes_hash[:kind] = "driver"
|
20
|
+
attributes_hash[:attributes] = Hash.new
|
21
|
+
v["interfaces"].each do |k,v|
|
22
|
+
attributes_hash[:attributes][k] = {
|
23
|
+
type: v["type"],
|
24
|
+
accessor: v["accessor type"],
|
25
|
+
units: v["units"],
|
26
|
+
noise: v["noise threshold"],
|
27
|
+
values: v["values"],
|
28
|
+
range: v["range"]
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
hash["workers"][parent_name]["scripts"].each do |k,v|
|
34
|
+
name = v["metadata"]["common name"].classify
|
35
|
+
if name == model_name.classify
|
36
|
+
attributes_hash = Hash.new
|
37
|
+
attributes_hash[:kind] = "script"
|
38
|
+
attributes_hash[:attributes] = Hash.new
|
39
|
+
v["interfaces"].each do |key,value|
|
40
|
+
attributes_hash[:attributes][key] = {
|
41
|
+
type: value["type"],
|
42
|
+
accessor: value["accessor type"],
|
43
|
+
units: value["units"],
|
44
|
+
noise: value["noise threshold"],
|
45
|
+
values: value["values"],
|
46
|
+
range: value["range"]
|
47
|
+
}
|
48
|
+
end
|
49
|
+
attributes_hash[:inputs] = Hash.new
|
50
|
+
v["inputs"].each do |key,value|
|
51
|
+
attributes_hash[:inputs][key] = value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
return attributes_hash
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.retrieve_configuration
|
59
|
+
json = HTTParty.post("#{Simbiotes.configuration.portal}api/hive", :query => {:public_key => Simbiotes.configuration.public_key, :private_key => Simbiotes.configuration.private_key}).body
|
60
|
+
hash = Simbiotes::Parse.portal(json)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.parse_all_interfaces
|
64
|
+
configuration = Portal.retrieve_configuration
|
65
|
+
hash = Hash.new
|
66
|
+
configuration["workers"].each do |key, value|
|
67
|
+
hash[key] = Hash.new
|
68
|
+
configuration["workers"][key]["drivers"].each do |k,v|
|
69
|
+
a = Array.new
|
70
|
+
if v["interfaces"] != nil
|
71
|
+
v["interfaces"].each do |key, value|
|
72
|
+
a << key
|
73
|
+
end
|
74
|
+
end
|
75
|
+
hash[key][v["metadata"]["common name"]] = a
|
76
|
+
end
|
77
|
+
configuration["workers"][key]["scripts"].each do |k,v|
|
78
|
+
a = Array.new
|
79
|
+
if v["interfaces"] != nil
|
80
|
+
v["interfaces"].each do |key, value|
|
81
|
+
a << key
|
82
|
+
end
|
83
|
+
end
|
84
|
+
hash[key][v["metadata"]["common name"]] = a
|
85
|
+
end
|
86
|
+
end
|
87
|
+
hash
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.sync_device_instances(worker_name)
|
91
|
+
instance_hash = JSON.parse(HTTParty.post("#{Simbiotes.configuration.portal}api/workers", :query => {:public_key => Simbiotes.configuration.public_key, :private_key => Simbiotes.configuration.private_key}).body)
|
92
|
+
Simbiotes.configuration.targets[worker_name].keys.each do |key|
|
93
|
+
klass = (worker_name + "::" + key).constantize rescue nil
|
94
|
+
unless klass == nil
|
95
|
+
instance_ids = Array.new
|
96
|
+
instance_hash[worker_name].each do |instance_id,status|
|
97
|
+
instance_ids << instance_id
|
98
|
+
end
|
99
|
+
stale_instances = klass.where.not(simbiotes_instance: instance_ids)
|
100
|
+
stale_instances.destroy_all
|
101
|
+
instance_ids.each do |instance_id|
|
102
|
+
i = klass.find_by(simbiotes_instance: instance_id)
|
103
|
+
if i == nil
|
104
|
+
i = klass.new
|
105
|
+
i.simbiotes_instance = instance_id
|
106
|
+
i.skip_extract = true
|
107
|
+
i.save(:validate => false)
|
108
|
+
i.skip_extract = false
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.upload_script(worker, script)
|
116
|
+
payload = {
|
117
|
+
:multipart => true,
|
118
|
+
:script_file => File.open("#{Rails.root}/lib/scripts/simbiotes/#{worker.downcase}/#{script.downcase}.rb", 'rb'),
|
119
|
+
:public_key => Simbiotes.configuration.public_key,
|
120
|
+
:private_key => Simbiotes.configuration.private_key,
|
121
|
+
:worker_name => worker,
|
122
|
+
:script_name => script
|
123
|
+
}
|
124
|
+
r = RestClient.post("#{Simbiotes.configuration.portal}api/upload_script", payload)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'simbiotes'
|
2
|
+
require 'rails'
|
3
|
+
|
4
|
+
module Simbiotes
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
generators do
|
7
|
+
require 'lib/generators/simbiotes/model'
|
8
|
+
require 'lib/generators/simbiotes/create_table'
|
9
|
+
require 'lib/generators/simbiotes/create_model'
|
10
|
+
require 'lib/generators/simbiotes/initializer'
|
11
|
+
require 'lib/generators/simbiotes/migration'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
|
2
|
+
# This class creates a local server listening on port 8001, and connects to a remote server on port 8000. Messages sent to the local server are transmitted
|
3
|
+
# to the remote server. Messages received from the remote server are forwarded to the appropriate logic.
|
4
|
+
|
5
|
+
require "socket"
|
6
|
+
module Simbiotes
|
7
|
+
class Server
|
8
|
+
def initialize( server = TCPSocket.open( Simbiotes.configuration.server, Simbiotes.configuration.server_port ) )
|
9
|
+
@server = server
|
10
|
+
@localport = Simbiotes.configuration.local_port
|
11
|
+
listen_remote
|
12
|
+
listen_local
|
13
|
+
end
|
14
|
+
|
15
|
+
def send(msg)
|
16
|
+
puts "Message sent: #{msg}"
|
17
|
+
@server.puts( msg )
|
18
|
+
end
|
19
|
+
|
20
|
+
def close
|
21
|
+
@server.close
|
22
|
+
end
|
23
|
+
|
24
|
+
def listen_remote
|
25
|
+
begin
|
26
|
+
Thread.new do
|
27
|
+
loop do
|
28
|
+
msg = @server.gets
|
29
|
+
puts msg
|
30
|
+
msg_hash = Simbiotes::Parse.message(msg)
|
31
|
+
r = Simbiotes::Insert.new(msg_hash)
|
32
|
+
puts "Message received": msg_hash
|
33
|
+
if r.action == "set-request-ack" || r.action == "set-complete" || r.action == "get-ack"
|
34
|
+
r.save
|
35
|
+
unless Simbiotes.configuration.local_logging == false
|
36
|
+
r.save_log
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
rescue => e
|
42
|
+
puts e
|
43
|
+
listen_remote
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
def listen_local
|
49
|
+
begin
|
50
|
+
server = TCPServer.open(@localport)
|
51
|
+
loop do
|
52
|
+
Thread.fork(server.accept) do |client|
|
53
|
+
s = client.gets
|
54
|
+
#puts s
|
55
|
+
self.send(s)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
rescue => e
|
59
|
+
puts e
|
60
|
+
listen_local
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
data/lib/simbiotes.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'simbiotes/configuration'
|
2
|
+
require "simbiotes/version"
|
3
|
+
require 'simbiotes/server'
|
4
|
+
require 'simbiotes/client'
|
5
|
+
require 'simbiotes/parse'
|
6
|
+
require 'simbiotes/insert'
|
7
|
+
require 'simbiotes/extract'
|
8
|
+
require 'simbiotes/portal'
|
9
|
+
require 'daemons'
|
10
|
+
|
11
|
+
module Simbiotes
|
12
|
+
|
13
|
+
class << self
|
14
|
+
attr_accessor :configuration
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.configuration
|
18
|
+
@configuration ||= Configuration.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.reset
|
22
|
+
@configuration = Configuration.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.configure
|
26
|
+
yield(configuration)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.get(object, time0= nil, time1= nil)
|
30
|
+
Simbiotes::Extract.get(object, time0, time1)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.get_attributes(parent_name, model_name)
|
34
|
+
configuration = Simbiotes::Portal.retrieve_configuration
|
35
|
+
attributes = Simbiotes::Portal.parse_drivers_and_scripts(configuration, parent_name, model_name)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.sync_device_instances(worker_name)
|
39
|
+
Simbiotes::Portal.sync_device_instances(worker_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.sync(object)
|
43
|
+
parent = object.class.parent.name
|
44
|
+
child = object.class.name.demodulize
|
45
|
+
attributes = Simbiotes.configuration.targets[parent][child]
|
46
|
+
interfaces = Hash.new
|
47
|
+
attributes.each do |attribute|
|
48
|
+
interfaces[attribute.downcase.gsub(" ", "_")] = object.send(attribute.downcase.gsub(" ", "_"))
|
49
|
+
end
|
50
|
+
Simbiotes::Extract.fire(object, interfaces, "get")
|
51
|
+
end
|
52
|
+
end
|