Commit 4df50754 by John Doe

added discrete|continuous|event display type

parent df09e963
...@@ -44,10 +44,8 @@ class DbAdapter ...@@ -44,10 +44,8 @@ class DbAdapter
rescue rescue
return nil return nil
end end
#if the url exists but is not a nilm... # if the url exists but is not a nilm...
unless resp.parsed_response.respond_to?(:map) return nil unless resp.parsed_response.respond_to?(:map)
return nil
end
resp.parsed_response.map do |entry| resp.parsed_response.map do |entry|
metadata = if entry[0].match(UpdateStream.decimation_tag).nil? metadata = if entry[0].match(UpdateStream.decimation_tag).nil?
__get_metadata(entry[0]) __get_metadata(entry[0])
...@@ -57,6 +55,18 @@ class DbAdapter ...@@ -57,6 +55,18 @@ class DbAdapter
# The streams are not pure attributes, pull them out # The streams are not pure attributes, pull them out
elements = metadata.delete(:streams) || [] elements = metadata.delete(:streams) || []
elements.each(&:symbolize_keys!) elements.each(&:symbolize_keys!)
# map the legacy discrete flag to new type setting
# discrete == True => type = event
# discrete == False => type = continuous
elements.map! do |e|
next unless e[:type].nil?
e[:display_type] = if e[:discrete]
'event'
else
'continuous'
end
e
end
# Create the schema: # Create the schema:
# 3 elements: path, attributes, elements # 3 elements: path, attributes, elements
{ {
...@@ -84,50 +94,44 @@ class DbAdapter ...@@ -84,50 +94,44 @@ class DbAdapter
end end
def get_count(path, start_time, end_time) def get_count(path, start_time, end_time)
begin resp = self.class.get("#{@url}/stream/extract",
resp = self.class.get("#{@url}/stream/extract", query: {
:query=>{ path: path,
:path=>path, start: start_time,
:start=>start_time, end: end_time,
:end=>end_time, count: 1
:count=>1 })
}) return nil unless resp.success?
return nil unless resp.success? return resp.parsed_response.to_i
return resp.parsed_response.to_i rescue
rescue return nil
return nil
end
end end
def get_data(path, start_time, end_time) def get_data(path, start_time, end_time)
begin resp = self.class.get("#{@url}/stream/extract",
resp = self.class.get("#{@url}/stream/extract", query: {
:query=>{ path: path,
:path=>path, start: start_time,
:start=>start_time, end: end_time,
:end=>end_time, markup: 1
:markup=>1 })
}) return nil unless resp.success?
return nil unless resp.success? return __parse_data(resp.parsed_response)
return __parse_data(resp.parsed_response) rescue
rescue return nil
return nil
end
end end
def get_intervals(path, start_time, end_time) def get_intervals(path, start_time, end_time)
begin resp = self.class.get("#{@url}/stream/intervals",
resp = self.class.get("#{@url}/stream/intervals", query: {
:query=>{ path: path,
:path=>path, start: start_time,
:start=>start_time, end: end_time
:end=>end_time })
}) return nil unless resp.success?
return nil unless resp.success? return __parse_intervals(resp.parsed_response)
return __parse_intervals(resp.parsed_response) rescue
rescue return nil
return nil
end
end end
def _set_path_metadata(path, data) def _set_path_metadata(path, data)
...@@ -163,7 +167,9 @@ class DbAdapter ...@@ -163,7 +167,9 @@ class DbAdapter
# elements are called streams in the nilmdb metadata # elements are called streams in the nilmdb metadata
# and they don't have id or timestamp fields # and they don't have id or timestamp fields
attribs[:streams] = db_stream.db_elements.map do |e| attribs[:streams] = db_stream.db_elements.map do |e|
e.attributes.except('id', 'created_at', 'updated_at', 'db_stream_id') vals = e.attributes.except('id', 'created_at', 'updated_at', 'db_stream_id')
vals[:discrete] = e.display_type=='event'
vals
end end
{ config_key__: attribs.to_json }.to_json { config_key__: attribs.to_json }.to_json
end end
...@@ -200,45 +206,41 @@ class DbAdapter ...@@ -200,45 +206,41 @@ class DbAdapter
# create an array from string response # create an array from string response
def __parse_data(resp) def __parse_data(resp)
return [] if resp==nil #no data returned return [] if resp.nil? # no data returned
data = [] data = []
add_break = false add_break = false
resp.split("\n").each do |row| resp.split("\n").each do |row|
next if row.length==0 #last row is empty (\n) next if row.empty? # last row is empty (\n)
words = row.split(" ") words = row.split(' ')
#check if this is an interval # check if this is an interval
if(words[0]=="#") if words[0] == '#'
#this is a comment line, check if it is an interval boundary marker # this is a comment line, check if it is an interval boundary marker
if(words[1]=="interval-start") intervalStart = words[2].to_i if words[1] == 'interval-start'
intervalStart=words[2].to_i if words[1] == 'interval-end'
end intervalEnd = words[2].to_i
if(words[1]=="interval-end") add_break = true if intervalEnd != intervalStart
intervalEnd=words[2].to_i end
if(intervalEnd!=intervalStart) next
add_break = true end
end data.push(nil) if add_break # add a data break
end add_break = false
next # this is a normal row
end data.push(words.map(&:to_f))
data.push(nil) if(add_break) #add a data break
add_break = false
#this is a normal row
data.push(words.map(&:to_f))
end end
data data
end end
#create horizontal line segments representing # create horizontal line segments representing
#the intervals # the intervals
# #
def __parse_intervals(resp) def __parse_intervals(resp)
intervals = JSON.parse('['+resp.chomp().gsub(/\r\n/,',')+']') intervals = JSON.parse('[' + resp.chomp.gsub(/\r\n/, ',') + ']')
data = [] data = []
intervals.each do |interval| intervals.each do |interval|
data.push([interval[0],0]) data.push([interval[0], 0])
data.push([interval[1],0]) data.push([interval[1], 0])
data.push(nil) #break up the intervals data.push(nil) # break up the intervals
end end
return data data
end end
end end
...@@ -2,16 +2,17 @@ ...@@ -2,16 +2,17 @@
class DbElementsController < ApplicationController class DbElementsController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
def index
@elements = DbElement.find(JSON.decode(params[:elements])) #def index
# make sure the user is allowed to view these elements # @elements = DbElement.find(JSON.parse(params[:elements]))
@elements.each do |elem| # # make sure the user is allowed to view these elements
unless current_user.views_nilm?(elem.db_stream.db.nilm) # @elements.each do |elem|
head :unauthorized # unless current_user.views_nilm?(elem.db_stream.db.nilm)
return # head :unauthorized
end # return
end # end
end # end
#end
def data def data
req_elements = DbElement.find(JSON.parse(params[:elements])) req_elements = DbElement.find(JSON.parse(params[:elements]))
......
...@@ -19,8 +19,8 @@ class DbStreamsController < ApplicationController ...@@ -19,8 +19,8 @@ class DbStreamsController < ApplicationController
params.permit(:name, :description, :name_abbrev, :hidden, params.permit(:name, :description, :name_abbrev, :hidden,
db_elements_attributes: db_elements_attributes:
[:id, :name, :units, :default_max, [:id, :name, :units, :default_max,
:default_min, :scale_factor, :default_min, :scale_factor, :display_type,
:offset, :plottable, :discrete]) :offset, :plottable])
end end
def set_stream def set_stream
......
...@@ -13,6 +13,8 @@ class DbElement < ApplicationRecord ...@@ -13,6 +13,8 @@ class DbElement < ApplicationRecord
validates :scale_factor, presence: true, numericality: true validates :scale_factor, presence: true, numericality: true
validates :default_min, allow_nil: true, numericality: true validates :default_min, allow_nil: true, numericality: true
validates :default_max, allow_nil: true, numericality: true validates :default_max, allow_nil: true, numericality: true
TYPES = %w(discrete continuous event)
validates :display_type, :inclusion => {:in => TYPES}
# force set any validated params to acceptable # force set any validated params to acceptable
# default values this allows us to process corrupt databases # default values this allows us to process corrupt databases
...@@ -23,6 +25,7 @@ class DbElement < ApplicationRecord ...@@ -23,6 +25,7 @@ class DbElement < ApplicationRecord
self.default_max = nil self.default_max = nil
self.scale_factor = 1.0 self.scale_factor = 1.0
self.offset = 0.0 self.offset = 0.0
self.display_type = 'continuous'
end end
def name_path def name_path
...@@ -30,7 +33,7 @@ class DbElement < ApplicationRecord ...@@ -30,7 +33,7 @@ class DbElement < ApplicationRecord
end end
def self.json_keys def self.json_keys
[:id, :db_stream_id, :name, :units, :column, :default_max, :discrete, [:id, :db_stream_id, :name, :units, :column, :default_max,
:default_min, :scale_factor, :offset, :plottable] :default_min, :scale_factor, :offset, :plottable, :display_type]
end end
end end
...@@ -49,6 +49,10 @@ class LoadElementData ...@@ -49,6 +49,10 @@ class LoadElementData
.sort{|a,b| a.end_time > b.end_time } .sort{|a,b| a.end_time > b.end_time }
.first.end_time .first.end_time
end end
if @start_time > @end_time
add_error("invalid time bounds")
return
end
#2 pull data from streams #2 pull data from streams
combined_data = [] combined_data = []
req_streams.each do |stream| req_streams.each do |stream|
......
...@@ -33,6 +33,7 @@ class LoadStreamData ...@@ -33,6 +33,7 @@ class LoadStreamData
plottable_decim = findPlottableDecimationLevel( plottable_decim = findPlottableDecimationLevel(
db_stream, valid_decim, start_time, end_time, resolution db_stream, valid_decim, start_time, end_time, resolution
) )
elements = db_stream.db_elements.order(:column)
if plottable_decim.nil? if plottable_decim.nil?
#check if its nil becuase the nilm isn't available #check if its nil becuase the nilm isn't available
return self unless self.success? return self unless self.success?
...@@ -41,7 +42,7 @@ class LoadStreamData ...@@ -41,7 +42,7 @@ class LoadStreamData
path = __build_path(db_stream, valid_decim.level) path = __build_path(db_stream, valid_decim.level)
resp = @db_adapter.get_intervals(path, start_time, end_time) resp = @db_adapter.get_intervals(path, start_time, end_time)
@data_type = 'interval' @data_type = 'interval'
@data = __build_interval_data(db_stream, resp) @data = __build_interval_data(elements, resp)
return self return self
end end
# request is plottable, see if we can get the raw (level 1) data # request is plottable, see if we can get the raw (level 1) data
...@@ -54,10 +55,13 @@ class LoadStreamData ...@@ -54,10 +55,13 @@ class LoadStreamData
if plottable_decim.level == 1 if plottable_decim.level == 1
@data_type = 'raw' @data_type = 'raw'
@data = __build_raw_data(db_stream, resp) @data = __build_raw_data(elements, resp)
else else
@data_type = 'decimated' @data_type = 'decimated'
@data = __build_decimated_data(db_stream, resp) decimateable_elements = elements.where(display_type: ["continuous","discrete"])
interval_elements = elements.where(display_type: "event")
@data = __build_decimated_data(decimateable_elements, resp) +
__build_intervals_from_decimated_data(interval_elements, resp)
end end
end end
...@@ -150,8 +154,7 @@ class LoadStreamData ...@@ -150,8 +154,7 @@ class LoadStreamData
"#{db_stream.path}~decim-#{level}" "#{db_stream.path}~decim-#{level}"
end end
def __build_raw_data(db_stream, resp) def __build_raw_data(elements, resp)
elements = db_stream.db_elements.order(:column)
data = elements.map { |e| { id: e.id, type: 'raw', values: [] } } data = elements.map { |e| { id: e.id, type: 'raw', values: [] } }
resp.each do |row| resp.each do |row|
if row.nil? # add an interval break to all the elements if row.nil? # add an interval break to all the elements
...@@ -166,8 +169,7 @@ class LoadStreamData ...@@ -166,8 +169,7 @@ class LoadStreamData
return data return data
end end
def __build_decimated_data(db_stream, resp) def __build_decimated_data(elements, resp)
elements = db_stream.db_elements.order(:column)
data = elements.map { |e| { id: e.id, type: 'decimated', values: [] } } data = elements.map { |e| { id: e.id, type: 'decimated', values: [] } }
resp.each do |row| resp.each do |row|
if row.nil? # add an interval break to all the elements if row.nil? # add an interval break to all the elements
...@@ -176,12 +178,13 @@ class LoadStreamData ...@@ -176,12 +178,13 @@ class LoadStreamData
end end
ts = row[0] ts = row[0]
elements.each_with_index do |elem, i| elements.each_with_index do |elem, i|
####TODO: fix offset calcs when elements is a subset
mean_offset = 0 mean_offset = 0
min_offset = elements.length min_offset = elem.db_stream.db_elements.length
max_offset = elements.length*2 max_offset = elem.db_stream.db_elements.length*2
mean = __scale_value(row[1+i+mean_offset],elem) mean = __scale_value(row[1+elem.column+mean_offset],elem)
min = __scale_value(row[1+i+min_offset], elem) min = __scale_value(row[1+elem.column+min_offset], elem)
max = __scale_value(row[1+i+max_offset], elem) max = __scale_value(row[1+elem.column+max_offset], elem)
tmp_min = [min,max].min tmp_min = [min,max].min
max = [min,max].max max = [min,max].max
min = tmp_min min = tmp_min
...@@ -191,11 +194,42 @@ class LoadStreamData ...@@ -191,11 +194,42 @@ class LoadStreamData
return data return data
end end
def __build_interval_data(db_stream, resp) def __build_interval_data(elements, resp)
elements = db_stream.db_elements.order(:column)
elements.map { |e| { id: e.id, type: 'interval', values: resp } } elements.map { |e| { id: e.id, type: 'interval', values: resp } }
end end
#for data that cannot be represented as decimations
# eg: events, compute intervals from the actual decimated data
def __build_intervals_from_decimated_data(elements, resp)
#compute intervals from resp
start_time = resp.first[0]
end_time = resp.last[0]
interval_start = start_time
interval_end = start_time
intervals = []
resp.each do |row|
if row.nil?
intervals += [[interval_start, 0], [interval_end, 0], nil]
interval_start = nil
next
end
if interval_start == nil
interval_start = row[0]
next
end
interval_end = row[0]
end
if interval_start != nil
intervals += [[interval_start, 0], [end_time, 0]]
end
elements.map do |e|
{ id: e.id,
type: 'interval',
values: intervals }
end
end
def __scale_value(value,element) def __scale_value(value,element)
(value.to_f-element.offset)*element.scale_factor (value.to_f-element.offset)*element.scale_factor
end end
......
...@@ -10,7 +10,6 @@ class UpdateDb ...@@ -10,7 +10,6 @@ class UpdateDb
end end
def run(dbinfo, schema) def run(dbinfo, schema)
# check to make sure dbinfo and schema are set # check to make sure dbinfo and schema are set
# if either is nil, the database is not available # if either is nil, the database is not available
if(dbinfo.nil? || schema.nil?) if(dbinfo.nil? || schema.nil?)
......
...@@ -64,7 +64,8 @@ class UpdateStream ...@@ -64,7 +64,8 @@ class UpdateStream
def __build_elements(stream:, stream_data:) def __build_elements(stream:, stream_data:)
stream.column_count.times do |x| stream.column_count.times do |x|
element = stream.db_elements.find_by_column(x) element = stream.db_elements.find_by_column(x)
element ||= DbElement.new(db_stream: stream, column: x) element ||= DbElement.new(db_stream: stream, column: x,
display_type: 'continuous')
# check if there is stream metadata for column x # check if there is stream metadata for column x
entry = stream_data.select { |meta| meta[:column] == x } entry = stream_data.select { |meta| meta[:column] == x }
# use the metadata if present # use the metadata if present
......
class AddTypeToDbElements < ActiveRecord::Migration[5.0]
def change
add_column :db_elements, :type, :string
remove_column :db_elements, :discrete
end
end
class RenameType < ActiveRecord::Migration[5.0]
def change
rename_column :db_elements, :type, :display_type
end
end
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170214031515) do ActiveRecord::Schema.define(version: 20170422184639) do
create_table "db_decimations", force: :cascade do |t| create_table "db_decimations", force: :cascade do |t|
t.integer "start_time", limit: 8 t.integer "start_time", limit: 8
...@@ -36,7 +36,7 @@ ActiveRecord::Schema.define(version: 20170214031515) do ...@@ -36,7 +36,7 @@ ActiveRecord::Schema.define(version: 20170214031515) do
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.boolean "plottable" t.boolean "plottable"
t.boolean "discrete" t.string "display_type"
end end
create_table "db_folders", force: :cascade do |t| create_table "db_folders", force: :cascade do |t|
......
# frozen_string_literal: true
require 'rails_helper' require 'rails_helper'
RSpec.describe DbElementsController, type: :request do RSpec.describe DbElementsController, type: :request do
let(:user1) { create(:confirmed_user, first_name: 'John')} let(:user1) { create(:confirmed_user, first_name: 'John') }
let(:user2) { create(:confirmed_user, first_name: 'Sam')} let(:user2) { create(:confirmed_user, first_name: 'Sam') }
describe 'GET #index' do describe 'GET #data' do
#retrieve data for elements listed by array of ids # retrieve data for elements listed by array of ids
context 'with authenticated user' do context 'with authenticated user' do
before do before do
nilm = create(:nilm, admins: [user1]) nilm = create(:nilm, admins: [user1])
stream = create(:db_stream, elements_count: 0, stream = create(:db_stream, elements_count: 0,
db: nilm.db, db: nilm.db,
db_folder: nilm.db.root_folder) db_folder: nilm.db.root_folder)
@elem1 = create(:db_element) @elem1 = create(:db_element)
@elem2 = create(:db_element) @elem2 = create(:db_element)
stream.db_elements << @elem1 stream.db_elements << @elem1
stream.db_elements << @elem2 stream.db_elements << @elem2
end
it 'returns elements with data' do
@service_data = [{id: @elem1.id, data: 'mock1'}, @service_data = [{ id: @elem1.id, data: 'mock1' },
{id: @elem2.id, data: 'mock2'}] { id: @elem2.id, data: 'mock2' }]
@mock_service = instance_double(LoadElementData, @mock_service = instance_double(LoadElementData,
run: StubService.new, run: StubService.new,
success?: true, notices: [], warnings: [], errors: [], start_time: 0,
data: @service_data) end_time: 1,
success?: true, notices: [], warnings: [], errors: [],
data: @service_data)
allow(LoadElementData).to receive(:new).and_return(@mock_service) allow(LoadElementData).to receive(:new).and_return(@mock_service)
end
it 'returns elements with data' do
@auth_headers = user1.create_new_auth_token @auth_headers = user1.create_new_auth_token
get "/db_elements.json", get '/db_elements/data.json',
params: {elements: [@elem1.id, @elem2.id], params: { elements: [@elem1.id, @elem2.id].to_json,
start_time: 0, end_time: 100}, start_time: 0, end_time: 100 },
headers: @auth_headers headers: @auth_headers
expect(response).to have_http_status(:ok) expect(response).to have_http_status(:ok)
# check to make sure JSON renders the elements # check to make sure JSON renders the elements
body = JSON.parse(response.body) body = JSON.parse(response.body)
...@@ -38,32 +42,31 @@ RSpec.describe DbElementsController, type: :request do ...@@ -38,32 +42,31 @@ RSpec.describe DbElementsController, type: :request do
end end
it 'returns error if time bounds are invalid' do it 'returns error if time bounds are invalid' do
@auth_headers = user1.create_new_auth_token @auth_headers = user1.create_new_auth_token
get "/db_elements.json", get '/db_elements/data.json',
params: {elements: [@elem1.id, @elem2.id], params: { elements: [@elem1.id, @elem2.id].to_json,
start_time: 100, end_time: 0}, start_time: 100, end_time: 0 },
headers: @auth_headers headers: @auth_headers
expect(response).to have_http_status(:unprocessable_entity) expect(response).to have_http_status(:unprocessable_entity)
end end
it 'only allows access to permitted elements' do it 'only allows access to permitted elements' do
nilm2 = create(:nilm, admins: [user2]) nilm2 = create(:nilm, admins: [user2])
stream2 = create(:db_stream, elements_count: 0, stream2 = create(:db_stream, elements_count: 0,
db: nilm2.db, db: nilm2.db,
db_folder: nilm2.db.root_folder) db_folder: nilm2.db.root_folder)
@elem3 = create(:db_element) @elem3 = create(:db_element)
stream2.db_elements << @elem3 stream2.db_elements << @elem3
@auth_headers = user1.create_new_auth_token @auth_headers = user1.create_new_auth_token
get "/db_elements.json", get '/db_elements/data.json',
params: {elements: [@elem1.id, @elem3.id], params: { elements: [@elem1.id, @elem3.id].to_json,
start_time: 100, end_time: 0}, start_time: 100, end_time: 0 },
headers: @auth_headers headers: @auth_headers
expect(response).to have_http_status(:unauthorized) expect(response).to have_http_status(:unauthorized)
end end
end end
context 'without sign-in' do context 'without sign-in' do
it 'returns unauthorized' do it 'returns unauthorized' do
get "/db_elements.json" get '/db_elements/data.json'
expect(response).to have_http_status(:unauthorized) expect(response).to have_http_status(:unauthorized)
end end
end end
......
...@@ -11,6 +11,6 @@ FactoryGirl.define do ...@@ -11,6 +11,6 @@ FactoryGirl.define do
scale_factor 1.0 scale_factor 1.0
offset 0.0 offset 0.0
plottable true plottable true
discrete false display_type 'continuous'
end end
end end
...@@ -7,9 +7,10 @@ FactoryGirl.define do ...@@ -7,9 +7,10 @@ FactoryGirl.define do
name_abbrev { Faker::Lorem.word } name_abbrev { Faker::Lorem.word }
description { Faker::Lorem.sentence } description { Faker::Lorem.sentence }
delete_locked false delete_locked false
start_time { Faker::Number.number(6)} start_time { Faker::Number.number(6).to_i}
end_time { start_time + Faker::Number.number(5) } end_time { start_time + Faker::Number.number(5).to_i }
size_on_disk { Faker::Number.number(6) } total_time {end_time - start_time}
size_on_disk { Faker::Number.number(6).to_i }
hidden false hidden false
path { "/root/streams/#{Faker::Lorem.unique.word}" } path { "/root/streams/#{Faker::Lorem.unique.word}" }
data_type { "float32_#{elements_count}" } data_type { "float32_#{elements_count}" }
......
...@@ -12,7 +12,7 @@ RSpec.describe 'DbElement' do ...@@ -12,7 +12,7 @@ RSpec.describe 'DbElement' do
specify { expect(db_element).to respond_to(:scale_factor) } specify { expect(db_element).to respond_to(:scale_factor) }
specify { expect(db_element).to respond_to(:offset) } specify { expect(db_element).to respond_to(:offset) }
specify { expect(db_element).to respond_to(:plottable) } specify { expect(db_element).to respond_to(:plottable) }
specify { expect(db_element).to respond_to(:discrete) } specify { expect(db_element).to respond_to(:display_type) }
end end
describe 'validation' do describe 'validation' do
......
...@@ -64,12 +64,14 @@ RSpec.describe 'LoadElementData' do ...@@ -64,12 +64,14 @@ RSpec.describe 'LoadElementData' do
describe 'when a nilm does not respond' do describe 'when a nilm does not respond' do
before do before do
db = create(:db, url: 'http://test/nilmdb') db = create(:db, url: 'http://test/nilmdb')
@db_stream1 = create(:db_stream, db: db, elements_count: 0) @db_stream1 = create(:db_stream, db: db, db_folder: db.root_folder,
elements_count: 0)
@elem0 = create(:db_element, column: 0, db_stream: @db_stream1) @elem0 = create(:db_element, column: 0, db_stream: @db_stream1)
@elem1 = create(:db_element, column: 1, db_stream: @db_stream1) @elem1 = create(:db_element, column: 1, db_stream: @db_stream1)
@stream1_data = [{id: @elem0.id, values: 'mock0'}, @stream1_data = [{id: @elem0.id, values: 'mock0'},
{id: @elem1.id, values: 'mock1'}] {id: @elem1.id, values: 'mock1'}]
@db_stream2 = create(:db_stream, db: db, elements_count: 0) @db_stream2 = create(:db_stream, db: db, db_folder: db.root_folder,
elements_count: 0)
@elem2 = create(:db_element, column: 2, db_stream: @db_stream2) @elem2 = create(:db_element, column: 2, db_stream: @db_stream2)
@elem3 = create(:db_element, column: 3, db_stream: @db_stream2) @elem3 = create(:db_element, column: 3, db_stream: @db_stream2)
@stream2_data = [{id: @elem2.id, values: 'mock2'}, @stream2_data = [{id: @elem2.id, values: 'mock2'},
......
...@@ -7,17 +7,20 @@ RSpec.describe 'LoadStreamData' do ...@@ -7,17 +7,20 @@ RSpec.describe 'LoadStreamData' do
describe 'with large datasets' do describe 'with large datasets' do
describe 'when the data is decimated' do describe 'when the data is decimated' do
before do before do
@data = [[98,0,1,2,-1,0,1,1,2,3], #decimated data (3 elements)
@data = [[40,0,1,2,-1,0,1,1,2,3],
nil, nil,
[99,0,1,2,-1,0,1,1,2,3]] [50,0,1,2,-1,0,1,1,2,3]]
@db_stream = create(:db_stream, elements_count: 0, @db_stream = create(:db_stream, elements_count: 0,
db: db, decimations_count: 3, # lvl64 db: db, decimations_count: 3, # lvl64
start_time: 0, end_time: 100) start_time: 0, end_time: 100)
#create the db elements #create the db elements
types = ['discrete','continuous','event']
3.times do |i| 3.times do |i|
@db_stream.db_elements << create(:db_element, @db_stream.db_elements << create(:db_element,
column: i, offset: i+1, scale_factor:i+2) column: i, offset: i+1, scale_factor:i+2, display_type: types[i])
end end
@mockAdapter = MockDataDbAdapter.new( @mockAdapter = MockDataDbAdapter.new(
start_time: @db_stream.start_time, start_time: @db_stream.start_time,
end_time: @db_stream.end_time, end_time: @db_stream.end_time,
...@@ -46,16 +49,29 @@ RSpec.describe 'LoadStreamData' do ...@@ -46,16 +49,29 @@ RSpec.describe 'LoadStreamData' do
end end
it 'populates @data structure with decimated data' do it 'populates @data structure with decimated data' do
@service.run(@db_stream, 10, 90) @service.run(@db_stream, 10, 90)
expect(@service.data.length).to eq 3
d_count = 0
i_count = 0
@service.data.each_with_index do |data,i| @service.data.each_with_index do |data,i|
elem = @db_stream.db_elements.find_by_column(i) elem = @db_stream.db_elements.find_by_column(i)
expect(data[:id]).to eq elem.id expect(data[:id]).to eq elem.id
mean = __scale_value(i,elem) if(elem.display_type=="discrete" || elem.display_type=="continuous")
min = __scale_value(i-1,elem) d_count += 1
max = __scale_value(i+1,elem) mean = __scale_value(i,elem)
expect(data[:values]).to eq([[98,mean,min,max], min = __scale_value(i-1,elem)
nil, max = __scale_value(i+1,elem)
[99,mean,min,max]]) expect(data[:type]).to eq 'decimated'
expect(data[:values]).to eq([[40,mean,min,max],
nil,
[50,mean,min,max]])
else
i_count += 1
expect(data[:type]).to eq 'interval'
expect(data[:values]).to eq [[10,40],[50,90]]
end
end end
expect(d_count).to eq 2 #2 decimated Streams
expect(i_count).to eq 1 #1 interval stream
end end
end end
describe 'when the data is not decimated' do describe 'when the data is not decimated' do
...@@ -96,7 +112,7 @@ RSpec.describe 'LoadStreamData' do ...@@ -96,7 +112,7 @@ RSpec.describe 'LoadStreamData' do
end end
describe 'with small datasets' do describe 'with small datasets' do
before do before do
@data = [[98,0,1,2],nil,[99,0,1,2]] @data = [[40,0,1,2],nil,[50,0,1,2]]
@db_stream = create(:db_stream, elements_count: 0, @db_stream = create(:db_stream, elements_count: 0,
db: db, decimations_count: 3, # lvl64 db: db, decimations_count: 3, # lvl64
start_time: 0, end_time: 100) start_time: 0, end_time: 100)
...@@ -129,9 +145,9 @@ RSpec.describe 'LoadStreamData' do ...@@ -129,9 +145,9 @@ RSpec.describe 'LoadStreamData' do
@service.data.each_with_index do |data,i| @service.data.each_with_index do |data,i|
elem = @db_stream.db_elements.find_by_column(i) elem = @db_stream.db_elements.find_by_column(i)
expect(data[:id]).to eq elem.id expect(data[:id]).to eq elem.id
expect(data[:values]).to eq([[98,(i-elem.offset)*elem.scale_factor], expect(data[:values]).to eq([[40,(i-elem.offset)*elem.scale_factor],
nil, nil,
[99,(i-elem.offset)*elem.scale_factor]]) [50,(i-elem.offset)*elem.scale_factor]])
end end
end end
end end
...@@ -172,6 +188,8 @@ RSpec.describe 'LoadStreamData' do ...@@ -172,6 +188,8 @@ RSpec.describe 'LoadStreamData' do
end end
end end
end end
end end
def __scale_value(value,element) def __scale_value(value,element)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment