trigger_switch_d 0.1.1 → 0.1.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.
Files changed (137) hide show
  1. data/README.rdoc +74 -57
  2. data/bin/ts_setup +68 -0
  3. data/bin/{teach → ts_teach} +1 -1
  4. data/bin/{turn_off → ts_turn_off} +1 -1
  5. data/bin/{turn_on → ts_turn_on} +1 -1
  6. data/bin/tsd +1 -1
  7. data/config/environment.rb.sample +42 -0
  8. data/config/lookup.dsl +7 -0
  9. data/lib/tellstick/code_converter.rb +56 -0
  10. data/lib/tellstick/protocol/nexa.rb +25 -10
  11. data/lib/tellstick/protocol/not_connected.rb +6 -14
  12. data/lib/tellstick/protocol/null_protocol.rb +6 -14
  13. data/lib/tellstick/protocol/proove.rb +60 -35
  14. data/lib/tellstick/protocol/protocol_loader.rb +2 -3
  15. data/lib/tellstick/protocol/rising_sun.rb +8 -4
  16. data/lib/tellstick/proxy_io.rb +32 -14
  17. data/lib/tellstick/tellstick.rb +4 -12
  18. data/lib/trigger_switch_d/action.rb +54 -19
  19. data/lib/trigger_switch_d/application.rb +77 -34
  20. data/lib/trigger_switch_d/config.rb +85 -35
  21. data/lib/trigger_switch_d/daylight.rb +135 -52
  22. data/lib/trigger_switch_d/ipc.rb +44 -12
  23. data/lib/trigger_switch_d/schedule.rb +20 -13
  24. data/lib/trigger_switch_d/switch.rb +6 -0
  25. data/lib/trigger_switch_d/trigger_switch_d_helper.rb +14 -13
  26. data/samples/devices +14 -0
  27. data/samples/devices.rising_sun +6 -0
  28. data/samples/environment.rb +44 -0
  29. data/samples/lookup.dsl +7 -0
  30. data/samples/scheduled_actions +6 -0
  31. data/samples/scheduled_actions.rising_sun +4 -0
  32. metadata +41 -116
  33. data/doc/classes/Tellstick/Tellstick.html +0 -117
  34. data/doc/classes/Tellstick/TellstickIO.html +0 -265
  35. data/doc/classes/Tellstick/TellstickIO.src/M000020.html +0 -18
  36. data/doc/classes/Tellstick/TellstickIO.src/M000021.html +0 -20
  37. data/doc/classes/Tellstick/TellstickIO.src/M000022.html +0 -26
  38. data/doc/classes/Tellstick/TellstickIO.src/M000023.html +0 -19
  39. data/doc/classes/Tellstick/TellstickIO.src/M000024.html +0 -26
  40. data/doc/classes/Tellstick/TellstickIO.src/M000025.html +0 -16
  41. data/doc/classes/Tellstick/TellstickIO.src/M000026.html +0 -16
  42. data/doc/classes/Tellstick/TellstickIO.src/M000027.html +0 -24
  43. data/doc/classes/Tellstick.html +0 -204
  44. data/doc/classes/Tellstick.src/M000019.html +0 -25
  45. data/doc/classes/TriggerSwitchD/Action.html +0 -165
  46. data/doc/classes/TriggerSwitchD/Action.src/M000015.html +0 -28
  47. data/doc/classes/TriggerSwitchD/Action.src/M000016.html +0 -18
  48. data/doc/classes/TriggerSwitchD/Application.html +0 -203
  49. data/doc/classes/TriggerSwitchD/Application.src/M000017.html +0 -21
  50. data/doc/classes/TriggerSwitchD/Application.src/M000018.html +0 -40
  51. data/doc/classes/TriggerSwitchD/ConfigFactory/Config.html +0 -127
  52. data/doc/classes/TriggerSwitchD/ConfigFactory/Config.src/M000014.html +0 -23
  53. data/doc/classes/TriggerSwitchD/ConfigFactory.html +0 -141
  54. data/doc/classes/TriggerSwitchD/ConfigFactory.src/M000013.html +0 -24
  55. data/doc/classes/TriggerSwitchD/IPC.html +0 -134
  56. data/doc/classes/TriggerSwitchD/IPC.src/M000012.html +0 -32
  57. data/doc/classes/TriggerSwitchD/Schedule/InstanceMethods.html +0 -242
  58. data/doc/classes/TriggerSwitchD/Schedule/InstanceMethods.src/M000005.html +0 -19
  59. data/doc/classes/TriggerSwitchD/Schedule/InstanceMethods.src/M000006.html +0 -18
  60. data/doc/classes/TriggerSwitchD/Schedule/InstanceMethods.src/M000007.html +0 -23
  61. data/doc/classes/TriggerSwitchD/Schedule/InstanceMethods.src/M000008.html +0 -19
  62. data/doc/classes/TriggerSwitchD/Schedule/InstanceMethods.src/M000009.html +0 -19
  63. data/doc/classes/TriggerSwitchD/Schedule/InstanceMethods.src/M000010.html +0 -18
  64. data/doc/classes/TriggerSwitchD/Schedule/InstanceMethods.src/M000011.html +0 -18
  65. data/doc/classes/TriggerSwitchD/Schedule.html +0 -147
  66. data/doc/classes/TriggerSwitchD/Schedule.src/M000004.html +0 -19
  67. data/doc/classes/TriggerSwitchD/SwitchFactory.html +0 -135
  68. data/doc/classes/TriggerSwitchD/SwitchFactory.src/M000003.html +0 -20
  69. data/doc/classes/TriggerSwitchD.html +0 -212
  70. data/doc/classes/TriggerSwitchD.src/M000001.html +0 -22
  71. data/doc/classes/TriggerSwitchD.src/M000002.html +0 -27
  72. data/doc/created.rid +0 -1
  73. data/doc/files/lib/tellstick/protocol/nexa_rb.html +0 -126
  74. data/doc/files/lib/tellstick/protocol/not_connected_rb.html +0 -126
  75. data/doc/files/lib/tellstick/protocol/null_protocol_rb.html +0 -126
  76. data/doc/files/lib/tellstick/protocol/plain_text_rb.html +0 -126
  77. data/doc/files/lib/tellstick/protocol/proove_rb.html +0 -126
  78. data/doc/files/lib/tellstick/protocol/protocol_loader_rb.html +0 -126
  79. data/doc/files/lib/tellstick/protocol/rising_sun_rb.html +0 -126
  80. data/doc/files/lib/tellstick/protocol/waveman_rb.html +0 -126
  81. data/doc/files/lib/tellstick/tellstick_io_rb.html +0 -135
  82. data/doc/files/lib/tellstick/tellstick_rb.html +0 -135
  83. data/doc/files/lib/tellstick_rb.html +0 -134
  84. data/doc/files/lib/trigger_switch_d/action_rb.html +0 -126
  85. data/doc/files/lib/trigger_switch_d/application_rb.html +0 -136
  86. data/doc/files/lib/trigger_switch_d/config_rb.html +0 -126
  87. data/doc/files/lib/trigger_switch_d/daylight_rb.html +0 -126
  88. data/doc/files/lib/trigger_switch_d/ipc_rb.html +0 -126
  89. data/doc/files/lib/trigger_switch_d/schedule_rb.html +0 -126
  90. data/doc/files/lib/trigger_switch_d/switch_rb.html +0 -126
  91. data/doc/files/lib/trigger_switch_d/trigger_switch_d_helper_rb.html +0 -126
  92. data/doc/files/lib/trigger_switch_d_rb.html +0 -140
  93. data/doc/fr_class_index.html +0 -38
  94. data/doc/fr_file_index.html +0 -46
  95. data/doc/fr_method_index.html +0 -53
  96. data/doc/index.html +0 -24
  97. data/features/execute_schedule.feature +0 -20
  98. data/features/group_aliases.feature +0 -31
  99. data/features/handle_switches.feature +0 -36
  100. data/features/listen_for_client_call.feature +0 -23
  101. data/features/persistent_schedule.feature +0 -70
  102. data/features/proove_protocol.feature +0 -20
  103. data/features/schedule.feature +0 -25
  104. data/features/simple_string_protocol.feature +0 -35
  105. data/features/step_definitions/execute_schedule_steps.rb +0 -16
  106. data/features/step_definitions/group_aliases_steps.rb +0 -24
  107. data/features/step_definitions/handle_switches_steps.rb +0 -21
  108. data/features/step_definitions/listen_for_client_call_steps.rb +0 -34
  109. data/features/step_definitions/persistent_schedule_steps.rb +0 -18
  110. data/features/step_definitions/proove_protocol_steps.rb +0 -3
  111. data/features/step_definitions/schedule_steps.rb +0 -9
  112. data/features/step_definitions/shared_steps.rb +0 -75
  113. data/features/step_definitions/simple_string_protocol_steps.rb +0 -3
  114. data/features/step_definitions/sunrise_steps.rb +0 -22
  115. data/features/step_definitions/tellstick_connected_steps.rb +0 -21
  116. data/features/sunrise.feature +0 -22
  117. data/features/sunset.feature +0 -22
  118. data/features/support/action_helpers.rb +0 -10
  119. data/features/support/env.rb +0 -7
  120. data/features/support/listen_for_client_call_helper.rb +0 -71
  121. data/features/support/proove_helpers.rb +0 -6
  122. data/features/support/sunrise_helper.rb +0 -8
  123. data/features/tellstick_connected.feature +0 -14
  124. data/spec/spec_helper.rb +0 -22
  125. data/spec/tellstick/protocol/nexa_spec.rb +0 -57
  126. data/spec/tellstick/protocol/proove_spec.rb +0 -61
  127. data/spec/tellstick/protocol/rising_sun_spec.rb +0 -56
  128. data/spec/tellstick/protocol/waveman_spec.rb +0 -57
  129. data/spec/tellstick/proxy_io_spec.rb +0 -34
  130. data/spec/tellstick/tellstick_spec.rb +0 -86
  131. data/spec/trigger_switch_d/application_spec.rb +0 -147
  132. data/spec/trigger_switch_d/config_spec.rb +0 -154
  133. data/spec/trigger_switch_d/daylight_spec.rb +0 -39
  134. data/spec/trigger_switch_d/ipc_spec.rb +0 -119
  135. data/spec/trigger_switch_d/schedule_spec.rb +0 -103
  136. data/spec/trigger_switch_d/trigger_switch_d_spec_helpers.rb +0 -24
  137. data/trigger_switch_d.gemspec +0 -43
