mqtt_pipe 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69a8164675982ac052fefb772507fd26f96eac61
4
- data.tar.gz: 6d001fffc5f2007191349ff736d4c3309e716813
3
+ metadata.gz: f579008e0f69a4f8dd375038f2b611d39e82ec07
4
+ data.tar.gz: 4b54e9845ad534d37b6f954028f5c6d9e3bcd83b
5
5
  SHA512:
6
- metadata.gz: 7e530f0ca6aa01fd40858e35993b038b9daa552ef7eb510bff04c9dde3b7b9150b6201bef7d5131183e1bfe369c2fa527348c90e94af38cd0d948b57e576ce79
7
- data.tar.gz: 908eb4630804e017663dd91d2cfc299433fcbcc9f026a6284e023b0cb95ca3f1856fc297a34b5d50470c0b57f805fb369d6a66484d51fb4d71da35ccfdc36151
6
+ metadata.gz: 1ded3c38efb21c73ecb8ac1cb2455cb1dc206e7e6273101fd26672e1c914143748e37862f39e311a79aed4a2fe3b7a2879f48586029d9ac2c96b271f8bd31e68
7
+ data.tar.gz: 249ded44ccac0db4e6f66372f242b99ea9d4c205fc245fe62c4b0233328ceebcfa9536450542dbf72a8af750754fdbf6a38bb648431b792ca24c4c18cf9df50b
data/README.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # MQTTPipe
2
2
 
