tellstickr 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/Gemfile +2 -0
- data/LICENSE +20 -0
- data/README.md +73 -0
- data/lib/tellstickr.rb +5 -0
- data/lib/tellstickr/core.rb +121 -0
- data/lib/tellstickr/device.rb +55 -0
- data/lib/tellstickr/error.rb +38 -0
- data/lib/tellstickr/sensor.rb +98 -0
- data/lib/tellstickr/version.rb +3 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/tellstickr/core_spec.rb +48 -0
- data/spec/tellstickr/device_spec.rb +52 -0
- data/spec/tellstickr/sensor_spec.rb +51 -0
- data/tellstickr.gemspec +23 -0
- metadata +103 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2f9c593af7b0656ef65d091c54dfc34332947044
|
4
|
+
data.tar.gz: fee091caf447495e468d0d7c0ec051be99625cf9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c419997ae2367ae56ab7186b2d4d85b016998cc24644f86221737fdca3f747f44b3897dfbf8196da858f2c11eeee3ed504cea76a62707a8b60867701fa3f12e5
|
7
|
+
data.tar.gz: 0d6439eb5b4e2735b879ddb854c5d782d06e1c69effabb703ce5aca425666b2f4b3698a21bb60feb216b03caa35f72361d3002e0cfe216b481c09553c36d6814
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2013 Per-Kristian Nordnes
|
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,73 @@
|
|
1
|
+
# TellStickR
|
2
|
+
|
3
|
+
This is a Gem for communicating with the Telldus TellStick and TellStick Duo through the official telldus-core C library in Ruby.
|
4
|
+
|
5
|
+
It also includes device and sensor helper classes for easy communication with various devices and sensors.
|
6
|
+
|
7
|
+
If you didn't know, TellSticks are USB radio frequency transmitters which turns any computer into a wireless home automation center (switch on/off electronic devices, read values from sensors, etc).
|
8
|
+
|
9
|
+
So far, version 2.1.0 of the telldus-core API is supported.
|
10
|
+
|
11
|
+
If you would like to contribute to this code, you are more than welcome to do so!
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
### TellStickR::Core
|
16
|
+
This is the binding to the telldus-core C library, with all functions and statics defined.
|
17
|
+
Documentation on these can be found here: http://developer.telldus.se/doxygen/group__core.html
|
18
|
+
|
19
|
+
### TellStickR::Device
|
20
|
+
Class for easy discovery and manipulation of devices.
|
21
|
+
|
22
|
+
```
|
23
|
+
devices = TellStickR::Device.discover
|
24
|
+
device = devices.first
|
25
|
+
# Turn it on
|
26
|
+
device.on
|
27
|
+
# Turn if off
|
28
|
+
device.off
|
29
|
+
# Make it ring (if supported)
|
30
|
+
device.bell
|
31
|
+
```
|
32
|
+
|
33
|
+
### TellStickR::Sensor
|
34
|
+
Class for easy discovery and reading sensors.
|
35
|
+
|
36
|
+
```
|
37
|
+
sensors = TellStickR::Sensor.discover
|
38
|
+
sensor = sensors.first
|
39
|
+
|
40
|
+
# Poll temperature
|
41
|
+
sensor.temperature
|
42
|
+
|
43
|
+
# Poll humidity
|
44
|
+
sensor.humidtity
|
45
|
+
|
46
|
+
# Register a callback that will be called when the sensor receives new data:
|
47
|
+
callback_id = sensor.register_callback(lambda{|data| puts data.inspect})
|
48
|
+
|
49
|
+
# Unregister a spesific callback:
|
50
|
+
sensor.unregister_callback(callback_id)
|
51
|
+
|
52
|
+
# Unregister all callbacks:
|
53
|
+
sensor.unregister_callbacks
|
54
|
+
|
55
|
+
# If you know the make and sensor id, you can do this
|
56
|
+
# (as long as it's defined in TellStickR::Sensor::PREDEFINED_SENSORS):
|
57
|
+
sensor = TellStickR::Sensor.from_predefined(:wt450h, 11)
|
58
|
+
```
|
59
|
+
|
60
|
+
## Links
|
61
|
+
|
62
|
+
* http://www.telldus.se/products/tellstick
|
63
|
+
* http://developer.telldus.se/
|
64
|
+
|
65
|
+
## Yos and tnx:
|
66
|
+
|
67
|
+
- Virus84 for the nice telldus-core on Raspberry Pi guide (https://blogg.itslav.nu/?p=875) which led to this project.
|
68
|
+
- Hallvar Helleseth for pointing out the Ruby FFI route.
|
69
|
+
- Kristoffer Sivertsen for introducing me to Tellsticks in the first place :)
|
70
|
+
- Telldus for a awesome, cheap and trouble-free product!
|
71
|
+
|
72
|
+
## Legal
|
73
|
+
Copyright (c) 2013 Per-Kristian Nordnes. Released under the MIT license. See the file LICENSE.
|
data/lib/tellstickr.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module TellStickR
|
4
|
+
|
5
|
+
class Core
|
6
|
+
|
7
|
+
# FFI wrapper for the telldus-core C library.
|
8
|
+
# Versions vary of telldus-core API vary, so far version 2.1.0 is supported.
|
9
|
+
# Functions for version 2.1.2 are implemented, but commented out for now.
|
10
|
+
|
11
|
+
extend FFI::Library
|
12
|
+
ffi_lib "telldus-core"
|
13
|
+
|
14
|
+
# Device method flags
|
15
|
+
TELLSTICK_TURNON = 1
|
16
|
+
TELLSTICK_TURNOFF = 2
|
17
|
+
TELLSTICK_BELL = 4
|
18
|
+
TELLSTICK_TOGGLE = 8
|
19
|
+
TELLSTICK_DIM = 16
|
20
|
+
TELLSTICK_LEARN = 32
|
21
|
+
TELLSTICK_EXECUTE = 64
|
22
|
+
TELLSTICK_UP = 128
|
23
|
+
TELLSTICK_DOWN = 256
|
24
|
+
TELLSTICK_STOP = 512
|
25
|
+
|
26
|
+
# Device types
|
27
|
+
TELLSTICK_TYPE_DEVICE = 1
|
28
|
+
TELLSTICK_TYPE_GROUP = 2
|
29
|
+
TELLSTICK_TYPE_SCENE = 3
|
30
|
+
|
31
|
+
# Sensor value types
|
32
|
+
TELLSTICK_TEMPERATURE = 1
|
33
|
+
TELLSTICK_HUMIDITY = 2
|
34
|
+
|
35
|
+
#Controller type
|
36
|
+
TELLSTICK_CONTROLLER_TELLSTICK = 1
|
37
|
+
TELLSTICK_CONTROLLER_TELLSTICK_DUO = 2
|
38
|
+
TELLSTICK_CONTROLLER_TELLSTICK_NET = 3
|
39
|
+
|
40
|
+
# Device changes
|
41
|
+
TELLSTICK_DEVICE_ADDED = 1
|
42
|
+
TELLSTICK_DEVICE_CHANGED = 2
|
43
|
+
TELLSTICK_DEVICE_REMOVED = 3
|
44
|
+
TELLSTICK_DEVICE_STATE_CHANGED = 4
|
45
|
+
|
46
|
+
# Change types
|
47
|
+
TELLSTICK_CHANGE_NAME = 1
|
48
|
+
TELLSTICK_CHANGE_PROTOCOL = 2
|
49
|
+
TELLSTICK_CHANGE_MODEL = 3
|
50
|
+
TELLSTICK_CHANGE_METHOD = 4
|
51
|
+
TELLSTICK_CHANGE_AVAILABLE = 5
|
52
|
+
TELLSTICK_CHANGE_FIRMWARE = 6
|
53
|
+
|
54
|
+
# Error codes
|
55
|
+
TELLSTICK_SUCCESS = 0
|
56
|
+
TELLSTICK_ERROR_NOT_FOUND = -1
|
57
|
+
TELLSTICK_ERROR_PERMISSION_DENIED = -2
|
58
|
+
TELLSTICK_ERROR_DEVICE_NOT_FOUND = -3
|
59
|
+
TELLSTICK_ERROR_METHOD_NOT_SUPPORTED = -4
|
60
|
+
TELLSTICK_ERROR_COMMUNICATION = -5
|
61
|
+
TELLSTICK_ERROR_CONNECTING_SERVICE = -6
|
62
|
+
TELLSTICK_ERROR_UNKNOWN_RESPONSE = -7
|
63
|
+
TELLSTICK_ERROR_SYNTAX = -8
|
64
|
+
TELLSTICK_ERROR_BROKEN_PIPE = -9
|
65
|
+
TELLSTICK_ERROR_COMMUNICATING_SERVICE = -10
|
66
|
+
TELLSTICK_ERROR_UNKNOWN = -99
|
67
|
+
|
68
|
+
# Callbacks
|
69
|
+
callback :TDDeviceEvent, [:int, :int, :string, :int, :pointer], :void
|
70
|
+
callback :TDDeviceChangeEvent, [:int, :int, :int, :int], :void
|
71
|
+
callback :TDRawDeviceEvent, [:string, :int, :int], :void
|
72
|
+
callback :TDSensorEvent, [:string, :string, :int, :int, :string, :int, :int, :pointer], :void
|
73
|
+
callback :TDControllerEvent, [:int, :int, :int, :string, :int], :void
|
74
|
+
|
75
|
+
# Functions
|
76
|
+
attach_function :tdInit, [], :void
|
77
|
+
attach_function :tdRegisterDeviceEvent, [:TDDeviceEvent, :pointer], :int
|
78
|
+
attach_function :tdRegisterRawDeviceEvent, [:TDRawDeviceEvent, :pointer], :int
|
79
|
+
attach_function :tdRegisterDeviceChangeEvent, [:TDDeviceChangeEvent, :pointer], :int
|
80
|
+
attach_function :tdRegisterSensorEvent, [:TDSensorEvent, :pointer], :int
|
81
|
+
# attach_function :tdRegisterControllerEvent, [:TDControllerEvent, :pointer], :int # Version 2.1.2
|
82
|
+
attach_function :tdUnregisterCallback, [:int], :void
|
83
|
+
attach_function :tdClose, [], :void
|
84
|
+
attach_function :tdReleaseString, [:string], :void
|
85
|
+
attach_function :tdTurnOn, [:int], :int
|
86
|
+
attach_function :tdTurnOff, [:int], :int
|
87
|
+
attach_function :tdBell, [:int], :int
|
88
|
+
attach_function :tdDim, [:int], :int
|
89
|
+
attach_function :tdExecute, [:int], :int
|
90
|
+
attach_function :tdUp, [:int], :int
|
91
|
+
attach_function :tdDown, [:int], :int
|
92
|
+
attach_function :tdStop, [:int], :int
|
93
|
+
attach_function :tdLearn, [:int], :int
|
94
|
+
attach_function :tdLastSentCommand, [:int, :int], :int
|
95
|
+
attach_function :tdLastSentValue, [:int], :string
|
96
|
+
attach_function :tdGetNumberOfDevices, [], :int
|
97
|
+
attach_function :tdGetDeviceId, [:int], :int
|
98
|
+
attach_function :tdGetDeviceType, [:int], :int
|
99
|
+
attach_function :tdGetName, [:int], :string
|
100
|
+
attach_function :tdSetName, [:int, :string], :bool
|
101
|
+
attach_function :tdGetProtocol, [:int], :string
|
102
|
+
attach_function :tdSetProtocol, [:int, :string], :bool
|
103
|
+
attach_function :tdGetModel, [:int], :string
|
104
|
+
attach_function :tdSetModel, [:int, :string], :bool
|
105
|
+
attach_function :tdSetDeviceParameter, [:int, :string, :string], :bool
|
106
|
+
attach_function :tdGetDeviceParameter, [:int, :string, :string], :string
|
107
|
+
attach_function :tdAddDevice, [], :int
|
108
|
+
attach_function :tdRemoveDevice, [:int], :bool
|
109
|
+
attach_function :tdMethods, [:int, :int], :int
|
110
|
+
attach_function :tdGetErrorString, [:int], :string
|
111
|
+
attach_function :tdSendRawCommand, [:string, :int], :int
|
112
|
+
attach_function :tdConnectTellStickController, [:int, :int, :string], :void
|
113
|
+
attach_function :tdDisconnectTellStickController, [:int, :int, :string], :void
|
114
|
+
attach_function :tdSensor, [:pointer, :int, :pointer, :int, :pointer, :pointer], :int
|
115
|
+
attach_function :tdSensorValue, [:string, :string, :int, :int, :pointer, :int, :pointer], :int
|
116
|
+
# attach_function :tdController, [:pointer, :pointer, :pointer, :int, :pointer], :int # Version 2.1.2
|
117
|
+
# attach_function :tdControllerValue, [:int, :pointer, :pointer, :int], :int # Version 2.1.2
|
118
|
+
# attach_function :tdSetControllerValue, [:int, :string, :string], :int # Version 2.1.2
|
119
|
+
# attach_function :tdRemoveController, [:int], :int # Version 2.1.2
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module TellStickR
|
2
|
+
|
3
|
+
class Device
|
4
|
+
|
5
|
+
attr_reader :id, :name, :protocol, :model
|
6
|
+
|
7
|
+
def initialize(id, name, protocol, model)
|
8
|
+
@id = id
|
9
|
+
@name = name
|
10
|
+
@protocol = protocol
|
11
|
+
@model = model
|
12
|
+
end
|
13
|
+
|
14
|
+
def learn
|
15
|
+
result = TellStickR::Core.tdLearn(@id)
|
16
|
+
return true if result == TellStickR::Core::TELLSTICK_SUCCESS
|
17
|
+
raise TellStickR::Error.new(result)
|
18
|
+
end
|
19
|
+
|
20
|
+
def on
|
21
|
+
result = TellStickR::Core.tdTurnOn(@id)
|
22
|
+
return true if result == TellStickR::Core::TELLSTICK_SUCCESS
|
23
|
+
raise TellStickR::Error.new(result)
|
24
|
+
end
|
25
|
+
|
26
|
+
def off
|
27
|
+
result = TellStickR::Core.tdTurnOff(@id)
|
28
|
+
return true if result == TellStickR::Core::TELLSTICK_SUCCESS
|
29
|
+
raise TellStickR::Error.new(result)
|
30
|
+
end
|
31
|
+
|
32
|
+
def bell
|
33
|
+
result = TellStickR::Core.tdBell(@id)
|
34
|
+
return true if result == TellStickR::Core::TELLSTICK_SUCCESS
|
35
|
+
raise TellStickR::Error.new(result)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.discover
|
39
|
+
nr_of_devices = TellStickR::Core.tdGetNumberOfDevices
|
40
|
+
i = 0
|
41
|
+
devices = []
|
42
|
+
while(i < nr_of_devices) do
|
43
|
+
id = TellStickR::Core.tdGetDeviceId(i)
|
44
|
+
name = TellStickR::Core.tdGetName(i)
|
45
|
+
protocol = TellStickR::Core.tdGetProtocol(i)
|
46
|
+
model = TellStickR::Core.tdGetModel(i)
|
47
|
+
devices << Device.new(id, name, protocol, model)
|
48
|
+
i += 1
|
49
|
+
end
|
50
|
+
devices
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module TellStickR
|
2
|
+
|
3
|
+
class Error < StandardError
|
4
|
+
|
5
|
+
def initialize(code)
|
6
|
+
@code = code
|
7
|
+
super(human_message)
|
8
|
+
end
|
9
|
+
|
10
|
+
def human_message
|
11
|
+
case @code
|
12
|
+
when TellStickR::Core::TELLSTICK_ERROR_NOT_FOUND
|
13
|
+
"Tellstick not found (#{@code})"
|
14
|
+
when TellStickR::Core::TELLSTICK_ERROR_PERMISSION_DENIED
|
15
|
+
"Permission denied accessing the Tellstick (#{@code})"
|
16
|
+
when TellStickR::Core::TELLSTICK_ERROR_DEVICE_NOT_FOUND
|
17
|
+
"The supplied device id was not found (#{@code})"
|
18
|
+
when TellStickR::Core::TELLSTICK_ERROR_METHOD_NOT_SUPPORTED
|
19
|
+
"The requested method is not supported by the device (#{@code})"
|
20
|
+
when TellStickR::Core::TELLSTICK_ERROR_COMMUNICATION
|
21
|
+
"An error occurred when communicating with the TellStick (#{@code})"
|
22
|
+
when TellStickR::Core::TELLSTICK_ERROR_CONNECTING_SERVICE
|
23
|
+
"The client library could not connect to the service. Maybe it is not running? (#{@code})"
|
24
|
+
when TellStickR::Core::TELLSTICK_ERROR_UNKNOWN_RESPONSE
|
25
|
+
"The client library received a response from the service it did not understand (#{@code})"
|
26
|
+
when TellStickR::Core::TELLSTICK_ERROR_SYNTAX
|
27
|
+
"Input/command could not be parsed or didn't follow input rules (#{@code})"
|
28
|
+
when TellStickR::Core::TELLSTICK_ERROR_BROKEN_PIPE
|
29
|
+
"Pipe broken during communication (#{@code})"
|
30
|
+
when TellStickR::Core::TELLSTICK_ERROR_COMMUNICATING_SERVICE
|
31
|
+
"Timeout waiting for response from the Telldus Service (#{@code})"
|
32
|
+
else TellStickR::Core::TELLSTICK_ERROR_UNKNOWN
|
33
|
+
"An unknown error has occurred (#{@code})"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module TellStickR
|
2
|
+
|
3
|
+
class Sensor
|
4
|
+
|
5
|
+
attr_reader :protocol, :model, :id
|
6
|
+
|
7
|
+
def initialize(protocol, model, id)
|
8
|
+
@protocol = protocol
|
9
|
+
@model = model
|
10
|
+
@id = id
|
11
|
+
@callback_functions = {}
|
12
|
+
TellStickR::Core.tdInit
|
13
|
+
end
|
14
|
+
|
15
|
+
def temperature
|
16
|
+
value = FFI::MemoryPointer.new(:string, 4)
|
17
|
+
time = FFI::MemoryPointer.new(:int, 2)
|
18
|
+
TellStickR::Core.tdSensorValue(@protocol, @model, @id, TellStickR::Core::TELLSTICK_TEMPERATURE, value, 4, time)
|
19
|
+
{value: value.get_string(0,4).to_f, time: Time.at(time.get_int32(0))}
|
20
|
+
end
|
21
|
+
|
22
|
+
def humidity
|
23
|
+
value = FFI::MemoryPointer.new(:string, 4)
|
24
|
+
time = FFI::MemoryPointer.new(:int, 2)
|
25
|
+
TellStickR::Core.tdSensorValue(@protocol, @model, @id, TellStickR::Core::TELLSTICK_HUMIDITY, value, 4, time)
|
26
|
+
{value: value.get_string(0,4).to_f, time: Time.at(time.get_int32(0))}
|
27
|
+
end
|
28
|
+
|
29
|
+
def register_callback(proc)
|
30
|
+
object_id = FFI::MemoryPointer.new(:int32)
|
31
|
+
object_id.write_int32(self.object_id)
|
32
|
+
callback = Proc.new do |protocol, model, id, data_type, value, timestamp, callback_id, context|
|
33
|
+
sensor = ObjectSpace._id2ref(context.get_int32(0))
|
34
|
+
if id == sensor.id
|
35
|
+
sensor.callback_functions[callback_id].call({
|
36
|
+
kind: (data_type == TellStickR::Core::TELLSTICK_TEMPERATURE ? :temperature : :humidity),
|
37
|
+
value: value.to_f, time: Time.at(timestamp.to_i)
|
38
|
+
})
|
39
|
+
end
|
40
|
+
end
|
41
|
+
id = TellStickR::Core.tdRegisterSensorEvent(callback, object_id)
|
42
|
+
@callback_functions[id] = proc
|
43
|
+
id
|
44
|
+
end
|
45
|
+
|
46
|
+
def unregister_callback(id)
|
47
|
+
TellStickR::Core.tdUnregisterCallback(id)
|
48
|
+
@callback_functions.delete(id)
|
49
|
+
end
|
50
|
+
|
51
|
+
def unregister_callbacks
|
52
|
+
@callback_functions.each do |k,v|
|
53
|
+
TellStickR::Core.tdUnregisterCallback(k)
|
54
|
+
@callback_functions.delete(k)
|
55
|
+
end
|
56
|
+
@callback_functions
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.discover
|
60
|
+
TellStickR::Core.tdInit
|
61
|
+
sensors = []
|
62
|
+
result = TellStickR::Core::TELLSTICK_SUCCESS
|
63
|
+
while(true) do
|
64
|
+
protocol = FFI::MemoryPointer.new(:string, 32)
|
65
|
+
model = FFI::MemoryPointer.new(:string, 32)
|
66
|
+
data_types = FFI::MemoryPointer.new(:int, 2)
|
67
|
+
id = FFI::MemoryPointer.new(:int, 2)
|
68
|
+
if TellStickR::Core.tdSensor(protocol, 32, model, 32, id, data_types) == TellStickR::Core::TELLSTICK_SUCCESS
|
69
|
+
sensors << Sensor.new(protocol.get_string(0, 32), model.get_string(0, 32), id.get_int32(0))
|
70
|
+
else
|
71
|
+
break
|
72
|
+
end
|
73
|
+
end
|
74
|
+
sensors
|
75
|
+
end
|
76
|
+
|
77
|
+
# A mapping of known protocols and models
|
78
|
+
# for different sensor products.
|
79
|
+
PREDEFINED_SENSORS = {
|
80
|
+
# Clas Ohlson Esic 36-179* sensors
|
81
|
+
wt450h: {
|
82
|
+
protocol: "mandolyn",
|
83
|
+
model: "temperaturehumidity"
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
def self.from_predefined(key, id)
|
88
|
+
predefined = PREDEFINED_SENSORS[key.to_sym]
|
89
|
+
if predefined
|
90
|
+
return Sensor.new(predefined[:protocol], predefined[:model], id)
|
91
|
+
else
|
92
|
+
raise "Unknown sensor product. Predefined sensors: #{PREDEFINED_SENSORS.map{|k,v| k}.join(', ')}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
require 'rspec'
|
3
|
+
|
4
|
+
SimpleCov.add_filter 'spec'
|
5
|
+
SimpleCov.add_filter 'config'
|
6
|
+
SimpleCov.start
|
7
|
+
|
8
|
+
require 'tellstickr'
|
9
|
+
|
10
|
+
RSpec.configure do |c|
|
11
|
+
c.mock_with :rspec
|
12
|
+
c.before(:each) do
|
13
|
+
end
|
14
|
+
c.around(:each) do |example|
|
15
|
+
example.run
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TellStickR::Core do
|
4
|
+
it 'has defined FFI-functions matching tellstick-core v. 2.1.0' do
|
5
|
+
functions = [
|
6
|
+
:tdInit,
|
7
|
+
:tdRegisterDeviceEvent,
|
8
|
+
:tdRegisterRawDeviceEvent,
|
9
|
+
:tdRegisterDeviceChangeEvent,
|
10
|
+
:tdRegisterSensorEvent,
|
11
|
+
:tdUnregisterCallback,
|
12
|
+
:tdClose,
|
13
|
+
:tdReleaseString,
|
14
|
+
:tdTurnOn,
|
15
|
+
:tdTurnOff,
|
16
|
+
:tdBell,
|
17
|
+
:tdDim,
|
18
|
+
:tdExecute,
|
19
|
+
:tdUp,
|
20
|
+
:tdDown,
|
21
|
+
:tdStop,
|
22
|
+
:tdLearn,
|
23
|
+
:tdLastSentCommand,
|
24
|
+
:tdLastSentValue,
|
25
|
+
:tdGetNumberOfDevices,
|
26
|
+
:tdGetDeviceId,
|
27
|
+
:tdGetDeviceType,
|
28
|
+
:tdGetName,
|
29
|
+
:tdSetName,
|
30
|
+
:tdGetProtocol,
|
31
|
+
:tdSetProtocol,
|
32
|
+
:tdGetModel,
|
33
|
+
:tdSetModel,
|
34
|
+
:tdSetDeviceParameter,
|
35
|
+
:tdGetDeviceParameter,
|
36
|
+
:tdAddDevice,
|
37
|
+
:tdRemoveDevice,
|
38
|
+
:tdMethods,
|
39
|
+
:tdGetErrorString,
|
40
|
+
:tdSendRawCommand,
|
41
|
+
:tdConnectTellStickController,
|
42
|
+
:tdDisconnectTellStickController,
|
43
|
+
:tdSensor,
|
44
|
+
:tdSensorValue
|
45
|
+
]
|
46
|
+
functions.select{|f| TellStickR::Core.methods.include?(f)}.size.should eq functions.size
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe TellStickR::Device do
|
3
|
+
|
4
|
+
let :device do
|
5
|
+
TellStickR::Device.new(12, "Lights", "arctech", "selflearning-switch:nexa")
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'initializes' do
|
9
|
+
device.id.should eq 12
|
10
|
+
device.name.should eq "Lights"
|
11
|
+
device.protocol.should eq "arctech"
|
12
|
+
device.model.should eq "selflearning-switch:nexa"
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'can learn' do
|
16
|
+
allow(TellStickR::Core).to receive(:tdLearn).and_return(TellStickR::Core::TELLSTICK_SUCCESS)
|
17
|
+
device.learn.should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'can be turned on' do
|
21
|
+
allow(TellStickR::Core).to receive(:tdTurnOn).and_return(TellStickR::Core::TELLSTICK_SUCCESS)
|
22
|
+
device.on.should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'can be turned off' do
|
26
|
+
allow(TellStickR::Core).to receive(:tdTurnOff).and_return(TellStickR::Core::TELLSTICK_SUCCESS)
|
27
|
+
device.off.should be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'can be belled' do
|
31
|
+
allow(TellStickR::Core).to receive(:tdBell).and_return(TellStickR::Core::TELLSTICK_SUCCESS)
|
32
|
+
device.bell.should be_true
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'can discover devices' do
|
36
|
+
allow(TellStickR::Core).to receive(:tdGetNumberOfDevices).and_return(1)
|
37
|
+
allow(TellStickR::Core).to receive(:tdGetDeviceId).and_return(12)
|
38
|
+
allow(TellStickR::Core).to receive(:tdGetName).and_return("My Device")
|
39
|
+
allow(TellStickR::Core).to receive(:tdGetProtocol).and_return("arctech")
|
40
|
+
allow(TellStickR::Core).to receive(:tdGetModel).and_return("selflearning-switch:nexa")
|
41
|
+
TellStickR::Device.discover.first.name.should eq "My Device"
|
42
|
+
TellStickR::Device.discover.first.id.should eq 12
|
43
|
+
TellStickR::Device.discover.first.protocol.should eq "arctech"
|
44
|
+
TellStickR::Device.discover.first.model.should eq "selflearning-switch:nexa"
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'gives human readable exception messages' do
|
48
|
+
allow(TellStickR::Core).to receive(:tdBell).and_return(TellStickR::Core::TELLSTICK_ERROR_METHOD_NOT_SUPPORTED)
|
49
|
+
lambda { device.bell }.should raise_error TellStickR::Error, "The requested method is not supported by the device (#{TellStickR::Core::TELLSTICK_ERROR_METHOD_NOT_SUPPORTED})"
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TellStickR::Sensor do
|
4
|
+
|
5
|
+
let :sensor do
|
6
|
+
TellStickR::Sensor.new("mandolyn", "temperaturehumidity", 1)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'initializes' do
|
10
|
+
sensor.protocol.should eq "mandolyn"
|
11
|
+
sensor.model.should eq "temperaturehumidity"
|
12
|
+
sensor.id.should eq 1
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'reads temperature' do
|
16
|
+
sensor.temperature.should == {:value=>0.to_f, :time=>Time.at(0)}
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'reads humidity' do
|
20
|
+
sensor.humidity.should == {:value=>0.to_f, :time=>Time.at(0)}
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'can discover sensors' do
|
24
|
+
TellStickR::Sensor.discover.class.should eq Array
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'has a hash of predefined sensors for easy initialization' do
|
28
|
+
TellStickR::Sensor::PREDEFINED_SENSORS.keys.include?(:wt450h).should be_true
|
29
|
+
end
|
30
|
+
|
31
|
+
it "can initialize from a predefined sensor product if you know the wireless id, and it's defined in TellStickR::Sensor::PREDEFINED_SENSORS" do
|
32
|
+
TellStickR::Sensor.from_predefined(:wt450h, 11).class.should eq TellStickR::Sensor
|
33
|
+
end
|
34
|
+
|
35
|
+
it "can not initialize from a predefined sensor product if the product is not defined" do
|
36
|
+
lambda { TellStickR::Sensor.from_predefined(:wtf, 9)}.should raise_error
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'can register callback functions which are callend when the sensor sends new values' do
|
40
|
+
sensor.register_callback(lambda{|data| puts data.inspect}).class.should eq Fixnum
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'can unregister a callback function from id' do
|
44
|
+
sensor.unregister_callback(1).should be_nil
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'can unregister all callbacks' do
|
48
|
+
sensor.unregister_callbacks.should == {}
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
data/tellstickr.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "tellstickr/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "tellstickr"
|
7
|
+
s.version = TellStickR::VERSION
|
8
|
+
s.authors = ["Per-Kristian Nordnes"]
|
9
|
+
s.email = ["per.kristian.nordnes@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/skogsmaskin/tellstickr"
|
11
|
+
s.summary = %q{Gem for communicating with the Telldus TellStick and TellStick Duo through the official telldus-core C library in Ruby.}
|
12
|
+
s.description = %q{FFI wrapper for the telldus-core C library, and classes for easy communication with various devices and sensors.}
|
13
|
+
s.license = "MIT"
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
|
18
|
+
s.add_development_dependency "rspec"
|
19
|
+
s.add_development_dependency "simplecov"
|
20
|
+
|
21
|
+
s.add_runtime_dependency "ffi"
|
22
|
+
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tellstickr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Per-Kristian Nordnes
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: simplecov
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ffi
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: FFI wrapper for the telldus-core C library, and classes for easy communication
|
56
|
+
with various devices and sensors.
|
57
|
+
email:
|
58
|
+
- per.kristian.nordnes@gmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE
|
66
|
+
- README.md
|
67
|
+
- lib/tellstickr.rb
|
68
|
+
- lib/tellstickr/core.rb
|
69
|
+
- lib/tellstickr/device.rb
|
70
|
+
- lib/tellstickr/error.rb
|
71
|
+
- lib/tellstickr/sensor.rb
|
72
|
+
- lib/tellstickr/version.rb
|
73
|
+
- spec/spec_helper.rb
|
74
|
+
- spec/tellstickr/core_spec.rb
|
75
|
+
- spec/tellstickr/device_spec.rb
|
76
|
+
- spec/tellstickr/sensor_spec.rb
|
77
|
+
- tellstickr.gemspec
|
78
|
+
homepage: https://github.com/skogsmaskin/tellstickr
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
metadata: {}
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubyforge_project:
|
98
|
+
rubygems_version: 2.0.3
|
99
|
+
signing_key:
|
100
|
+
specification_version: 4
|
101
|
+
summary: Gem for communicating with the Telldus TellStick and TellStick Duo through
|
102
|
+
the official telldus-core C library in Ruby.
|
103
|
+
test_files: []
|