sappho-heatmiser-proxy 0.0.1 → 0.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.
- data/lib/sappho-heatmiser-proxy.rb +22 -5
- data/lib/sappho-heatmiser-proxy/heatmiser.rb +66 -73
- data/lib/sappho-heatmiser-proxy/heatmiser_client.rb +28 -28
- data/lib/sappho-heatmiser-proxy/trace_log.rb +3 -4
- data/lib/sappho-heatmiser-proxy/version.rb +1 -1
- metadata +4 -5
- data/lib/sappho-heatmiser-proxy/heatmiser_proxy.rb +0 -42
@@ -8,17 +8,34 @@ module Sappho
|
|
8
8
|
module Proxy
|
9
9
|
|
10
10
|
require 'sappho-heatmiser-proxy/heatmiser'
|
11
|
-
require 'sappho-heatmiser-proxy/
|
11
|
+
require 'sappho-heatmiser-proxy/heatmiser_client'
|
12
|
+
require 'sappho-heatmiser-proxy/client_register'
|
13
|
+
require 'sappho-heatmiser-proxy/trace_log'
|
12
14
|
require 'thread'
|
15
|
+
require 'socket'
|
13
16
|
|
14
17
|
class CommandLine
|
15
18
|
|
16
19
|
def CommandLine.process
|
17
20
|
Thread.abort_on_exception = true
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
Thread.new do
|
22
|
+
clients = ClientRegister.instance
|
23
|
+
port = Integer SystemConfiguration.instance.config['heatmiser.port']
|
24
|
+
log = TraceLog.instance
|
25
|
+
log.info "opening proxy server port #{port}"
|
26
|
+
TCPServer.open port do | server |
|
27
|
+
log.info "proxy server port #{port} is now open"
|
28
|
+
loop do
|
29
|
+
if clients.maxAlreadyConnected?
|
30
|
+
sleep 1
|
31
|
+
else
|
32
|
+
log.info "listening for new clients on proxy server port #{port}"
|
33
|
+
Thread.new server.accept { |client| HeatmiserClient.new(client).communicate }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
Thread.new{Heatmiser.new.monitor}.join
|
22
39
|
end
|
23
40
|
|
24
41
|
end
|
@@ -11,95 +11,88 @@ module Sappho
|
|
11
11
|
require 'sappho-heatmiser-proxy/heatmiser_status'
|
12
12
|
require 'sappho-heatmiser-proxy/trace_log'
|
13
13
|
require 'sappho-heatmiser-proxy/command_queue'
|
14
|
-
require '
|
14
|
+
require 'sappho-heatmiser-proxy/system_configuration'
|
15
15
|
require 'timeout'
|
16
16
|
require 'socket'
|
17
|
-
require 'sappho-heatmiser-proxy/system_configuration'
|
18
17
|
|
19
18
|
class Heatmiser
|
20
19
|
|
21
20
|
def monitor
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
log.info "clock correction: #{TraceLog.hex command}"
|
59
|
-
end
|
21
|
+
status = HeatmiserStatus.instance
|
22
|
+
queue = CommandQueue.instance
|
23
|
+
log = TraceLog.instance
|
24
|
+
config = SystemConfiguration.instance.config
|
25
|
+
hostname = config['heatmiser.address']
|
26
|
+
port = Integer config['heatmiser.port']
|
27
|
+
pin = Integer config['heatmiser.pin']
|
28
|
+
pinLo = pin & 0xFF
|
29
|
+
pinHi = (pin >> 8) & 0xFF
|
30
|
+
queryCommand = HeatmiserCRC.new([0x93, 0x0B, 0x00, pinLo, pinHi, 0x00, 0x00, 0xFF, 0xFF]).appendCRC
|
31
|
+
loop do
|
32
|
+
status.invalidate
|
33
|
+
begin
|
34
|
+
log.info "opening connection to heatmiser at #{hostname}:#{port}"
|
35
|
+
TCPSocket.open hostname, port do | socket |
|
36
|
+
log.info "connected to heatmiser at #{hostname}:#{port}"
|
37
|
+
loop do
|
38
|
+
begin
|
39
|
+
sleep 5
|
40
|
+
command = queryCommand
|
41
|
+
if queuedCommand = queue.get
|
42
|
+
command = queuedCommand
|
43
|
+
else
|
44
|
+
if status.get{status.valid ? status.deviceTimeOffset : 0.0}.abs > 5.0
|
45
|
+
timeNow = Time.now
|
46
|
+
dayOfWeek = timeNow.wday
|
47
|
+
dayOfWeek = 7 if dayOfWeek == 0
|
48
|
+
command = HeatmiserCRC.new([0xA3, 0x12, 0x00, pinLo, pinHi, 0x01, 0x2B, 0x00, 0x07,
|
49
|
+
timeNow.year - 2000,
|
50
|
+
timeNow.month,
|
51
|
+
timeNow.day,
|
52
|
+
dayOfWeek,
|
53
|
+
timeNow.hour,
|
54
|
+
timeNow.min,
|
55
|
+
timeNow.sec]).appendCRC
|
56
|
+
log.info "clock correction: #{TraceLog.hex command}"
|
60
57
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
58
|
+
end
|
59
|
+
log.debug "sending command: #{TraceLog.hex command}" if log.debug?
|
60
|
+
reply = []
|
61
|
+
startTime = Time.now
|
62
|
+
timeout 20 do
|
63
|
+
socket.write command.pack('c*')
|
64
|
+
reply = socket.read(81).unpack('c*')
|
65
|
+
end
|
66
|
+
timestamp = Time.now
|
67
|
+
log.debug "reply: #{TraceLog.hex reply}" if log.debug?
|
68
|
+
crcHi = reply.pop & 0xFF
|
69
|
+
crcLo = reply.pop & 0xFF
|
70
|
+
crc = HeatmiserCRC.new reply
|
71
|
+
if (reply[0] & 0xFF) == 0x94 and reply[1] == 0x51 and reply[2] == 0 and
|
72
|
+
crc.crcHi == crcHi and crc.crcLo == crcLo
|
73
|
+
reply << crcLo << crcHi
|
74
|
+
status.set reply, timestamp, (timestamp - startTime) do
|
75
|
+
queue.completed if queuedCommand
|
79
76
|
end
|
80
|
-
rescue Timeout::Error
|
81
|
-
log.info "heatmiser at #{hostname}:#{port} is not responding - assuming connection down"
|
82
|
-
break
|
83
|
-
rescue => error
|
84
|
-
log.error error
|
85
|
-
break
|
86
77
|
end
|
78
|
+
rescue Timeout::Error
|
79
|
+
log.info "heatmiser at #{hostname}:#{port} is not responding - assuming connection down"
|
80
|
+
break
|
81
|
+
rescue => error
|
82
|
+
log.error error
|
83
|
+
break
|
87
84
|
end
|
88
|
-
log.info "closing connection to heatmiser at #{hostname}:#{port}"
|
89
|
-
socket.close
|
90
85
|
end
|
91
|
-
|
92
|
-
|
86
|
+
log.info "closing connection to heatmiser at #{hostname}:#{port}"
|
87
|
+
socket.close
|
93
88
|
end
|
94
|
-
|
89
|
+
rescue => error
|
90
|
+
log.error error
|
95
91
|
end
|
92
|
+
sleep 10
|
96
93
|
end
|
97
94
|
end
|
98
95
|
|
99
|
-
def wait
|
100
|
-
@thread.join
|
101
|
-
end
|
102
|
-
|
103
96
|
end
|
104
97
|
|
105
98
|
end
|
@@ -7,7 +7,6 @@ module Sappho
|
|
7
7
|
module Heatmiser
|
8
8
|
module Proxy
|
9
9
|
|
10
|
-
require 'thread'
|
11
10
|
require 'socket'
|
12
11
|
require 'sappho-heatmiser-proxy/trace_log'
|
13
12
|
require 'sappho-heatmiser-proxy/heatmiser_status'
|
@@ -16,42 +15,43 @@ module Sappho
|
|
16
15
|
|
17
16
|
class HeatmiserClient
|
18
17
|
|
19
|
-
def
|
18
|
+
def initialize client
|
20
19
|
@clients = ClientRegister.instance
|
21
20
|
@clients.register client
|
22
21
|
@ip = @clients.ip client
|
23
22
|
@client = client
|
24
23
|
@status = HeatmiserStatus.instance
|
25
24
|
@log = TraceLog.instance
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
command = read 5
|
31
|
-
@log.debug "header: #{TraceLog.hex command}" if @log.debug?
|
32
|
-
packetSize = (command[1] & 0xFF) | ((command[2] << 8) & 0x0F00)
|
33
|
-
command += read(packetSize - 5)
|
34
|
-
CommandQueue.instance.push @ip, command unless (command[0] & 0xFF) == 0x93
|
35
|
-
@status.get { @client.write @status.raw.pack('c*') if @status.valid }
|
36
|
-
@log.info "command received from client #{@ip} so it is alive"
|
37
|
-
end
|
38
|
-
rescue Timeout::Error
|
39
|
-
@log.info "no command received from client #{@ip} so presuming it dormant"
|
40
|
-
break
|
41
|
-
rescue HeatmiserClient::ReadError
|
42
|
-
@log.info "unable to receive data from client #{@ip} so presuming it has disconnected"
|
43
|
-
break
|
44
|
-
rescue => error
|
45
|
-
@log.error error
|
46
|
-
break
|
47
|
-
end
|
48
|
-
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def communicate
|
28
|
+
loop do
|
49
29
|
begin
|
50
|
-
|
51
|
-
|
30
|
+
timeout 20 do
|
31
|
+
command = read 5
|
32
|
+
@log.debug "header: #{TraceLog.hex command}" if @log.debug?
|
33
|
+
packetSize = (command[1] & 0xFF) | ((command[2] << 8) & 0x0F00)
|
34
|
+
command += read(packetSize - 5)
|
35
|
+
CommandQueue.instance.push @ip, command unless (command[0] & 0xFF) == 0x93
|
36
|
+
@status.get { @client.write @status.raw.pack('c*') if @status.valid }
|
37
|
+
@log.info "command received from client #{@ip} so it is alive"
|
38
|
+
end
|
39
|
+
rescue Timeout::Error
|
40
|
+
@log.info "no command received from client #{@ip} so presuming it dormant"
|
41
|
+
break
|
42
|
+
rescue HeatmiserClient::ReadError
|
43
|
+
@log.info "unable to receive data from client #{@ip} so presuming it has disconnected"
|
44
|
+
break
|
45
|
+
rescue => error
|
46
|
+
@log.error error
|
47
|
+
break
|
52
48
|
end
|
53
|
-
@clients.unregister @client
|
54
49
|
end
|
50
|
+
begin
|
51
|
+
@client.close
|
52
|
+
rescue
|
53
|
+
end
|
54
|
+
@clients.unregister @client
|
55
55
|
end
|
56
56
|
|
57
57
|
def read size
|
@@ -19,10 +19,9 @@ module Sappho
|
|
19
19
|
|
20
20
|
def initialize
|
21
21
|
@mutex = Mutex.new
|
22
|
-
|
23
|
-
@log = Logger.new
|
24
|
-
@log.level = config['log.debug'] ? Logger::DEBUG : Logger::INFO
|
25
|
-
@log.formatter = proc { |severity, datetime, progname, message| "#{message}\n" }
|
22
|
+
$stdout.sync = true
|
23
|
+
@log = Logger.new $stdout
|
24
|
+
@log.level = SystemConfiguration.instance.config['log.debug'] ? Logger::DEBUG : Logger::INFO
|
26
25
|
@log.info "#{NAME} version #{VERSION} - #{HOMEPAGE}"
|
27
26
|
end
|
28
27
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sappho-heatmiser-proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Andrew Heald
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-02-
|
18
|
+
date: 2012-02-28 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rake
|
@@ -51,7 +51,6 @@ files:
|
|
51
51
|
- lib/sappho-heatmiser-proxy/heatmiser.rb
|
52
52
|
- lib/sappho-heatmiser-proxy/heatmiser_client.rb
|
53
53
|
- lib/sappho-heatmiser-proxy/heatmiser_crc.rb
|
54
|
-
- lib/sappho-heatmiser-proxy/heatmiser_proxy.rb
|
55
54
|
- lib/sappho-heatmiser-proxy/heatmiser_status.rb
|
56
55
|
- lib/sappho-heatmiser-proxy/system_configuration.rb
|
57
56
|
- lib/sappho-heatmiser-proxy/trace_log.rb
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# See https://github.com/sappho/sappho-heatmiser-proxy/wiki for project documentation.
|
2
|
-
# This software is licensed under the GNU Affero General Public License, version 3.
|
3
|
-
# See http://www.gnu.org/licenses/agpl.html for full details of the license terms.
|
4
|
-
# Copyright 2012 Andrew Heald.
|
5
|
-
|
6
|
-
module Sappho
|
7
|
-
module Heatmiser
|
8
|
-
module Proxy
|
9
|
-
|
10
|
-
require 'sappho-heatmiser-proxy/heatmiser_client'
|
11
|
-
require 'sappho-heatmiser-proxy/client_register'
|
12
|
-
require 'thread'
|
13
|
-
require 'socket'
|
14
|
-
require 'sappho-heatmiser-proxy/trace_log'
|
15
|
-
|
16
|
-
class HeatmiserProxy
|
17
|
-
|
18
|
-
def serve
|
19
|
-
Thread.new do
|
20
|
-
clients = ClientRegister.instance
|
21
|
-
port = Integer SystemConfiguration.instance.config['heatmiser.port']
|
22
|
-
log = TraceLog.instance
|
23
|
-
log.info "opening proxy server port #{port}"
|
24
|
-
TCPServer.open port do | server |
|
25
|
-
log.info "proxy server port #{port} is now open"
|
26
|
-
loop do
|
27
|
-
if clients.maxAlreadyConnected?
|
28
|
-
sleep 1
|
29
|
-
else
|
30
|
-
log.info "listening for new clients on proxy server port #{port}"
|
31
|
-
HeatmiserClient.new.session server.accept
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|