3
- This gem wraps the [MQTT gem](https://github.com/njh/ruby-mqtt) and adds a serializer for simple data structures.
3
+ This gem wraps the [MQTT gem](https://github.com/njh/ruby-mqtt) and adds a serializer for simple data structures. The serializer is heavily inspired by [MessagePack](http://msgpack.org) and borrows some of their byte values when packing the data. It is however much more restricted in what data types it supports. Right now hashes are for example not supported, but this may change in the future.
4
+
5
+ The reason for the limitations is that the gem is later meant to talk to devices with much more limited hardware (think Arduino, but really the ESP8266).
6
+
7
+ ## TODO
8
+
9
+ 1. Handle disconnects gracefully
10
+ 2. Possibly add a few data types. See below for more details on that.
4
11
 
5
12
  ## Installation
6
13
 
@@ -21,10 +28,26 @@ Or install it yourself as:
21
28
  ## Usage
22
29
 
23
30
  ```ruby
24
- pipe = MQTTPipe.create do
31
+ MQTTPipe.create do
25
32
  on 'hello/world/#' do |message, id|
26
33
  p message, id
27
34
  end
35
+
36
+ open 'test.mosquitto.org', port: 1883 do
37
+ 100.times do |i|
38
+ send "hello/world/#{i}", Time.now
39
+ end
40
+ end
41
+ end
42
+ ```
43
+
44
+ Everything does not need to be contained in a block:
45
+
46
+ ```ruby
47
+ pipe = MQTTPipe.create
48
+
49
+ pipe.on 'hello/#' do
50
+ # do something
28
51
  end
29
52
 
30
53
  pipe.open 'test.mosquitto.org', port: 1883 do
@@ -34,6 +57,53 @@ pipe.open 'test.mosquitto.org', port: 1883 do
34
57
  end
35
58
  ```
36
59
 
60
+ ## Protocol
61
+
62
+ Taking inspiration from the excellent [MessagePack](http://msgpack.org) project each data type is represented by a byte value, or in same cases a range of values. The currently supported data types along with their byte values are:
63
+
64
+ Data type | Byte value (in hex)
65
+ ------------------------- | -------------------
66
+ `0..127` | 0x00 - 0x7F
67
+ `Array` | 0x80 - 0x9F
68
+ `String` | 0xA0 - 0xBF
69
+ `Class` | 0xC0
70
+ `NilClass` | 0xC1
71
+ `FalseClass` | 0xC2
72
+ `TrueClass` | 0xC3
73
+ `8 bit unsigned` | 0xC4
74
+ `6 bit signed` | 0xC5
75
+ `32 bit signed` | 0xC6
76
+ `Float` | 0xC7
77
+ `Time` | 0xC8
78
+ `MQTTPipe::Types::Color` | 0xC9
79
+ - | 0xCA
80
+ - | 0xCB
81
+ - | 0xCC
82
+ - | 0xCD
83
+ - | 0xCE
84
+ - | 0xCF
85
+ `-48..-1` | 0xD0 - 0xFF
86
+
87
+ Note that the integers are split over several codes to accommodate for the various sizes that can occur. Because it is common to send small numerical values these can in most cases be represented by a single byte, instead of two.
88
+
89
+ Array and string are also special cases in that their sizes are not known. They require a length value to be passed along with them, but instead of always including an extra byte for that purpose, length smaller than 32 can be encoded directly in the type byte value. An example is shown below:
90
+
91
+ #### Strings with length 1..31:
92
+
93
+ 'test' -> [0xA0 + 4, 0x74, 0x65, 0x73, 0x74]
94
+
95
+ #### Strings with length 32..288
96
+
97
+ 'testing how really long strings are encoded'
98
+ -> [0xA0, 43 - 32, 0x74, 0x65, 0x73, ...]
99
+
100
+ Some data types that may be supported in the future are:
101
+
102
+ - IP Addresses
103
+ - Hashes
104
+ - Strings longer than 288 characters
105
+ - UTF-8 encoded strings (could be a breaking change)
106
+
37
107
  ## Contributing
38
108
 
39
109
  1. Fork it ( https://github.com/[my-github-username]/mqtt_pipe/fork )
@@ -22,6 +22,27 @@ module MQTTPipe
22
22
  # Use the refinements made to the supported classes
23
23
 
24
24
  using Types
25
+
26
+
27
+ ##
28
+ # Checks whether a class or object is supported by the
29
+ # packer. For arrays each item is checked recursivly
30
+
31
+ def supports_type? type
32
+ if type.is_a? Class
33
+ type.to_packed
34
+ elsif type.is_a? Array
35
+ return type.detect{|obj| not supports_type? obj }.nil?
36
+ else
37
+ type.class.to_packed
38
+ end
39
+ return true
40
+ rescue NoMethodError
41
+ return false
42
+ end
43
+
44
+ alias_method :supports?, :supports_type?
45
+
25
46
 
26
47
  ##
27
48
  # Packs the arguments acording to their type.
@@ -58,6 +79,7 @@ module MQTTPipe
58
79
  return result
59
80
  end
60
81
 
82
+
61
83
  ##
62
84
  # A simple helper method to read a given number of bytes
63
85
  # +from+ IO object and format them +as+ anything
@@ -70,6 +92,7 @@ module MQTTPipe
70
92
  raw.unpack(as).first
71
93
  end
72
94
 
95
+
73
96
  private
74
97
 
75
98
  def unpack_single raw
@@ -1,3 +1,3 @@
1
1
  module MQTTPipe
2
- VERSION = "0.0.2"
3
- end
2
+ VERSION = "0.0.3"
3
+ end
data/spec/packer_spec.rb CHANGED
@@ -3,6 +3,41 @@ require 'mqtt_pipe'
3
3
  describe MQTTPipe::Packer do
4
4
  let(:klass) { MQTTPipe::Packer }
5
5
 
6
+ describe '#supports_type?' do
7
+ it 'expects one argument' do
8
+ expect{klass.supports_type?}.to raise_error ArgumentError
9
+ end
10
+
11
+ context 'When the type is supported' do
12
+ it 'returns true for integers' do
13
+ expect(klass.supports_type? Integer).to be true
14
+ expect(klass.supports_type? Fixnum).to be true
15
+ expect(klass.supports_type? 42).to be true
16
+ end
17
+
18
+ it 'returns true for strings' do
19
+ expect(klass.supports_type? String).to be true
20
+ expect(klass.supports_type? 'string').to be true
21
+ end
22
+
23
+ it 'returns true for arrays containing supported types' do
24
+ expect(klass.supports_type? Array).to be true
25
+ expect(klass.supports_type? [42, 'string']).to be true
26
+ end
27
+ end
28
+
29
+ context 'When the type is not supported' do
30
+ it 'returns false for arbitrary classes/objects' do
31
+ expect(klass.supports_type? Regexp).to be false
32
+ expect(klass.supports_type? /regexp/).to be false
33
+ end
34
+
35
+ it 'returns false for arrays containing unsupported objects' do
36
+ expect(klass.supports_type? [42, /regexp/]).to be false
37
+ end
38
+ end
39
+ end
40
+
6
41
  describe '#pack/#[]' do
7
42
  describe 'Array' do
8
43
  it 'serializes empty arrays to nil' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mqtt_pipe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastian Lindberg