data/README.rdoc CHANGED
@@ -1,54 +1,68 @@
1
- = trigger_switch_d
1
+ == trigger_switch_d
2
2
 
3
3
  * http://github.com/pfspontus/trigger_switch_d
4
4
 
5
- ==License
6
- See link:License.txt
5
+ == LICENSE
7
6
 
8
- ==Requirements
7
+ See link:LICENSE.txt
8
+
9
+ == REQUIREMENTS
9
10
 
10
11
  Mac OSX
11
- USB dongle (such as tellstick from http://www.telldus.se)
12
- ruby-serialport (http://ruby-serialport.rubyforge.org/)
13
- VCP USB drivers (available at http://ftdichip.com)
12
+ * USB dongle (such as tellstick from http://www.telldus.se)
13
+ * ruby-serialport (http://ruby-serialport.rubyforge.org/)
14
+ * VCP USB drivers (available at http://ftdichip.com)
15
+
16
+ == DESCRIPTION
14
17
 
15
- ==Description
16
18
  Scheduled (tsd) is run as a daemon without any need for user interaction.
17
19
  It sends commands to remote triggered devices such as lamps and switches,
18
20
  to activate/deactive them at scheduled times.
19
21
 
20
- ==Installation
22
+
23
+ == INSTALLATION
24
+
21
25
  1. Get source
22
26
 
23
27
  <tt>git clone git://github.com/pfspontus/trigger_switch_d.git</tt>
24
28
 
25
29
  2. install gem:
26
30
 
27
- <tt>sudo gem install trigger_switch_d</tt>
31
+ <tt>sudo gem install trigger_switch_d</tt>
32
+
33
+ == USAGE
28
34
 
29
- ==Usage
30
- 1. Register you remote triggered devices in a file called devices
31
- using the following format:
32
- ---
33
- - name: "yttertrapp"
34
- switches:
35
- - unit_code: "5"
36
- house_code: A
37
- model_name: plain_text
35
+ Before running tsd you need to do a few things.
38
36
 
39
- 2. Create a schedule in a file called scheduled_actions using the
37
+ 1. Setup required folders and files (home or system) by running
38
+
39
+ <tt>ts_setup (home|system)</tt>
40
+
41
+ make the necessary adjustments in environment.rb
42
+
43
+ 2. Register you remote triggered devices in a file called devices
44
+ using the following format (yaml):<br>
45
+ <pre>---
46
+ - name: "yttertrapp"
47
+ switches:
48
+ - unit_code: "5"
49
+ house_code: A
50
+ model_name: plain_tex
51
+ </pre>
52
+
53
+ 3. Create a schedule in a file called scheduled_actions using the
40
54
  following format:
41
55
 
42
56
  tänd yttertrapp klockan 08:15
43
57
 
44
- where "tänd" is the action, yttertrapp is the device etc. Available
45
- actions are "tänd" and "släck". Device names are the ones from step 1.
58
+ where "tänd" is the action, yttertrapp is the device etc. Available
59
+ actions are "tänd" and "släck". Device names are the ones from step 1.
46
60
 
47
- 3. Copy the files devices and scheduled_actions to the sub-directory db
61
+ 4. Copy the files devices and scheduled_actions to the sub-directory db
48
62
 
49
- 4. run ./bin/tsd
63
+ 5. run tsd
50
64
 
51
- ==Communicating with tsd when it is running
65
+ == COMMUNICATING WITH TSD WHEN IT IS RUNNING
52
66
 
53
67
  Start IRB from a terminal and use UNIXSocket.open("/tmp/com.adhocskill.trigger_switch_d")
54
68
  to open a socket. Strings that tsd will respond to are:
@@ -62,45 +76,48 @@ The list of strings (commands) will get longer with time.
62
76
 
63
77
  Here's an example session:
64
78
 
65
- >> sock = UNIXSocket.open("/tmp/com.adhocskill.trigger_switch_d")
66
- => #<UNIXSocket:0x1017ede78>
67
- >> sock.send("list_schedule",0)
68
- => 13
69
- >> puts sock.recvfrom(1000)[0]
70
- ---
71
- - "släck källare vid soluppgång"
72
- - "släck källare klockan 00:15"
73
- - "tänd källare klockan 04:00"
74
- - "tänd yttertrapp vid solnedgång"
75
- - "släck yttertrapp vid soluppgång"
76
- - "tänd källare vid solnedgång"
77
- => nil
78
- >> sock.send("bye",0)
79
- => 3
80
- >> puts sock.recvfrom(1000)[0]
81
- bye
82
- => nil
83
- >>
84
-
85
- ==Sunrise and sunset
79
+ bq. >> sock = UNIXSocket.open("/tmp/com.adhocskill.trigger_switch_d")<br>
80
+ => #<UNIXSocket:0x1017ede78><br>
81
+ >> sock.send("list_schedule",0)<br>
82
+ => 13<br>
83
+ >> puts sock.recvfrom(1000)[0]<br>
84
+ --- <br>
85
+ - "släck källare vid soluppgång"<br>
86
+ - "släck källare klockan 00:15"<br>
87
+ - "tänd källare klockan 04:00"<br>
88
+ - "tänd yttertrapp vid solnedgång"<br>
89
+ - "släck yttertrapp vid soluppgång"<br>
90
+ - "tänd källare vid solnedgång"<br>
91
+ => nil<br>
92
+ >> sock.send("bye",0)<br>
93
+ => 3<br>
94
+ >> puts sock.recvfrom(1000)[0]<br>
95
+ bye<br>
96
+ => nil<br>
97
+ >> <br>
98
+
99
+ == SUNRISE AND SUNSET
100
+
86
101
  You can schedule an action to occur at sunrise or sunset by typing
87
102
  "vid soluppgång" or "vid solnedgång" instead of "klockan HH:MM" when
88
103
  you schedule your actions. As and example:
89
104
 
90
105
  släck yttertrapp vid soluppgång
91
106
 
92
- ==Locale
107
+ == LOCALE
108
+
93
109
  The file lookup.dsl in the config folder, contains words associated with the
94
110
  actions. The file is pretty much self explanatory feel free to set the words
95
111
  to the language of your choice.
96
112
 
97
- ==File structure
98
- bin:: executable scripts
99
- config:: environment files
100
- db:: files used by tsd
101
- doc:: rdoc documentation of the whole project
102
- feature:: cucumber feature/step files
103
- lib:: project source
104
- log:: scheduled puts a running log here
105
- sample:: some sample files to put in db or config
106
- spec:: rspec bdd files
113
+ == FILE STRUCTURE
114
+
115
+ <pre>bin executable scripts
116
+ config environment files
117
+ db files used by tsd
118
+ doc rdoc documentation of the whole project
119
+ feature cucumber feature/step files
120
+ lib project source
121
+ log scheduled puts a running log here
122
+ sample some sample files to put in db or config
123
+ spec rspec bdd files</pre>
data/bin/ts_setup ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/ruby
2
+ # TriggerSwitchD, executes commands to activate/deactive remote switches.
3
+ # (c) Copyright 2010 Pontus Strömdahl, AdhocSkill.
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+ # ==Usage
19
+ # 1. Deside if you want the required files in your home folder or in a
20
+ # more system wide folder. If you go for the home folder files will
21
+ # be created in ~/.trigger_switch_d. If you go for the system wide
22
+ # folder files will be created in /etc/trigger_switch_d
23
+ #
24
+ # 2. Type:
25
+ #
26
+ # (for home folder)
27
+ # ts_setup home
28
+ #
29
+ # (for system wide folder)
30
+ # ts_setup system
31
+
32
+ if ((ARGV.length != 1) || ((ARGV[0] =~ /^(home|system)$/) == nil))
33
+ puts <<-EOS
34
+ # ==Usage
35
+ # 1. Deside if you want the required files in your home folder or in a
36
+ # more system wide folder. If you go for the home folder files will
37
+ # be created in ~/.trigger_switch_d. If you go for the system wide
38
+ # folder files will be created in /etc/trigger_switch_d
39
+ #
40
+ # 2. Type:
41
+ #
42
+ # (for home folder)
43
+ # ts_setup home
44
+ #
45
+ # (for system wide folder)
46
+ # ts_setup system
47
+ EOS
48
+ exit
49
+ end
50
+
51
+ def create(path)
52
+ db = "db"
53
+ config = "config"
54
+ config_path = "#{path}/#{config}"
55
+ db_path = "#{path}/#{db}"
56
+ `mkdir #{path}`
57
+ `mkdir #{path}/log`
58
+ `mkdir #{db_path}`
59
+ `mkdir #{config_path}`
60
+ `touch #{db_path}/devices`
61
+ `touch #{db_path}/scheduled_actions`
62
+ `cp samples/environment.rb #{config_path}`
63
+ end
64
+
65
+ case ARGV[0]
66
+ when "home" then create("#{File.expand_path("~")}/.trigger_switch_d")
67
+ when "system" then create("/etc/trigger_switch_d")
68
+ end
@@ -37,7 +37,7 @@ require 'tellstick'
37
37
  require 'trigger_switch_d'
38
38
 
39
39
  #code to run tellstick app
40
- File.open(TriggerSwitchD::ConfigFactory::ENV_PATH,"r") do |config_file|
40
+ File.open(TriggerSwitchD::ConfigFactory::ProperEnvironmentFile.new.path,"r") do |config_file|
41
41
  TriggerSwitchD::ConfigFactory.new(config_file)
42
42
  end
43
43
  stick = Tellstick::create(TriggerSwitchD::Config.output,ARGV[2])
@@ -34,7 +34,7 @@ require 'tellstick'
34
34
  require 'trigger_switch_d'
35
35
 
36
36
  #code to run tellstick app
37
- File.open(TriggerSwitchD::ConfigFactory::ENV_PATH,"r") do |config_file|
37
+ File.open(TriggerSwitchD::ConfigFactory::ProperEnvironmentFile.new.path,"r") do |config_file|
38
38
  TriggerSwitchD::ConfigFactory.new(config_file)
39
39
  end
40
40
  stick = Tellstick::create(TriggerSwitchD::Config.output,ARGV[2])
@@ -34,7 +34,7 @@ require 'tellstick'
34
34
  require 'trigger_switch_d'
35
35
 
36
36
  #code to run tellstick app
37
- File.open(TriggerSwitchD::ConfigFactory::ENV_PATH,"r") do |config_file|
37
+ File.open(TriggerSwitchD::ConfigFactory::ProperEnvironmentFile.new.path,"r") do |config_file|
38
38
  TriggerSwitchD::ConfigFactory.new(config_file)
39
39
  end
40
40
  stick = Tellstick::create(TriggerSwitchD::Config.output,ARGV[2])
data/bin/tsd CHANGED
@@ -61,7 +61,7 @@ require 'tellstick'
61
61
  require 'trigger_switch_d'
62
62
 
63
63
  if $0 == __FILE__
64
- file = File.open(TriggerSwitchD::ConfigFactory::ENV_PATH,"r")
64
+ file = File.open(TriggerSwitchD::ConfigFactory::ProperEnvironmentFile.new.path,"r")
65
65
  app = TriggerSwitchD::Application.new(file)
66
66
  file.close
67
67
  app.start
@@ -0,0 +1,42 @@
1
+ # TriggerSwitchD, executes commands to activate/deactive remote switches.
2
+ # (c) Copyright 2010 Pontus Strömdahl, AdhocSkill.
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+
18
+ #longitude and latitude for Malmö, Sweden. decimal form
19
+ Config.geo_position = {:north => 54.57525, :west => -12.94125}
20
+
21
+ #Paths: base for files tsd.log, devices, scheduled_actions and lookup.dsl (leave alone if uncertain)
22
+ Config.log_path = "log"
23
+ Config.db_path = "db"
24
+ Config.dsl_path = "config"
25
+ Config.vcp_port = "/dev/tty.usbserial-A6008UFF"
26
+
27
+ #Log: can be one of :file, :development or :spec (:spec is for the rspecs, ie don't use)
28
+ # when log_object is set to :file, the log is written to tsd.log (log_path + /tsd.log)
29
+ # when log_object is set to :development the log is written to STDOUT, useful for debugging
30
+ # Config.log_object = :file
31
+ Config.log_object = :development
32
+ # Config.log_object = :spec
33
+
34
+ #Output: can be one of :development, :tellstick or :spec (:spec is for the rspecs, ie don't use)
35
+ # when output is set to :development output is written to STDOUT, useful for debugging
36
+ # when output is set to :vcp output is sent to the usb port that has a virtual com port
37
+ # Config.output = :vcp
38
+ Config.output = :development
39
+ # Config.output = :spec
40
+
41
+ #Unix socket: (leave alone if uncertain)
42
+ Config.unix_socket_path = "/tmp"
data/config/lookup.dsl ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ släck: deactivate
3
+ klockan: at
4
+ solnedgång: sunset
5
+ vid: at
6
+ soluppgång: sunrise
7
+ tänd: activate
@@ -0,0 +1,56 @@
1
+ # TriggerSwitchD, executes commands to activate/deactive remote switches.
2
+ # (c) Copyright 2010 Pontus Strömdahl, AdhocSkill.
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ module Tellstick
18
+ #Validates and converts code string to a positive integer
19
+ #Uses an array patters to validate code against
20
+ class CodeConverter
21
+ def initialize(patterns,integer_offset=0)
22
+ @patterns = patterns
23
+ @integer_offset = integer_offset
24
+ end
25
+
26
+ def to_i(code)
27
+ choices = %w{integer_str upcase_str lowcase_str}
28
+ self.class.send(choices[find_parser(code)],code,@integer_offset)
29
+ end
30
+
31
+ private
32
+ def find_parser(code)
33
+ @patterns.each_with_index do |pattern,index|
34
+ result = self.class.match_code(code,pattern,index)
35
+ return result unless result == nil
36
+ end
37
+ end
38
+
39
+ def self.match_code(code,pattern,index)
40
+ return index if ((code =~ pattern) == 0)
41
+ nil
42
+ end
43
+
44
+ def self.integer_str(*args)
45
+ args[0].to_i + args[1]
46
+ end
47
+
48
+ def self.upcase_str(*args)
49
+ args[0][0]-"A"[0]
50
+ end
51
+
52
+ def self.lowcase_str(*args)
53
+ args[0][0]-"a"[0]
54
+ end
55
+ end
56
+ end
@@ -16,6 +16,7 @@
16
16
 
17
17
 
18
18
  require File.join(File.dirname(__FILE__),"protocol_loader")
19
+ require File.join(File.dirname(__FILE__),"..","code_converter")
19
20
 
20
21
  module Tellstick
21
22
  module Nexa #:nodoc:
@@ -26,23 +27,37 @@ module Tellstick
26
27
  def turn_off(house,unit)
27
28
  output.puts "S#{codify(house)}#{codify(unit.to_s)}$k$k$kk$$kk$$k$k$}+"
28
29
  end
29
- def teach(house,unit)
30
- turn_on(house,unit)
30
+ def teach(*args)
31
+ turn_on(*args)
31
32
  end
32
33
  def output
33
34
  @output
34
35
  end
36
+
35
37
  private
38
+
39
+ attr_reader :convert_it
40
+ def convert_it
41
+ @convert_it ||= CodeConverter.new([/[1234]/,/[A-D]/,/[a-d]/],-1)
42
+ end
43
+
36
44
  def codify(code)
37
- tmp_code = ((code =~ /[1234]/) == 0) ? code.to_i - 1: 0
38
- tmp_code = code[0]-"A"[0] if ((code =~ /[A-D]/) == 0)
39
- tmp_code = code[0]-"a"[0] if ((code =~ /[a-d]/) == 0)
40
- result = ["$k$k", "$k$k", "$k$k", "$k$k"]
41
- (0..result.length-1).each do |bit|
42
- result[result.length-1-bit] = "$kk$" if (tmp_code & 1) == 1
43
- tmp_code >>= 1
45
+ Nexa::adjust_result(convert_it.to_i(code)).reverse
46
+ end
47
+
48
+ def self.adjust_result(code)
49
+ choices = %w{$k$k $kk$}
50
+ translate_to_bit_array(code).map do |bit|
51
+ choices[bit]
52
+ end.reverse
53
+ end
54
+
55
+ def self.translate_to_bit_array(code)
56
+ (0..3).map do
57
+ val = (code & 1)
58
+ code >>= 1
59
+ val
44
60
  end
45
- result.reverse
46
61
  end
47
62
  end
48
63
  end
@@ -18,25 +18,17 @@
18
18
  module Tellstick
19
19
  module NotConnected #:nodoc:
20
20
 
21
- def turn_on(house,unit)
22
- [output,STDOUT].each {|o| o.puts attention }
23
- end
24
-
25
- def turn_off(house,unit)
26
- [output,STDOUT].each {|o| o.puts attention }
27
- end
28
-
29
- def teach(house,unit)
30
- [output,STDOUT].each {|o| o.puts attention }
21
+ def attention(*args)
22
+ [output,STDOUT].each {|out| out.puts "Koppla in usb stickan först" }
31
23
  end
24
+
25
+ alias turn_on attention
26
+ alias turn_off attention
27
+ alias teach attention
32
28
 
33
29
  def output
34
30
  @output
35
31
  end
36
32
 
37
- private
38
- def attention
39
- "Koppla in usb stickan först"
40
- end
41
33
  end
42
34
  end
@@ -17,25 +17,17 @@
17
17
 
18
18
  module Tellstick
19
19
  module NullProtocol #:nodoc:
20
- def turn_on(house,unit)
21
- [output,STDOUT].each {|o| o.puts attention }
22
- end
23
-
24
- def turn_off(house,unit)
25
- [output,STDOUT].each {|o| o.puts attention }
26
- end
27
20
 
28
- def teach(house,unit)
29
- [output,STDOUT].each {|o| o.puts attention }
21
+ def attention(*args)
22
+ [output,STDOUT].each {|out| out.puts "Protokollet finns inte" }
30
23
  end
31
24
 
25
+ alias turn_on attention
26
+ alias turn_off attention
27
+ alias teach attention
28
+
32
29
  def output
33
30
  @output
34
31
  end
35
-
36
- private
37
- def attention
38
- "Protokollet finns inte"
39
- end
40
32
  end
41
33
  end
@@ -16,22 +16,26 @@
16
16
 
17
17
 
18
18
  require File.join(File.dirname(__FILE__),"protocol_loader")
19
+ require File.join(File.dirname(__FILE__),"..","code_converter")
19
20
 
20
21
  module Tellstick
21
22
  module Proove #:nodoc:
22
23
  include ProtocolLoader
23
- def turn_on(house,unit)
24
- output.puts build_command_string(house,unit,true)
24
+ def turn_on(*args)
25
+ args << true
26
+ output.puts build_command_string(*Proove::preprocess_build_command_args(*args))
25
27
  end
26
28
 
27
- def turn_off(house,unit)
28
- output.puts build_command_string(house,unit,false)
29
+ def turn_off(*args)
30
+ args << false
31
+ output.puts build_command_string(*Proove::preprocess_build_command_args(*args))
29
32
  end
30
33
 
31
- def teach(house,unit)
32
- (1..5).each do |i|
33
- output.puts build_command_string(house,unit,true,2)
34
- output.gets
34
+ def teach(*args)
35
+ args += [true,2]
36
+ (1..5).each do
37
+ @output.puts build_command_string(*Proove::preprocess_build_command_args(*args))
38
+ @output.gets
35
39
  sleep 0.2
36
40
  end
37
41
  end
@@ -41,43 +45,64 @@ module Tellstick
41
45
  end
42
46
 
43
47
  private
44
- def part_for(code,number_of_bits)
48
+
49
+ attr_reader :convert_it
50
+ def convert_it
51
+ @convert_it ||= CodeConverter.new([/\d+/,/[A-D]/,/[a-d]/])
52
+ end
53
+
54
+ def self.part_for(code,number_of_bits)
45
55
  result = ""
46
- (0..number_of_bits).each do |i|
47
- result << (((code & 1) << (number_of_bits - i) == 1)? "10" : "01")
56
+ (0..number_of_bits).each do |index|
57
+ result << (((code & 1) << (number_of_bits - index) == 1)? "10" : "01")
48
58
  end
49
59
  result
50
60
  end
51
61
 
52
- def translate(code_part)
53
- result = ""
62
+ def self.character_bit_pattern(code,character)
63
+ code <<= 4
64
+ return (code | 8) if character == "1"
65
+ (code | 10)
66
+ end
67
+
68
+ def self.translate(code_part)
54
69
  code = 9
55
- code_part.scan(/./).each_with_index do |c,i|
56
- code <<= 4
57
- if c == "1"
58
- code |= 8
59
- else
60
- code |= 10
61
- end
62
- if (i % 2 == 0)
63
- result << code.chr
64
- code = 0
65
- end
70
+ translate_inner(code_part) do |result, character,index|
71
+ code = code_tmp = character_bit_pattern(code,character)
72
+ code = 0 if (index % 2 == 0)
73
+ translate_update_result(result,code_tmp,index)
74
+ end
75
+ end
76
+
77
+ def self.translate_update_result(result,code,index)
78
+ return result if (index % 2 != 0)
79
+ result << code.chr
80
+ end
81
+
82
+ def self.translate_inner(code_part)
83
+ index = 0
84
+ code_part.scan(/./).inject("") do |result, character|
85
+ result = yield(result, character, index)
86
+ index += 1
87
+ result
66
88
  end
67
- result
68
89
  end
69
90
 
70
- def build_command_string(house,unit,on,number_repeat=5)
71
- house_code = ((house =~ /\d+/) == 0) ? house.to_i : 0
72
- house_code = house[0]-"A"[0] if ((house =~ /[A-Z]/) == 0)
73
- house_code = house[0]-"a"[0] if ((house =~ /[a-z]/) == 0)
91
+ def self.signal_part(house_code, unit,on_off)
74
92
  unit_code = unit.to_i - 1
75
-
76
- on_off = on ? "10" : "01"
77
-
78
- signal_part = "#{part_for(house_code,25)}01#{on_off}#{part_for(unit_code,3)}0"
79
-
80
- "R#{number_repeat.chr}T\177\377\030\001\204#{translate(signal_part)}+"
93
+ Proove::translate("#{part_for(house_code,25)}01#{on_off}#{part_for(unit_code,3)}0")
81
94
  end
95
+
96
+ def self.preprocess_build_command_args(*args)
97
+ args << 5 if args.length < 4
98
+ args
99
+ end
100
+
101
+ def build_command_string(*args)
102
+ house,unit,on,number_repeat = args
103
+ house_code = convert_it.to_i(house)
104
+ on_off = on ? "10" : "01"
105
+ "R#{number_repeat.chr}T\177\377\030\001\204#{Proove::signal_part(house_code,unit,on_off)}+"
106
+ end
82
107
  end
83
108
  end
@@ -18,9 +18,8 @@
18
18
  module Tellstick
19
19
  module ProtocolLoader #:nodoc:
20
20
  def self.included(klass)
21
- p = klass
22
- key = p.name.gsub("Tellstick::","").split(/(?=[A-Z])/).map{|w| w.downcase}.join("_")
23
- $protocol[key] = p
21
+ key = klass.name.gsub("Tellstick::","").split(/(?=[A-Z])/).map{|name| name.downcase}.join("_")
22
+ $protocol[key] = klass
24
23
  end
25
24
  end
26
25
  end