tempoiq 1.0.0 → 1.0.2
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 +4 -4
- data/README.md +12 -5
- data/lib/tempoiq/client.rb +40 -2
- data/lib/tempoiq/constants.rb +1 -1
- data/lib/tempoiq/models/single.rb +8 -3
- data/test/client_test.rb +234 -11
- data/test/integration/integration-credentials.yml.example +5 -0
- metadata +22 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfdc25fdc88fdd73576dd4e68649facbf463be7d
|
4
|
+
data.tar.gz: 00605f70755dae0ff641342fe726104d446ca4d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a52391dfe9959ea2c258baceb688e5e65171cc46a4e1d77f36b0d4d3ba05632cdae3e9feb1ca61e81010febbc8ce6267248aa407a532107eb131f415f208d9f
|
7
|
+
data.tar.gz: 892f02d33742ed6a08fedcf3f03576c6abe114198778430dc6154818aa995f1a9925287b1f9804a4238b7fc8c6a8258a33af6b19abb9dee1bfd403f32c5500df
|
data/README.md
CHANGED
@@ -1,11 +1,18 @@
|
|
1
|
-
# TempoIQ
|
1
|
+
# TempoIQ Ruby Library
|
2
2
|
|
3
3
|
## Installation
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
gem install tempoiq
|
8
|
-
|
5
|
+
The TempoIQ Ruby library makes calls to the [TempoIQ API](https://tempoiq.com/). The module is available on rubygems.org as [tempoiq](https://rubygems.org/gems/tempoiq):
|
6
|
+
|
7
|
+
gem install tempoiq
|
8
|
+
|
9
|
+
You can also check out this repository and install locally:
|
10
|
+
|
11
|
+
git clone https://github.com/TempoIQ/tempoiq-ruby.git
|
12
|
+
cd tempoiq-ruby/
|
13
|
+
gem build tempoiq.gemspec
|
14
|
+
gem install tempoiq-<version>.gem
|
15
|
+
|
9
16
|
|
10
17
|
## Quickstart
|
11
18
|
|
data/lib/tempoiq/client.rb
CHANGED
@@ -346,7 +346,7 @@ module TempoIQ
|
|
346
346
|
:content => media_type("query", "v1")))
|
347
347
|
end
|
348
348
|
|
349
|
-
# Read the latest
|
349
|
+
# Read the latest point from a set of Devices / Sensors, with an optional functional pipeline
|
350
350
|
# to transform the values.
|
351
351
|
#
|
352
352
|
# * +selection+ [Selection] - Device selection, describes which Devices / Sensors we should operate on
|
@@ -369,12 +369,50 @@ module TempoIQ
|
|
369
369
|
end
|
370
370
|
|
371
371
|
query = Query.new(Search.new("devices", selection),
|
372
|
-
Single.new(
|
372
|
+
Single.new(:latest),
|
373
373
|
pipeline)
|
374
374
|
|
375
375
|
Cursor.new(Row, remoter, "/v2/single", query)
|
376
376
|
end
|
377
377
|
|
378
|
+
# Read a single point from a set of Devices / Sensors, with an optional functional pipeline
|
379
|
+
# to transform the values.
|
380
|
+
#
|
381
|
+
# * +selection+ [Selection] - Device selection, describes which Devices / Sensors we should operate on
|
382
|
+
# * +function+ [Symbol] - The type of single point query to perform. One of:
|
383
|
+
# * :earliest - get the earliest points from the selection
|
384
|
+
# * :latest - get the latest points from the selection
|
385
|
+
# * :before - get the nearest points before the timestamp
|
386
|
+
# * :after - get the nearest points after the timestamp
|
387
|
+
# * :exact - get the points exactly at the timestamp if any
|
388
|
+
# * :nearest - get the nearest points to the timestamp
|
389
|
+
# * +timestamp+ [Time] (optional)- Time, if any to apply the function to. Not necessary for earliest or latest.
|
390
|
+
# * +pipeline+ [Pipeline] (optional)- Functional pipeline transformation. Supports analytic computation on a stream of DataPoints.
|
391
|
+
#
|
392
|
+
# On success:
|
393
|
+
# - Return a Cursor of Row objects with only one Row inside
|
394
|
+
# On failure:
|
395
|
+
# - Raise an HttpException
|
396
|
+
#
|
397
|
+
# ==== Example
|
398
|
+
# # Find the last DataPoint from Device 'bulding4567' Sensor 'temp1' before January 1, 2013
|
399
|
+
# rows = client.single({:devices => {:key => 'building4567'}, :sensors => {:key => 'temp1'}}, :before, Time.utc(2013, 1, 1))
|
400
|
+
# rows.each do |row|
|
401
|
+
# puts "Data at timestamp: #{row.ts}, value: #{row.value('building4567', 'temp1')}"
|
402
|
+
# end
|
403
|
+
def single(selection, function, timestamp = nil, pipeline = Pipeline.new, &block)
|
404
|
+
if block_given?
|
405
|
+
yield pipeline
|
406
|
+
end
|
407
|
+
|
408
|
+
query = Query.new(Search.new("devices", selection),
|
409
|
+
Single.new(function, timestamp),
|
410
|
+
pipeline)
|
411
|
+
|
412
|
+
Cursor.new(Row, remoter, "/v2/single", query, media_types(:accept => [media_type("error", "v1"), media_type("datapoint-collection", "v1")],
|
413
|
+
:content => media_type("query", "v1")))
|
414
|
+
end
|
415
|
+
|
378
416
|
# Delete datapoints by device and sensor key, start and stop date
|
379
417
|
#
|
380
418
|
# + *device_key* [String] - Device key to read from
|
data/lib/tempoiq/constants.rb
CHANGED
@@ -1,17 +1,22 @@
|
|
1
1
|
module TempoIQ
|
2
2
|
class Single
|
3
|
-
attr_reader :name
|
3
|
+
attr_reader :name, :function, :timestamp, :include_selection
|
4
4
|
attr_accessor :include_selection
|
5
5
|
|
6
|
-
def initialize(include_selection = false)
|
6
|
+
def initialize(function, timestamp = nil, include_selection = false)
|
7
7
|
@name = "single"
|
8
8
|
@include_selection = include_selection
|
9
|
+
@function = function
|
10
|
+
@timestamp = timestamp
|
9
11
|
end
|
10
12
|
|
11
13
|
def to_hash
|
12
|
-
{
|
14
|
+
hash = {
|
15
|
+
"function" => function.to_s,
|
13
16
|
"include_selection" => include_selection
|
14
17
|
}
|
18
|
+
hash["timestamp"] = timestamp.iso8601(3) if timestamp
|
19
|
+
hash
|
15
20
|
end
|
16
21
|
end
|
17
22
|
end
|
data/test/client_test.rb
CHANGED
@@ -442,15 +442,15 @@ module ClientTest
|
|
442
442
|
|
443
443
|
stubbed_read = {
|
444
444
|
"data" => [
|
445
|
-
|
445
|
+
{
|
446
446
|
"t" => ts.iso8601(3),
|
447
447
|
"data" => {
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
448
|
+
device_key => {
|
449
|
+
sensor_key1 => 4.0,
|
450
|
+
sensor_key2 => 2.0
|
451
|
+
}
|
452
|
+
}
|
453
|
+
}
|
454
454
|
],
|
455
455
|
"next_page" => {
|
456
456
|
"next_query" => next_query
|
@@ -512,8 +512,10 @@ module ClientTest
|
|
512
512
|
client.remoter.stub(:get, "/v2/single", 200, JSON.dump(stubbed_single))
|
513
513
|
client.remoter.stub(:post, "/v2/write", 200)
|
514
514
|
|
515
|
-
client.
|
516
|
-
|
515
|
+
client.write_bulk do |write|
|
516
|
+
write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts, 4.0))
|
517
|
+
write.add(device_key, sensor_key2, TempoIQ::DataPoint.new(ts, 2.0))
|
518
|
+
end
|
517
519
|
|
518
520
|
selection = {
|
519
521
|
:devices => {:key => device_key}
|
@@ -526,6 +528,225 @@ module ClientTest
|
|
526
528
|
assert_equal(2.0, rows[0].value(device.key, sensor_key2))
|
527
529
|
end
|
528
530
|
|
531
|
+
def test_earliest
|
532
|
+
device = create_device
|
533
|
+
client = get_client
|
534
|
+
|
535
|
+
device_key = device.key
|
536
|
+
sensor_key1 = device.sensors.first.key
|
537
|
+
sensor_key2 = device.sensors[1].key
|
538
|
+
|
539
|
+
ts = Time.utc(2012, 1, 1)
|
540
|
+
|
541
|
+
stubbed_single = {
|
542
|
+
"data" => [
|
543
|
+
{
|
544
|
+
"t" => ts.iso8601(3),
|
545
|
+
"data" => {
|
546
|
+
device_key => {
|
547
|
+
sensor_key1 => 4.0,
|
548
|
+
sensor_key2 => 2.0
|
549
|
+
}
|
550
|
+
}
|
551
|
+
}
|
552
|
+
]
|
553
|
+
}
|
554
|
+
|
555
|
+
client.remoter.stub(:get, "/v2/single", 200, JSON.dump(stubbed_single))
|
556
|
+
client.remoter.stub(:post, "/v2/write", 200)
|
557
|
+
|
558
|
+
client.write_bulk do |write|
|
559
|
+
write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts, 4.0))
|
560
|
+
write.add(device_key, sensor_key2, TempoIQ::DataPoint.new(ts, 2.0))
|
561
|
+
end
|
562
|
+
|
563
|
+
selection = {
|
564
|
+
:devices => {:key => device_key}
|
565
|
+
}
|
566
|
+
|
567
|
+
rows = client.single(selection, :earliest).to_a
|
568
|
+
|
569
|
+
assert_equal(1, rows.size)
|
570
|
+
assert_equal(4.0, rows[0].value(device.key, sensor_key1))
|
571
|
+
assert_equal(2.0, rows[0].value(device.key, sensor_key2))
|
572
|
+
end
|
573
|
+
|
574
|
+
def test_nearest
|
575
|
+
device = create_device
|
576
|
+
client = get_client
|
577
|
+
|
578
|
+
device_key = device.key
|
579
|
+
sensor_key1 = device.sensors.first.key
|
580
|
+
sensor_key2 = device.sensors[1].key
|
581
|
+
|
582
|
+
ts_before = Time.utc(2011, 6, 1)
|
583
|
+
ts_after = Time.utc(2013, 1, 1)
|
584
|
+
ts_nearest = Time.utc(2012, 1, 1)
|
585
|
+
|
586
|
+
stubbed_single = {
|
587
|
+
"data" => [
|
588
|
+
{
|
589
|
+
"t" => ts_before.iso8601(3),
|
590
|
+
"data" => {
|
591
|
+
device_key => {
|
592
|
+
sensor_key1 => 4.0,
|
593
|
+
sensor_key2 => 2.0
|
594
|
+
}
|
595
|
+
}
|
596
|
+
}
|
597
|
+
]
|
598
|
+
}
|
599
|
+
|
600
|
+
client.remoter.stub(:get, "/v2/single", 200, JSON.dump(stubbed_single))
|
601
|
+
client.remoter.stub(:post, "/v2/write", 200)
|
602
|
+
|
603
|
+
client.write_bulk do |write|
|
604
|
+
write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts_before, 4.0))
|
605
|
+
write.add(device_key, sensor_key2, TempoIQ::DataPoint.new(ts_before, 2.0))
|
606
|
+
write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts_after, 3.0))
|
607
|
+
write.add(device_key, sensor_key2, TempoIQ::DataPoint.new(ts_after, 1.0))
|
608
|
+
end
|
609
|
+
|
610
|
+
selection = {
|
611
|
+
:devices => {:key => device_key}
|
612
|
+
}
|
613
|
+
|
614
|
+
rows = client.single(selection, :nearest, ts_nearest).to_a
|
615
|
+
|
616
|
+
assert_equal(1, rows.size)
|
617
|
+
assert_equal(4.0, rows[0].value(device.key, sensor_key1))
|
618
|
+
assert_equal(2.0, rows[0].value(device.key, sensor_key2))
|
619
|
+
end
|
620
|
+
|
621
|
+
def test_before
|
622
|
+
device = create_device
|
623
|
+
client = get_client
|
624
|
+
|
625
|
+
device_key = device.key
|
626
|
+
sensor_key1 = device.sensors.first.key
|
627
|
+
sensor_key2 = device.sensors[1].key
|
628
|
+
|
629
|
+
ts = Time.utc(2012, 1, 1)
|
630
|
+
|
631
|
+
stubbed_single = {
|
632
|
+
"data" => [
|
633
|
+
{
|
634
|
+
"t" => ts.iso8601(3),
|
635
|
+
"data" => {
|
636
|
+
device_key => {
|
637
|
+
sensor_key1 => 4.0,
|
638
|
+
sensor_key2 => 2.0
|
639
|
+
}
|
640
|
+
}
|
641
|
+
}
|
642
|
+
]
|
643
|
+
}
|
644
|
+
|
645
|
+
client.remoter.stub(:get, "/v2/single", 200, JSON.dump(stubbed_single))
|
646
|
+
client.remoter.stub(:post, "/v2/write", 200)
|
647
|
+
|
648
|
+
client.write_bulk do |write|
|
649
|
+
write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts, 4.0))
|
650
|
+
write.add(device_key, sensor_key2, TempoIQ::DataPoint.new(ts, 2.0))
|
651
|
+
end
|
652
|
+
|
653
|
+
selection = {
|
654
|
+
:devices => {:key => device_key}
|
655
|
+
}
|
656
|
+
|
657
|
+
rows = client.single(selection, :before, ts).to_a
|
658
|
+
|
659
|
+
assert_equal(1, rows.size)
|
660
|
+
assert_equal(4.0, rows[0].value(device.key, sensor_key1))
|
661
|
+
assert_equal(2.0, rows[0].value(device.key, sensor_key2))
|
662
|
+
end
|
663
|
+
|
664
|
+
def test_exact
|
665
|
+
device = create_device
|
666
|
+
client = get_client
|
667
|
+
|
668
|
+
device_key = device.key
|
669
|
+
sensor_key1 = device.sensors.first.key
|
670
|
+
sensor_key2 = device.sensors[1].key
|
671
|
+
|
672
|
+
ts = Time.utc(2012, 1, 1)
|
673
|
+
|
674
|
+
stubbed_single = {
|
675
|
+
"data" => [
|
676
|
+
{
|
677
|
+
"t" => ts.iso8601(3),
|
678
|
+
"data" => {
|
679
|
+
device_key => {
|
680
|
+
sensor_key1 => 4.0,
|
681
|
+
sensor_key2 => 2.0
|
682
|
+
}
|
683
|
+
}
|
684
|
+
}
|
685
|
+
]
|
686
|
+
}
|
687
|
+
|
688
|
+
client.remoter.stub(:get, "/v2/single", 200, JSON.dump(stubbed_single))
|
689
|
+
client.remoter.stub(:post, "/v2/write", 200)
|
690
|
+
|
691
|
+
client.write_bulk do |write|
|
692
|
+
write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts, 4.0))
|
693
|
+
write.add(device_key, sensor_key2, TempoIQ::DataPoint.new(ts, 2.0))
|
694
|
+
end
|
695
|
+
|
696
|
+
selection = {
|
697
|
+
:devices => {:key => device_key}
|
698
|
+
}
|
699
|
+
|
700
|
+
rows = client.single(selection, :exact, ts).to_a
|
701
|
+
|
702
|
+
assert_equal(1, rows.size)
|
703
|
+
assert_equal(4.0, rows[0].value(device.key, sensor_key1))
|
704
|
+
assert_equal(2.0, rows[0].value(device.key, sensor_key2))
|
705
|
+
end
|
706
|
+
|
707
|
+
def test_after
|
708
|
+
device = create_device
|
709
|
+
client = get_client
|
710
|
+
|
711
|
+
device_key = device.key
|
712
|
+
sensor_key1 = device.sensors.first.key
|
713
|
+
sensor_key2 = device.sensors[1].key
|
714
|
+
|
715
|
+
ts = Time.utc(2012, 1, 2)
|
716
|
+
|
717
|
+
stubbed_single = {
|
718
|
+
"data" => [
|
719
|
+
{
|
720
|
+
"t" => ts.iso8601(3),
|
721
|
+
"data" => {
|
722
|
+
device_key => {
|
723
|
+
sensor_key1 => 4.0,
|
724
|
+
sensor_key2 => 2.0
|
725
|
+
}
|
726
|
+
}
|
727
|
+
}
|
728
|
+
]
|
729
|
+
}
|
730
|
+
|
731
|
+
client.remoter.stub(:get, "/v2/single", 200, JSON.dump(stubbed_single))
|
732
|
+
client.remoter.stub(:post, "/v2/write", 200)
|
733
|
+
|
734
|
+
client.write_bulk do |write|
|
735
|
+
write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts, 4.0))
|
736
|
+
write.add(device_key, sensor_key2, TempoIQ::DataPoint.new(ts, 2.0))
|
737
|
+
end
|
738
|
+
|
739
|
+
selection = {
|
740
|
+
:devices => {:key => device_key}
|
741
|
+
}
|
742
|
+
|
743
|
+
rows = client.single(selection, :after, Time.utc(2011, 1, 1)).to_a
|
744
|
+
|
745
|
+
assert_equal(1, rows.size)
|
746
|
+
assert_equal(4.0, rows[0].value(device.key, sensor_key1))
|
747
|
+
assert_equal(2.0, rows[0].value(device.key, sensor_key2))
|
748
|
+
end
|
749
|
+
|
529
750
|
def test_delete_points
|
530
751
|
device = create_device
|
531
752
|
client = get_client
|
@@ -538,8 +759,10 @@ module ClientTest
|
|
538
759
|
|
539
760
|
client.remoter.stub(:post, "/v2/write", 200)
|
540
761
|
|
541
|
-
client.
|
542
|
-
|
762
|
+
client.write_bulk do |write|
|
763
|
+
write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts, 4.0))
|
764
|
+
write.add(device_key, sensor_key2, TempoIQ::DataPoint.new(ts, 2.0))
|
765
|
+
end
|
543
766
|
|
544
767
|
selection = {
|
545
768
|
:devices => {:key => device_key}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tempoiq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TempoIQ Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: test-unit
|
@@ -16,28 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: json
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - ~>
|
32
46
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
47
|
+
version: '1'
|
34
48
|
type: :runtime
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
52
|
- - ~>
|
39
53
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
54
|
+
version: '1'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: httpclient
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -106,6 +120,7 @@ files:
|
|
106
120
|
- lib/trusted-certs.crt
|
107
121
|
- test/client_test.rb
|
108
122
|
- test/integration/integration-credentials.yml
|
123
|
+
- test/integration/integration-credentials.yml.example
|
109
124
|
- test/integration/test_live_client.rb
|
110
125
|
- test/unit/test_cursor.rb
|
111
126
|
- test/unit/test_stubbed_client.rb
|
@@ -129,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
144
|
version: '0'
|
130
145
|
requirements: []
|
131
146
|
rubyforge_project:
|
132
|
-
rubygems_version: 2.4.
|
147
|
+
rubygems_version: 2.4.5
|
133
148
|
signing_key:
|
134
149
|
specification_version: 4
|
135
150
|
summary: TempoIQ http client
|