apiotics-test 0.1.49
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +260 -0
- data/Rakefile +33 -0
- data/lib/apiotics.rb +58 -0
- data/lib/apiotics/client.rb +20 -0
- data/lib/apiotics/configuration.rb +23 -0
- data/lib/apiotics/extract.rb +107 -0
- data/lib/apiotics/hardware.rb +109 -0
- data/lib/apiotics/insert.rb +115 -0
- data/lib/apiotics/parse.rb +20 -0
- data/lib/apiotics/portal.rb +217 -0
- data/lib/apiotics/railtie.rb +14 -0
- data/lib/apiotics/server.rb +238 -0
- data/lib/apiotics/version.rb +3 -0
- data/lib/generators/apiotics/channel/USAGE +10 -0
- data/lib/generators/apiotics/channel/channel_generator.rb +35 -0
- data/lib/generators/apiotics/channel/templates/apiotics_channel.rb.erb +9 -0
- data/lib/generators/apiotics/channel/templates/apiotics_channel_client.coffee.erb +16 -0
- data/lib/generators/apiotics/channel/templates/apiotics_channel_initializer.rb.erb +3 -0
- data/lib/generators/apiotics/controller/USAGE +8 -0
- data/lib/generators/apiotics/controller/controller_generator.rb +25 -0
- data/lib/generators/apiotics/controller/templates/apiotics_scaffold.rb.erb +60 -0
- data/lib/generators/apiotics/create_model/USAGE +10 -0
- data/lib/generators/apiotics/create_model/create_model_generator.rb +76 -0
- data/lib/generators/apiotics/create_model/templates/apiotics_logs_model.rb.erb +7 -0
- data/lib/generators/apiotics/create_model/templates/apiotics_model.rb.erb +49 -0
- data/lib/generators/apiotics/create_model/templates/apiotics_module.rb.erb +14 -0
- data/lib/generators/apiotics/create_model/templates/apiotics_module_model.rb.erb +8 -0
- data/lib/generators/apiotics/create_model/templates/create_module_model_table.rb.erb +9 -0
- data/lib/generators/apiotics/create_table/USAGE +9 -0
- data/lib/generators/apiotics/create_table/create_table_generator.rb +62 -0
- data/lib/generators/apiotics/create_table/templates/create_logs_table.rb.erb +14 -0
- data/lib/generators/apiotics/create_table/templates/create_table.rb.erb +16 -0
- data/lib/generators/apiotics/initializer/USAGE +8 -0
- data/lib/generators/apiotics/initializer/initializer_generator.rb +29 -0
- data/lib/generators/apiotics/initializer/templates/apiotics.rb.erb +10 -0
- data/lib/generators/apiotics/initializer/templates/apiotics_module.rb.erb +6 -0
- data/lib/generators/apiotics/initializer/templates/apiotics_parents.rb.erb +3 -0
- data/lib/generators/apiotics/initializer/templates/apiotics_settings.rb.erb +9 -0
- data/lib/generators/apiotics/initializer/templates/apiotics_targets.rb.erb +4 -0
- data/lib/generators/apiotics/initializer/templates/setting.rb.erb +3 -0
- data/lib/generators/apiotics/install/USAGE +11 -0
- data/lib/generators/apiotics/install/install_generator.rb +11 -0
- data/lib/generators/apiotics/migration/USAGE +10 -0
- data/lib/generators/apiotics/migration/migration_generator.rb +54 -0
- data/lib/generators/apiotics/migration/templates/create_logs_table.rb.erb +14 -0
- data/lib/generators/apiotics/migration/templates/migrate_table.rb.erb +12 -0
- data/lib/generators/apiotics/model/USAGE +11 -0
- data/lib/generators/apiotics/model/model_generator.rb +58 -0
- data/lib/generators/apiotics/scaffold/scaffold_generator.rb +23 -0
- data/lib/generators/apiotics/scaffold/templates/USAGE +0 -0
- data/lib/generators/apiotics/script/USAGE +8 -0
- data/lib/generators/apiotics/script/script_generator.rb +45 -0
- data/lib/generators/apiotics/script/templates/comm_server.rake +19 -0
- data/lib/generators/apiotics/script/templates/dev_comm_server.rake +19 -0
- data/lib/generators/apiotics/script/templates/dev_server.rb +8 -0
- data/lib/generators/apiotics/script/templates/dev_server_control.rb +7 -0
- data/lib/generators/apiotics/script/templates/install_firmware.rake +10 -0
- data/lib/generators/apiotics/script/templates/publish_script.rake +6 -0
- data/lib/generators/apiotics/script/templates/script.rb.erb +12 -0
- data/lib/generators/apiotics/script/templates/server.rb +8 -0
- data/lib/generators/apiotics/script/templates/server_control.rb +7 -0
- data/lib/generators/apiotics/script/templates/test_comm_server.rake +19 -0
- data/lib/generators/apiotics/script/templates/test_server.rb +8 -0
- data/lib/generators/apiotics/script/templates/test_server_control.rb +7 -0
- data/lib/generators/apiotics/view/USAGE +12 -0
- data/lib/generators/apiotics/view/templates/default.css.erb +18 -0
- data/lib/generators/apiotics/view/templates/edit.html.erb +6 -0
- data/lib/generators/apiotics/view/templates/form.html.erb +52 -0
- data/lib/generators/apiotics/view/templates/index.html.erb +66 -0
- data/lib/generators/apiotics/view/templates/show.html.erb +56 -0
- data/lib/generators/apiotics/view/view_generator.rb +26 -0
- data/lib/tasks/simbiotes_tasks.rake +4 -0
- metadata +256 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 74dc3049ede534877349365340d48559dbbb4b41
|
4
|
+
data.tar.gz: 392128d01db6b10264cb4aa36391542cbfc93d67
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: df3572837f9b03a4078bcf8b0fd76dbe8ab582645ae2c80b0d5bab8e3f8e821016a4792ab8337e0401633da5d4282bc6618fb8a29ae149df033b095ff7ba947a
|
7
|
+
data.tar.gz: ed4ac85ae1fa4a741467bb7e61da422552a422fd33fd84b9da4bb3ed438af52b50da207448960f244be994562a84a312e7d56a9bc0921ce5f6cdd7b5792a080b
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2017 MicroArx Corporation
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,260 @@
|
|
1
|
+
# Apiotics
|
2
|
+
The easy way to make your Rails application interact with IoT devices.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
Add this line to your application's Gemfile:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
gem "apiotics"
|
9
|
+
```
|
10
|
+
|
11
|
+
Or install it yourself as:
|
12
|
+
```bash
|
13
|
+
$ gem install apiotics
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
```bash
|
18
|
+
$ bundle
|
19
|
+
$ rails generate apiotics:install
|
20
|
+
```
|
21
|
+
On the Apiotics portal located at www.apiotics.com, you can create a Hive for your project. Hives have Workers (each type of IoT device in your project will have a corresponding worker in the Hive). Workers have Drivers and, optionally, Scripts. Drivers and Scripts have interfaces. An example worker might be a Thermostat. The Thermostat has a Control Script with two interfaces: temperature and target temperature. If you set the target temperature to 72 and the temperature is 65, the Thermostat will turn the heat on. We'll use this example again and flesh it out below.
|
22
|
+
|
23
|
+
Once you have created a Hive, it will give you a public and a private API key. Best practice is to set environment variables in your development, test and production environments to equal these API keys. Then, set config.public_key and config.private_key in config/initializers/apiotics.rb to those environment variables. You can enter the API keys directly into the configuration file, but you should only do this if you never plan to put your Rails application and Hive into production, as it is a significant security risk.
|
24
|
+
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
Apiotics.configure do |config|
|
28
|
+
config.public_key = ENV['SIMBIOTES_PUBLIC_API_KEY']
|
29
|
+
config.private_key = ENV['SIMBIOTES_PRIVATE_API_KEY']
|
30
|
+
config.local_port = 8001
|
31
|
+
config.server_port = 8000
|
32
|
+
config.local_logging = true
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
36
|
+
## Usage
|
37
|
+
After you have installed the API keys, log in to the Apiotics portal (www.apiotics.com) to see that your Hive has Workers and that those Workers have Drivers and, if applicable, Scripts defined. Each Worker, Driver or Script will have one or more Interfaces. For example, if you are making a connected Thermostat, your Hive might have a Worker named 'Thermostat' and it might have the following Drivers/Scripts: Thermometer, Furnace and Control.
|
38
|
+
|
39
|
+
Each of the Drivers/Scripts has Interfaces (all of this would be viewable on the www.apiotics.com portal). The Control script might have two interfaces: Temperature and Target Temperature.
|
40
|
+
|
41
|
+
We want to be able to interact with these interfaces easily through our Rails application for all of the Thermostats that we have out there in the field.
|
42
|
+
|
43
|
+
### Models and Tables
|
44
|
+
|
45
|
+
To do this, we will create a model in our Rails application with attributes that correspond to the interfaces we want to interact with. We will then create records in our Rails database that correspond to our devices. Once we've done that, we can interact with a database record using ActiveRecord as usual, but the attribute values from our database records will be automatically synced to the corresponding device.
|
46
|
+
|
47
|
+
Because our model is going to sync with our IoT devices, we need to use the Apiotics model generator that comes with the gem to create the model rather than the model generator that comes by default with Rails. To use it, we pass two arguments, the name of the Worker and the name of the Driver or Script that we want to interact with. In this case, our worker is Thermostat and we want to interact with Control, so we create the model as follows:
|
48
|
+
|
49
|
+
```bash
|
50
|
+
$ rails generate apiotics:model Thermostat Control
|
51
|
+
```
|
52
|
+
|
53
|
+
This generator actually creates a model and a module. The module is in app/models/thermostat.rb and the model in app/models/thermostat/control.rb. If you create models that correspond to one or more of your Thermostat's other Drivers/Scripts, they will be placed in the app/models/thermostat directory as well.
|
54
|
+
|
55
|
+
Now you should migrate your database in order to create the database tables that correspond to your model.
|
56
|
+
|
57
|
+
```bash
|
58
|
+
$ rake db:migrate
|
59
|
+
```
|
60
|
+
|
61
|
+
The migration creates three tables: thermostat_controls, thermostat_control_temperature_logs and thermostat_control_target_temperature_logs. The thermostat_controls table holds the data for temperature and target temperature for all of the devices within your Hive.
|
62
|
+
|
63
|
+
### Instances and Devices
|
64
|
+
|
65
|
+
Now that you have your models and database tables created, you can use them to communicate with the devices that are out in the field.
|
66
|
+
|
67
|
+
The first thing to do is to create database records that correspond to actual devices. On the Apiotics Portal (www.apiotics.com) you will see a list of Worker Instances (each Instance represents an individual device of that particular Worker type) on each Worker page. Each Worker Instance has an id, you'll see them as a long string of characters on the page, one for each Worker Instance.
|
68
|
+
|
69
|
+
Now, run:
|
70
|
+
|
71
|
+
```bash
|
72
|
+
$ rails console
|
73
|
+
```
|
74
|
+
|
75
|
+
This will open up an irb console with your Rails environment (including the Apiotics gem) loaded.
|
76
|
+
|
77
|
+
In your console run:
|
78
|
+
|
79
|
+
```irb
|
80
|
+
> Thermostat.sync_device_instances
|
81
|
+
```
|
82
|
+
|
83
|
+
That will create a database record for each device instance you currently have defined in for your Thermostat worker. If you have no instances defined, create one on the Thermostat worker page in the apiotics.com portal.
|
84
|
+
|
85
|
+
Next, exit your rails console by typing:
|
86
|
+
|
87
|
+
```irb
|
88
|
+
> exit
|
89
|
+
```
|
90
|
+
|
91
|
+
The next thing we need to do is establish a communications channel we can use to communicate between our Rails application and the devices in the field. To do this, we use a local server that handles sending communications to the remote devices and handles communications that we will receive from them.
|
92
|
+
|
93
|
+
To start it up in production:
|
94
|
+
|
95
|
+
```bash
|
96
|
+
$ rake comms:start
|
97
|
+
```
|
98
|
+
|
99
|
+
In development:
|
100
|
+
|
101
|
+
```bash
|
102
|
+
$ rake dev_comms:start
|
103
|
+
```
|
104
|
+
|
105
|
+
In test:
|
106
|
+
|
107
|
+
```bash
|
108
|
+
$ rake test_comms:start
|
109
|
+
```
|
110
|
+
|
111
|
+
This starts our communications server. If you want to stop the communications server for any reason simply:
|
112
|
+
|
113
|
+
In production:
|
114
|
+
|
115
|
+
```bash
|
116
|
+
$ rake comms:stop
|
117
|
+
```
|
118
|
+
|
119
|
+
In development:
|
120
|
+
|
121
|
+
```bash
|
122
|
+
$ rake dev_comms:stop
|
123
|
+
```
|
124
|
+
|
125
|
+
In test:
|
126
|
+
|
127
|
+
```bash
|
128
|
+
$ rake test_comms:stop
|
129
|
+
```
|
130
|
+
|
131
|
+
Note that you can only communicate with devices if the local communications server is running.
|
132
|
+
|
133
|
+
### Communicating with Devices
|
134
|
+
|
135
|
+
Now that the preliminaries are out of the way, let's communicate with devices.
|
136
|
+
|
137
|
+
Open up your rails console again by typing:
|
138
|
+
|
139
|
+
```bash
|
140
|
+
$ rails c
|
141
|
+
```
|
142
|
+
|
143
|
+
In your console, type the following to get a device instance and assign it to the variable d:
|
144
|
+
|
145
|
+
```irb
|
146
|
+
> d = Thermostat::Control.first
|
147
|
+
```
|
148
|
+
|
149
|
+
The first thing to do is to synchronize the database's data with the data from the device. (This sends a get request for each Interface in the current Driver/Script) To do this type in your console:
|
150
|
+
|
151
|
+
```irb
|
152
|
+
> d.sync
|
153
|
+
```
|
154
|
+
|
155
|
+
Now that you are synced with the device, you can set the device's Interfaces easily right from Rails. Let's say you want to set the temperature of your thermostat to 68 degrees. Here's how you do it:
|
156
|
+
|
157
|
+
```irb
|
158
|
+
> d.target_temperature = 68
|
159
|
+
> d.save
|
160
|
+
```
|
161
|
+
|
162
|
+
All of the communications to the device are taken care of for you. If the value of these Interfaces changes (if the ambient temperature rises or falls for example) then your database will be kept up to date via the communications server without needing to sync the device instance going forward.
|
163
|
+
|
164
|
+
### Building a Web Scaffold
|
165
|
+
|
166
|
+
Now that you can communicate with your devices from the rails console, let's create a web scaffold so that you can communicate with them via your web browser.
|
167
|
+
|
168
|
+
If you haven't done it already, run
|
169
|
+
|
170
|
+
```bash
|
171
|
+
> rails generate simple_form:install
|
172
|
+
```
|
173
|
+
Then at the top of the config/initializers/simple_form.rb file put
|
174
|
+
|
175
|
+
```ruby
|
176
|
+
require 'simple_form'
|
177
|
+
```
|
178
|
+
|
179
|
+
To install the form helpers we will use to build forms to edit device interfaces via the browser.
|
180
|
+
|
181
|
+
Once you've done that, you can run the apiotics scaffold controller generator to generate a scaffold and views for your device.
|
182
|
+
|
183
|
+
```bash
|
184
|
+
> rails generate apiotics:controller Thermostat
|
185
|
+
```
|
186
|
+
|
187
|
+
This command installs a default controller and views for your Thermostat. Once they are installed, you can see them in your browser by starting up your development web server.
|
188
|
+
|
189
|
+
```bash
|
190
|
+
> rails server
|
191
|
+
```
|
192
|
+
|
193
|
+
Then in your web browser of choice, navigate to http://localhost:3000/thermostats. This page will show you a list of your Thermostat instances, as well as the current values of the different interfaces for your device. You can use the edit links for each device instance to change these values.
|
194
|
+
|
195
|
+
### Adding Push Web Updates
|
196
|
+
|
197
|
+
Since we want to be able to see changes to our devices without refreshing our webpage manually, we can leverage Rails 5's ActionCable to push device updates to our page.
|
198
|
+
|
199
|
+
To do this, run:
|
200
|
+
|
201
|
+
```bash
|
202
|
+
> rails generate apiotics:channel Thermostat
|
203
|
+
```
|
204
|
+
|
205
|
+
This command installs a configuration file, in this case app/channels/thermostat_channel.rb, to define an ActionCable channel for your Worker, in this case thermostat_channel, as well as a coffeescript file, in this case app/assets/javascripts/channels/thermostat.coffee, that defines how the browser will update information from the server on the page.
|
206
|
+
|
207
|
+
In order for the ActionCable messages to actually transmit to the browser, we need to install Redis. Redis is an open source in-memory data store that ActionCable uses to implement its PubSub messaging.
|
208
|
+
|
209
|
+
The easiest way to install Redis (if you are on a Mac) is:
|
210
|
+
|
211
|
+
```bash
|
212
|
+
> brew install redis
|
213
|
+
```
|
214
|
+
|
215
|
+
Then, once it is installed, run:
|
216
|
+
|
217
|
+
```bash
|
218
|
+
> redis-server
|
219
|
+
```
|
220
|
+
|
221
|
+
In your Rails application, edit your config/cable.yml file to look as follows:
|
222
|
+
|
223
|
+
```yaml
|
224
|
+
development:
|
225
|
+
adapter: redis
|
226
|
+
|
227
|
+
test:
|
228
|
+
adapter: redis
|
229
|
+
|
230
|
+
production:
|
231
|
+
adapter: redis
|
232
|
+
```
|
233
|
+
|
234
|
+
Add the following to your Gemfile:
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
gem 'jquery-rails'
|
238
|
+
```
|
239
|
+
|
240
|
+
And run
|
241
|
+
|
242
|
+
```bash
|
243
|
+
> bundle install
|
244
|
+
```
|
245
|
+
|
246
|
+
Next, open up your app/assets/javascripts/application.js file. Make sure you add the following lines to it above the require_tree . line, if you have it.
|
247
|
+
|
248
|
+
```js
|
249
|
+
//= require jquery
|
250
|
+
//= require jquery_ujs
|
251
|
+
```
|
252
|
+
|
253
|
+
Then, restart your Rails server. Once you have done that, the values on the Thermostats page will update via push notifications.
|
254
|
+
|
255
|
+
|
256
|
+
## Contributing
|
257
|
+
Contribution directions go here.
|
258
|
+
|
259
|
+
## License
|
260
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Apiotics'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
require 'bundler/gem_tasks'
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'test'
|
28
|
+
t.pattern = 'test/**/*_test.rb'
|
29
|
+
t.verbose = false
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
task default: :test
|
data/lib/apiotics.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'apiotics/configuration'
|
2
|
+
require "apiotics/version"
|
3
|
+
require 'apiotics/server'
|
4
|
+
require 'apiotics/client'
|
5
|
+
require 'apiotics/parse'
|
6
|
+
require 'apiotics/insert'
|
7
|
+
require 'apiotics/extract'
|
8
|
+
require 'apiotics/portal'
|
9
|
+
require 'apiotics/hardware'
|
10
|
+
require 'daemons'
|
11
|
+
|
12
|
+
module Apiotics
|
13
|
+
|
14
|
+
class << self
|
15
|
+
attr_accessor :configuration
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.configuration
|
19
|
+
@configuration ||= Configuration.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.reset
|
23
|
+
@configuration = Configuration.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.configure
|
27
|
+
yield(configuration)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.get(object, time0= nil, time1= nil)
|
31
|
+
Apiotics::Extract.get(object, time0, time1)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.get_attributes(parent_name, model_name)
|
35
|
+
configuration = Apiotics::Portal.retrieve_configuration
|
36
|
+
attributes = Apiotics::Portal.parse_drivers_and_scripts(configuration, parent_name, model_name)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.sync_device_instances(worker_name, sync_data= false)
|
40
|
+
Apiotics::Portal.sync_device_instances(worker_name, sync_data)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.sync(object)
|
44
|
+
parent = object.class.parent.name
|
45
|
+
child = object.class.name.demodulize
|
46
|
+
attributes = Apiotics.configuration.targets[parent][child]
|
47
|
+
interfaces = Hash.new
|
48
|
+
attributes.each do |attribute|
|
49
|
+
interfaces[attribute.underscore.downcase.gsub(" ", "_")] = object.send(attribute.underscore.downcase.gsub(" ", "_")).to_s
|
50
|
+
end
|
51
|
+
Apiotics::Extract.fire(object, interfaces, "get")
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.clear_settings
|
55
|
+
ApioticsSetting.destroy_all
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -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 Apiotics
|
6
|
+
class Client
|
7
|
+
def initialize( server = 'localhost', port = Apiotics.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,23 @@
|
|
1
|
+
module Apiotics
|
2
|
+
class Configuration
|
3
|
+
|
4
|
+
attr_accessor :public_key, :private_key, :local_logging, :targets, :local_port, :server, :server_port, :portal, :push, :tls, :verify_peer, :handshake, :parents
|
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 = "https://test.apiotics.com/"
|
15
|
+
@push = false
|
16
|
+
@tls = true
|
17
|
+
@verify_peer = true
|
18
|
+
@handshake = true
|
19
|
+
@parents = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Apiotics
|
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 Apiotics::Extract.is_target(object, k)
|
12
|
+
interfaces[k] = v[1].to_s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
if interfaces != {}
|
16
|
+
Extract.fire(object, interfaces, "set-request")
|
17
|
+
if Apiotics.configuration.parents != {}
|
18
|
+
interfaces.each do |k,v|
|
19
|
+
if Apiotics.configuration.parents[object.class.parent.demodulize][object.class.demodulize][k] != nil
|
20
|
+
m = "#{object.class.parent}".demodulize.underscore.gsub(" ","_").downcase
|
21
|
+
target_class = Apiotics.configuration.parents[object.class.parent.demodulize][object.class.demodulize][k]["driver"].downcase.constantize
|
22
|
+
target = object.m.target_class
|
23
|
+
i = Apiotics.configuration.parents[object.class.parent.demodulize][object.class.demodulize][k]["interface"].downcase.constantize
|
24
|
+
if Apiotics.configuration.parents[object.class.parent.demodulize][object.class.demodulize][k].keys < 3
|
25
|
+
target.i = v
|
26
|
+
target.skip_extract = true
|
27
|
+
target.save
|
28
|
+
target.skip_extract = false
|
29
|
+
else
|
30
|
+
target.i = Apiotics.configuration.parents[object.class.parent.demodulize][object.class.demodulize][k][v]
|
31
|
+
target.skip_extract = true
|
32
|
+
target.save
|
33
|
+
target.skip_extract = false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.is_target(object, k)
|
41
|
+
if Apiotics.configuration.targets[object.class.parent.to_s][object.class.name.demodulize.to_s].include?(k) || Apiotics.configuration.targets[object.class.parent.to_s][object.class.name.demodulize.to_s].include?(k.titleize)
|
42
|
+
return true
|
43
|
+
else
|
44
|
+
return false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.get(object, time0= nil, time1= nil)
|
49
|
+
object.accessed_fields.each do |field|
|
50
|
+
v = Array.new
|
51
|
+
if time0 != nil
|
52
|
+
Extract.fire(object, field, object.send(field), "get", time0, time1)
|
53
|
+
else
|
54
|
+
Extract.fire(object, field, object.send(field), "get")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.fire(object, interfaces, a, time0= nil, time1= nil)
|
60
|
+
if Apiotics.configuration.targets[object.class.parent.to_s] != nil
|
61
|
+
k = "#{object.class.parent}::#{object.class.parent}".constantize
|
62
|
+
i = "#{object.class.parent}".demodulize.underscore.gsub(" ","_").downcase + "_id"
|
63
|
+
msg = {
|
64
|
+
"action" => a,
|
65
|
+
"instance" => k.find(object.send(i)).apiotics_instance,
|
66
|
+
"driver" => object.class.name.to_s,
|
67
|
+
"interface" => interfaces,
|
68
|
+
}
|
69
|
+
if time0 != nil
|
70
|
+
msg["time0"] = time0
|
71
|
+
msg["time1"] = time1
|
72
|
+
end
|
73
|
+
c = Apiotics::Client.new
|
74
|
+
c.send(msg.to_json)
|
75
|
+
object.skip_extract = true
|
76
|
+
interfaces.each do |key, value|
|
77
|
+
object.send(("#{key}_ack=").to_sym, false)
|
78
|
+
object.send(("#{key}_complete=").to_sym, false)
|
79
|
+
object.send(("#{key}_action=").to_sym, a)
|
80
|
+
end
|
81
|
+
object.save
|
82
|
+
object.skip_extract = false
|
83
|
+
unless Apiotics.configuration.local_logging == false
|
84
|
+
Extract.save_log(object, interfaces, a)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
def self.save_log(object, interfaces, a)
|
92
|
+
interfaces.each do |key, value|
|
93
|
+
klass = "#{object.class.name.underscore}_#{key}_log".classify.constantize
|
94
|
+
r = klass.new
|
95
|
+
r.send(("#{key}_action=").to_sym, a)
|
96
|
+
r.send(("#{key}=".to_sym), value)
|
97
|
+
r.send(("#{key}_ack=").to_sym, false)
|
98
|
+
r.send(("#{key}_complete=").to_sym, false)
|
99
|
+
r.send(("#{object.class.name.demodulize.underscore.gsub("/","_")}_id=").to_sym, object.id)
|
100
|
+
puts r.inspect
|
101
|
+
r.save
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|