sappho-heatmiser-proxy 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.
- data/bin/sappho-heatmiser-proxy +12 -12
 - data/lib/sappho-heatmiser-proxy.rb +44 -35
 - data/lib/sappho-heatmiser-proxy/command_queue.rb +60 -60
 - data/lib/sappho-heatmiser-proxy/heatmiser.rb +96 -86
 - data/lib/sappho-heatmiser-proxy/heatmiser_client.rb +78 -78
 - data/lib/sappho-heatmiser-proxy/heatmiser_crc.rb +48 -48
 - data/lib/sappho-heatmiser-proxy/heatmiser_status.rb +131 -136
 - data/lib/sappho-heatmiser-proxy/model/heatmiser_log.rb +29 -0
 - data/lib/sappho-heatmiser-proxy/system_configuration.rb +48 -33
 - data/lib/sappho-heatmiser-proxy/version.rb +18 -18
 - metadata +59 -10
 
    
        data/bin/sappho-heatmiser-proxy
    CHANGED
    
    | 
         @@ -1,12 +1,12 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #!/usr/bin/env ruby
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            # See https://github.com/sappho/sappho-heatmiser-proxy/wiki for project documentation.
         
     | 
| 
       4 
     | 
    
         
            -
            # This software is licensed under the GNU Affero General Public License, version 3.
         
     | 
| 
       5 
     | 
    
         
            -
            # See http://www.gnu.org/licenses/agpl.html for full details of the license terms.
         
     | 
| 
       6 
     | 
    
         
            -
            # Copyright 2012 Andrew Heald.
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
            require 'sappho-heatmiser-proxy'
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
            Sappho::Heatmiser::Proxy::CommandLine.process
         
     | 
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # See https://github.com/sappho/sappho-heatmiser-proxy/wiki for project documentation.
         
     | 
| 
      
 4 
     | 
    
         
            +
            # This software is licensed under the GNU Affero General Public License, version 3.
         
     | 
| 
      
 5 
     | 
    
         
            +
            # See http://www.gnu.org/licenses/agpl.html for full details of the license terms.
         
     | 
| 
      
 6 
     | 
    
         
            +
            # Copyright 2012 Andrew Heald.
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            $: << File.expand_path('../lib', __FILE__)
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            require 'sappho-heatmiser-proxy'
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            Sappho::Heatmiser::Proxy::CommandLine.process
         
     | 
| 
         @@ -1,35 +1,44 @@ 
     | 
|
| 
       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'
         
     | 
| 
       11 
     | 
    
         
            -
                  require 'sappho-heatmiser-proxy/heatmiser_client'
         
     | 
| 
       12 
     | 
    
         
            -
                  require 'sappho-basics/auto_flush_log'
         
     | 
| 
       13 
     | 
    
         
            -
                  require 'sappho-socket/safe_server'
         
     | 
| 
       14 
     | 
    
         
            -
                  require 'sappho-heatmiser-proxy/version'
         
     | 
| 
       15 
     | 
    
         
            -
                  require ' 
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                   
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                       
     | 
| 
       23 
     | 
    
         
            -
                       
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                       
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
      
 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'
         
     | 
| 
      
 11 
     | 
    
         
            +
                  require 'sappho-heatmiser-proxy/heatmiser_client'
         
     | 
| 
      
 12 
     | 
    
         
            +
                  require 'sappho-basics/auto_flush_log'
         
     | 
| 
      
 13 
     | 
    
         
            +
                  require 'sappho-socket/safe_server'
         
     | 
| 
      
 14 
     | 
    
         
            +
                  require 'sappho-heatmiser-proxy/version'
         
     | 
| 
      
 15 
     | 
    
         
            +
                  require 'mongo_mapper'
         
     | 
| 
      
 16 
     | 
    
         
            +
                  require 'mongo/connection'
         
     | 
| 
      
 17 
     | 
    
         
            +
                  require 'thread'
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  class CommandLine
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    def CommandLine.process
         
     | 
| 
      
 22 
     | 
    
         
            +
                      log = Sappho::ApplicationAutoFlushLog.instance
         
     | 
| 
      
 23 
     | 
    
         
            +
                      log.info "#{NAME} version #{VERSION} - #{HOMEPAGE}"
         
     | 
| 
      
 24 
     | 
    
         
            +
                      config = SystemConfiguration.instance
         
     | 
| 
      
 25 
     | 
    
         
            +
                      if config.mongoLogging
         
     | 
| 
      
 26 
     | 
    
         
            +
                        log.info "connecting to mongodb database #{config.mongodbDatabase} on #{config.mongodbHostname}:#{config.mongodbPort}"
         
     | 
| 
      
 27 
     | 
    
         
            +
                        MongoMapper.connection = Mongo::Connection.new config.mongodbHostname, config.mongodbPort
         
     | 
| 
      
 28 
     | 
    
         
            +
                        MongoMapper.database = config.mongodbDatabase
         
     | 
| 
      
 29 
     | 
    
         
            +
                      else
         
     | 
| 
      
 30 
     | 
    
         
            +
                        log.info 'logging to mongodb is disabled'
         
     | 
| 
      
 31 
     | 
    
         
            +
                      end
         
     | 
| 
      
 32 
     | 
    
         
            +
                      Sappho::Socket::SafeServer.new('heatmiser proxy', config.heatmiserPort, config.maxClients, config.detailedLogging).serve do
         
     | 
| 
      
 33 
     | 
    
         
            +
                        | socket, ip | HeatmiserClient.new(socket, ip).communicate
         
     | 
| 
      
 34 
     | 
    
         
            +
                      end
         
     | 
| 
      
 35 
     | 
    
         
            +
                      Thread.new do
         
     | 
| 
      
 36 
     | 
    
         
            +
                        Heatmiser.new.monitor
         
     | 
| 
      
 37 
     | 
    
         
            +
                      end.join
         
     | 
| 
      
 38 
     | 
    
         
            +
                    end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,60 +1,60 @@ 
     | 
|
| 
       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 'singleton'
         
     | 
| 
       11 
     | 
    
         
            -
                  require 'thread'
         
     | 
| 
       12 
     | 
    
         
            -
                  require 'sappho-basics/auto_flush_log'
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                  class CommandQueue
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                    include Singleton, Sappho::LogUtilities
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                    def initialize
         
     | 
| 
       19 
     | 
    
         
            -
                      @queue = []
         
     | 
| 
       20 
     | 
    
         
            -
                      @mutex = Mutex.new
         
     | 
| 
       21 
     | 
    
         
            -
                      @log = Sappho::ApplicationAutoFlushLog.instance
         
     | 
| 
       22 
     | 
    
         
            -
                    end
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                    def push clientIP, command
         
     | 
| 
       25 
     | 
    
         
            -
                      @log.info "client #{clientIP} requests command: #{hexString command}"
         
     | 
| 
       26 
     | 
    
         
            -
                      @mutex.synchronize do
         
     | 
| 
       27 
     | 
    
         
            -
                        @queue << {
         
     | 
| 
       28 
     | 
    
         
            -
                            :clientIP => clientIP,
         
     | 
| 
       29 
     | 
    
         
            -
                            :command => command.dup
         
     | 
| 
       30 
     | 
    
         
            -
                        }
         
     | 
| 
       31 
     | 
    
         
            -
                      end
         
     | 
| 
       32 
     | 
    
         
            -
                    end
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                    def get
         
     | 
| 
       35 
     | 
    
         
            -
                      command = nil
         
     | 
| 
       36 
     | 
    
         
            -
                      @mutex.synchronize do
         
     | 
| 
       37 
     | 
    
         
            -
                        if @queue.size > 0
         
     | 
| 
       38 
     | 
    
         
            -
                          queue = @queue[0]
         
     | 
| 
       39 
     | 
    
         
            -
                          command = queue[:command].dup
         
     | 
| 
       40 
     | 
    
         
            -
                          @log.info "client #{queue[:clientIP]} command executing: #{hexString command}"
         
     | 
| 
       41 
     | 
    
         
            -
                        end
         
     | 
| 
       42 
     | 
    
         
            -
                      end
         
     | 
| 
       43 
     | 
    
         
            -
                      command
         
     | 
| 
       44 
     | 
    
         
            -
                    end
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                    def completed
         
     | 
| 
       47 
     | 
    
         
            -
                      @mutex.synchronize do
         
     | 
| 
       48 
     | 
    
         
            -
                        if @queue.size > 0
         
     | 
| 
       49 
     | 
    
         
            -
                          queue = @queue[0]
         
     | 
| 
       50 
     | 
    
         
            -
                          @log.info "client #{queue[:clientIP]} command completed: #{hexString queue[:command]}"
         
     | 
| 
       51 
     | 
    
         
            -
                          @queue.shift
         
     | 
| 
       52 
     | 
    
         
            -
                        end
         
     | 
| 
       53 
     | 
    
         
            -
                      end
         
     | 
| 
       54 
     | 
    
         
            -
                    end
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                  end
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                end
         
     | 
| 
       59 
     | 
    
         
            -
              end
         
     | 
| 
       60 
     | 
    
         
            -
            end
         
     | 
| 
      
 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 'singleton'
         
     | 
| 
      
 11 
     | 
    
         
            +
                  require 'thread'
         
     | 
| 
      
 12 
     | 
    
         
            +
                  require 'sappho-basics/auto_flush_log'
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  class CommandQueue
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    include Singleton, Sappho::LogUtilities
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    def initialize
         
     | 
| 
      
 19 
     | 
    
         
            +
                      @queue = []
         
     | 
| 
      
 20 
     | 
    
         
            +
                      @mutex = Mutex.new
         
     | 
| 
      
 21 
     | 
    
         
            +
                      @log = Sappho::ApplicationAutoFlushLog.instance
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                    def push clientIP, command
         
     | 
| 
      
 25 
     | 
    
         
            +
                      @log.info "client #{clientIP} requests command: #{hexString command}"
         
     | 
| 
      
 26 
     | 
    
         
            +
                      @mutex.synchronize do
         
     | 
| 
      
 27 
     | 
    
         
            +
                        @queue << {
         
     | 
| 
      
 28 
     | 
    
         
            +
                            :clientIP => clientIP,
         
     | 
| 
      
 29 
     | 
    
         
            +
                            :command => command.dup
         
     | 
| 
      
 30 
     | 
    
         
            +
                        }
         
     | 
| 
      
 31 
     | 
    
         
            +
                      end
         
     | 
| 
      
 32 
     | 
    
         
            +
                    end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                    def get
         
     | 
| 
      
 35 
     | 
    
         
            +
                      command = nil
         
     | 
| 
      
 36 
     | 
    
         
            +
                      @mutex.synchronize do
         
     | 
| 
      
 37 
     | 
    
         
            +
                        if @queue.size > 0
         
     | 
| 
      
 38 
     | 
    
         
            +
                          queue = @queue[0]
         
     | 
| 
      
 39 
     | 
    
         
            +
                          command = queue[:command].dup
         
     | 
| 
      
 40 
     | 
    
         
            +
                          @log.info "client #{queue[:clientIP]} command executing: #{hexString command}"
         
     | 
| 
      
 41 
     | 
    
         
            +
                        end
         
     | 
| 
      
 42 
     | 
    
         
            +
                      end
         
     | 
| 
      
 43 
     | 
    
         
            +
                      command
         
     | 
| 
      
 44 
     | 
    
         
            +
                    end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                    def completed
         
     | 
| 
      
 47 
     | 
    
         
            +
                      @mutex.synchronize do
         
     | 
| 
      
 48 
     | 
    
         
            +
                        if @queue.size > 0
         
     | 
| 
      
 49 
     | 
    
         
            +
                          queue = @queue[0]
         
     | 
| 
      
 50 
     | 
    
         
            +
                          @log.info "client #{queue[:clientIP]} command completed: #{hexString queue[:command]}"
         
     | 
| 
      
 51 
     | 
    
         
            +
                          @queue.shift
         
     | 
| 
      
 52 
     | 
    
         
            +
                        end
         
     | 
| 
      
 53 
     | 
    
         
            +
                      end
         
     | 
| 
      
 54 
     | 
    
         
            +
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,86 +1,96 @@ 
     | 
|
| 
       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_crc'
         
     | 
| 
       11 
     | 
    
         
            -
                  require 'sappho-heatmiser-proxy/heatmiser_status'
         
     | 
| 
       12 
     | 
    
         
            -
                  require 'sappho-basics/auto_flush_log'
         
     | 
| 
       13 
     | 
    
         
            -
                  require 'sappho-heatmiser-proxy/command_queue'
         
     | 
| 
       14 
     | 
    
         
            -
                  require 'sappho-heatmiser-proxy/system_configuration'
         
     | 
| 
       15 
     | 
    
         
            -
                  require 'sappho- 
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                       
     | 
| 
       24 
     | 
    
         
            -
                       
     | 
| 
       25 
     | 
    
         
            -
                       
     | 
| 
       26 
     | 
    
         
            -
                       
     | 
| 
       27 
     | 
    
         
            -
                       
     | 
| 
       28 
     | 
    
         
            -
                       
     | 
| 
       29 
     | 
    
         
            -
                       
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                           
     | 
| 
       35 
     | 
    
         
            -
                             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                               
     | 
| 
       39 
     | 
    
         
            -
                               
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                                                         timeNow. 
     | 
| 
       43 
     | 
    
         
            -
                                                          
     | 
| 
       44 
     | 
    
         
            -
                                                         timeNow. 
     | 
| 
       45 
     | 
    
         
            -
                                                          
     | 
| 
       46 
     | 
    
         
            -
                                                         timeNow. 
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                           
     | 
| 
       52 
     | 
    
         
            -
                           
     | 
| 
       53 
     | 
    
         
            -
                          socket. 
     | 
| 
       54 
     | 
    
         
            -
                           
     | 
| 
       55 
     | 
    
         
            -
                           
     | 
| 
       56 
     | 
    
         
            -
                           
     | 
| 
       57 
     | 
    
         
            -
                           
     | 
| 
       58 
     | 
    
         
            -
                           
     | 
| 
       59 
     | 
    
         
            -
                           
     | 
| 
       60 
     | 
    
         
            -
                           
     | 
| 
       61 
     | 
    
         
            -
                           
     | 
| 
       62 
     | 
    
         
            -
                           
     | 
| 
       63 
     | 
    
         
            -
                           
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                            reply  
     | 
| 
       67 
     | 
    
         
            -
                             
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                           
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
      
 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_crc'
         
     | 
| 
      
 11 
     | 
    
         
            +
                  require 'sappho-heatmiser-proxy/heatmiser_status'
         
     | 
| 
      
 12 
     | 
    
         
            +
                  require 'sappho-basics/auto_flush_log'
         
     | 
| 
      
 13 
     | 
    
         
            +
                  require 'sappho-heatmiser-proxy/command_queue'
         
     | 
| 
      
 14 
     | 
    
         
            +
                  require 'sappho-heatmiser-proxy/system_configuration'
         
     | 
| 
      
 15 
     | 
    
         
            +
                  require 'sappho-heatmiser-proxy/model/heatmiser_log'
         
     | 
| 
      
 16 
     | 
    
         
            +
                  require 'sappho-socket/safe_socket'
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  class Heatmiser
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    include Sappho::LogUtilities
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    def monitor
         
     | 
| 
      
 23 
     | 
    
         
            +
                      status = HeatmiserStatus.instance
         
     | 
| 
      
 24 
     | 
    
         
            +
                      queue = CommandQueue.instance
         
     | 
| 
      
 25 
     | 
    
         
            +
                      log = Sappho::ApplicationAutoFlushLog.instance
         
     | 
| 
      
 26 
     | 
    
         
            +
                      config = SystemConfiguration.instance
         
     | 
| 
      
 27 
     | 
    
         
            +
                      desc = "heatmiser #{config.heatmiserId} at #{config.heatmiserHostname}:#{config.heatmiserPort}"
         
     | 
| 
      
 28 
     | 
    
         
            +
                      log.info "connecting to #{desc}"
         
     | 
| 
      
 29 
     | 
    
         
            +
                      queryCommand = HeatmiserCRC.new([0x93, 0x0B, 0x00, config.pinLo, config.pinHi, 0x00, 0x00, 0xFF, 0xFF]).appendCRC
         
     | 
| 
      
 30 
     | 
    
         
            +
                      socket = Sappho::Socket::SafeSocket.new 5
         
     | 
| 
      
 31 
     | 
    
         
            +
                      loop do
         
     | 
| 
      
 32 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 33 
     | 
    
         
            +
                          command = queryCommand
         
     | 
| 
      
 34 
     | 
    
         
            +
                          if queuedCommand = queue.get
         
     | 
| 
      
 35 
     | 
    
         
            +
                            command = queuedCommand
         
     | 
| 
      
 36 
     | 
    
         
            +
                          else
         
     | 
| 
      
 37 
     | 
    
         
            +
                            if status.get{status.valid ? status.deviceTimeOffset : 0.0}.abs > 5 and config.heatmiserHardware
         
     | 
| 
      
 38 
     | 
    
         
            +
                              timeNow = Time.now
         
     | 
| 
      
 39 
     | 
    
         
            +
                              dayOfWeek = timeNow.wday
         
     | 
| 
      
 40 
     | 
    
         
            +
                              dayOfWeek = 7 if dayOfWeek == 0
         
     | 
| 
      
 41 
     | 
    
         
            +
                              command = HeatmiserCRC.new([0xA3, 0x12, 0x00, config.pinLo, config.pinHi, 0x01, 0x2B, 0x00, 0x07,
         
     | 
| 
      
 42 
     | 
    
         
            +
                                                         timeNow.year - 2000,
         
     | 
| 
      
 43 
     | 
    
         
            +
                                                         timeNow.month,
         
     | 
| 
      
 44 
     | 
    
         
            +
                                                         timeNow.day,
         
     | 
| 
      
 45 
     | 
    
         
            +
                                                         dayOfWeek,
         
     | 
| 
      
 46 
     | 
    
         
            +
                                                         timeNow.hour,
         
     | 
| 
      
 47 
     | 
    
         
            +
                                                         timeNow.min,
         
     | 
| 
      
 48 
     | 
    
         
            +
                                                         timeNow.sec]).appendCRC
         
     | 
| 
      
 49 
     | 
    
         
            +
                              log.info "clock correction: #{hexString command}"
         
     | 
| 
      
 50 
     | 
    
         
            +
                            end
         
     | 
| 
      
 51 
     | 
    
         
            +
                          end
         
     | 
| 
      
 52 
     | 
    
         
            +
                          log.debug "sending command: #{hexString command}" if log.debug?
         
     | 
| 
      
 53 
     | 
    
         
            +
                          socket.open config.heatmiserHostname, config.heatmiserPort
         
     | 
| 
      
 54 
     | 
    
         
            +
                          socket.settle 0.1
         
     | 
| 
      
 55 
     | 
    
         
            +
                          startTime = Time.now
         
     | 
| 
      
 56 
     | 
    
         
            +
                          socket.write command.pack('c*')
         
     | 
| 
      
 57 
     | 
    
         
            +
                          reply = socket.read(81).unpack('c*')
         
     | 
| 
      
 58 
     | 
    
         
            +
                          timestamp = Time.now
         
     | 
| 
      
 59 
     | 
    
         
            +
                          log.debug "reply: #{hexString reply}" if log.debug?
         
     | 
| 
      
 60 
     | 
    
         
            +
                          crcHi = reply.pop & 0xFF
         
     | 
| 
      
 61 
     | 
    
         
            +
                          crcLo = reply.pop & 0xFF
         
     | 
| 
      
 62 
     | 
    
         
            +
                          crc = HeatmiserCRC.new reply
         
     | 
| 
      
 63 
     | 
    
         
            +
                          if (reply[0] & 0xFF) == 0x94 and reply[1] == 0x51 and reply[2] == 0 and
         
     | 
| 
      
 64 
     | 
    
         
            +
                              crc.crcHi == crcHi and crc.crcLo == crcLo
         
     | 
| 
      
 65 
     | 
    
         
            +
                            reply << crcLo << crcHi
         
     | 
| 
      
 66 
     | 
    
         
            +
                            status.set reply, timestamp, (timestamp - startTime)
         
     | 
| 
      
 67 
     | 
    
         
            +
                            queue.completed if queuedCommand
         
     | 
| 
      
 68 
     | 
    
         
            +
                            Sappho::Heatmiser::Model::HeatmiserLog.new(status.get{{
         
     | 
| 
      
 69 
     | 
    
         
            +
                              :deviceId => config.heatmiserId,
         
     | 
| 
      
 70 
     | 
    
         
            +
                              :timestamp => timestamp,
         
     | 
| 
      
 71 
     | 
    
         
            +
                              :sensedTemperature => status.sensedTemperature,
         
     | 
| 
      
 72 
     | 
    
         
            +
                              :requestedTemperature => status.requestedTemperature,
         
     | 
| 
      
 73 
     | 
    
         
            +
                              :heatOn => status.heatOn,
         
     | 
| 
      
 74 
     | 
    
         
            +
                              :frostProtectOn => status.frostProtectOn,
         
     | 
| 
      
 75 
     | 
    
         
            +
                              :deviceTimeOffset => status.deviceTimeOffset}}).save if config.mongoLogging
         
     | 
| 
      
 76 
     | 
    
         
            +
                          else
         
     | 
| 
      
 77 
     | 
    
         
            +
                            log.info "#{desc} responded with invalid bytes - ignoring it this time"
         
     | 
| 
      
 78 
     | 
    
         
            +
                          end
         
     | 
| 
      
 79 
     | 
    
         
            +
                        rescue Timeout::Error
         
     | 
| 
      
 80 
     | 
    
         
            +
                          status.invalidate
         
     | 
| 
      
 81 
     | 
    
         
            +
                          log.info "#{desc} is not responding - the connection might be down"
         
     | 
| 
      
 82 
     | 
    
         
            +
                        rescue => error
         
     | 
| 
      
 83 
     | 
    
         
            +
                          status.invalidate
         
     | 
| 
      
 84 
     | 
    
         
            +
                          log.error error
         
     | 
| 
      
 85 
     | 
    
         
            +
                        end
         
     | 
| 
      
 86 
     | 
    
         
            +
                        socket.settle 0.1
         
     | 
| 
      
 87 
     | 
    
         
            +
                        socket.close
         
     | 
| 
      
 88 
     | 
    
         
            +
                        socket.settle 2
         
     | 
| 
      
 89 
     | 
    
         
            +
                      end
         
     | 
| 
      
 90 
     | 
    
         
            +
                    end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
      
 95 
     | 
    
         
            +
              end
         
     | 
| 
      
 96 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,78 +1,78 @@ 
     | 
|
| 
       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-basics/auto_flush_log'
         
     | 
| 
       11 
     | 
    
         
            -
                  require 'sappho-heatmiser-proxy/heatmiser_status'
         
     | 
| 
       12 
     | 
    
         
            -
                  require 'sappho-heatmiser-proxy/command_queue'
         
     | 
| 
       13 
     | 
    
         
            -
                  require 'sappho-heatmiser-proxy/system_configuration'
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                  class HeatmiserClient
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                    include Sappho::LogUtilities
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                    def initialize client, ip
         
     | 
| 
       20 
     | 
    
         
            -
                      @ip = ip
         
     | 
| 
       21 
     | 
    
         
            -
                      @client = client
         
     | 
| 
       22 
     | 
    
         
            -
                      @status = HeatmiserStatus.instance
         
     | 
| 
       23 
     | 
    
         
            -
                      @log = Sappho::ApplicationAutoFlushLog.instance
         
     | 
| 
       24 
     | 
    
         
            -
                    end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                    def communicate
         
     | 
| 
       27 
     | 
    
         
            -
                      config = SystemConfiguration.instance
         
     | 
| 
       28 
     | 
    
         
            -
                      active = true
         
     | 
| 
       29 
     | 
    
         
            -
                      while active do
         
     | 
| 
       30 
     | 
    
         
            -
                        begin
         
     | 
| 
       31 
     | 
    
         
            -
                          command = read 5
         
     | 
| 
       32 
     | 
    
         
            -
                          if command == 'check'
         
     | 
| 
       33 
     | 
    
         
            -
                            reply = @status.get {
         
     | 
| 
       34 
     | 
    
         
            -
                              @status.timeSinceLastValid > 60 ?
         
     | 
| 
       35 
     | 
    
         
            -
                                  'error: no response from heatmiser unit in last minute' :
         
     | 
| 
       36 
     | 
    
         
            -
                                  @status.valid ? 'ok' : 'error: last response from heatmiser unit was invalid'
         
     | 
| 
       37 
     | 
    
         
            -
                            }
         
     | 
| 
       38 
     | 
    
         
            -
                            @log.info "client #{@ip} checking status - reply: #{reply}"
         
     | 
| 
       39 
     | 
    
         
            -
                            @client.write "#{reply}\r\n"
         
     | 
| 
       40 
     | 
    
         
            -
                            active = false
         
     | 
| 
       41 
     | 
    
         
            -
                          else
         
     | 
| 
       42 
     | 
    
         
            -
                            command = command.unpack('c*')
         
     | 
| 
       43 
     | 
    
         
            -
                            @log.debug "header: #{hexString command}" if @log.debug?
         
     | 
| 
       44 
     | 
    
         
            -
                            raise ClientDataError, "invalid pin" unless (command[3] & 0xFF) == config.pinLo and (command[4] & 0xFF) == config.pinHi
         
     | 
| 
       45 
     | 
    
         
            -
                            packetSize = (command[1] & 0xFF) | ((command[2] << 8) & 0xFF00)
         
     | 
| 
       46 
     | 
    
         
            -
                            raise ClientDataError, "invalid packet size" if packetSize < 7 or packetSize > 128
         
     | 
| 
       47 
     | 
    
         
            -
                            command += read(packetSize - 5).unpack('c*')
         
     | 
| 
       48 
     | 
    
         
            -
                            CommandQueue.instance.push @ip, command unless (command[0] & 0xFF) == 0x93
         
     | 
| 
       49 
     | 
    
         
            -
                            @status.get { @client.write @status.raw.pack('c*') if @status.valid }
         
     | 
| 
       50 
     | 
    
         
            -
                            @log.info "command received from client #{@ip} so it is alive"
         
     | 
| 
       51 
     | 
    
         
            -
                          end
         
     | 
| 
       52 
     | 
    
         
            -
                        rescue Timeout::Error
         
     | 
| 
       53 
     | 
    
         
            -
                          @log.info "timeout on client #{@ip} so presuming it dormant"
         
     | 
| 
       54 
     | 
    
         
            -
                          active = false
         
     | 
| 
       55 
     | 
    
         
            -
                        rescue ClientDataError => error
         
     | 
| 
       56 
     | 
    
         
            -
                          @log.info "data error from client #{@ip}: #{error.message}"
         
     | 
| 
       57 
     | 
    
         
            -
                          active = false
         
     | 
| 
       58 
     | 
    
         
            -
                        rescue => error
         
     | 
| 
       59 
     | 
    
         
            -
                          @log.error error
         
     | 
| 
       60 
     | 
    
         
            -
                          active = false
         
     | 
| 
       61 
     | 
    
         
            -
                        end
         
     | 
| 
       62 
     | 
    
         
            -
                      end
         
     | 
| 
       63 
     | 
    
         
            -
                    end
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
                    def read size
         
     | 
| 
       66 
     | 
    
         
            -
                      data = @client.read size
         
     | 
| 
       67 
     | 
    
         
            -
                      raise ClientDataError, "nothing received so presuming it has disconnected" unless data and data.size == size
         
     | 
| 
       68 
     | 
    
         
            -
                      data
         
     | 
| 
       69 
     | 
    
         
            -
                    end
         
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
                    class ClientDataError < Interrupt
         
     | 
| 
       72 
     | 
    
         
            -
                    end
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
                  end
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                end
         
     | 
| 
       77 
     | 
    
         
            -
              end
         
     | 
| 
       78 
     | 
    
         
            -
            end
         
     | 
| 
      
 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-basics/auto_flush_log'
         
     | 
| 
      
 11 
     | 
    
         
            +
                  require 'sappho-heatmiser-proxy/heatmiser_status'
         
     | 
| 
      
 12 
     | 
    
         
            +
                  require 'sappho-heatmiser-proxy/command_queue'
         
     | 
| 
      
 13 
     | 
    
         
            +
                  require 'sappho-heatmiser-proxy/system_configuration'
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  class HeatmiserClient
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    include Sappho::LogUtilities
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    def initialize client, ip
         
     | 
| 
      
 20 
     | 
    
         
            +
                      @ip = ip
         
     | 
| 
      
 21 
     | 
    
         
            +
                      @client = client
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @status = HeatmiserStatus.instance
         
     | 
| 
      
 23 
     | 
    
         
            +
                      @log = Sappho::ApplicationAutoFlushLog.instance
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    def communicate
         
     | 
| 
      
 27 
     | 
    
         
            +
                      config = SystemConfiguration.instance
         
     | 
| 
      
 28 
     | 
    
         
            +
                      active = true
         
     | 
| 
      
 29 
     | 
    
         
            +
                      while active do
         
     | 
| 
      
 30 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 31 
     | 
    
         
            +
                          command = read 5
         
     | 
| 
      
 32 
     | 
    
         
            +
                          if command == 'check'
         
     | 
| 
      
 33 
     | 
    
         
            +
                            reply = @status.get {
         
     | 
| 
      
 34 
     | 
    
         
            +
                              @status.timeSinceLastValid > 60 ?
         
     | 
| 
      
 35 
     | 
    
         
            +
                                  'error: no response from heatmiser unit in last minute' :
         
     | 
| 
      
 36 
     | 
    
         
            +
                                  @status.valid ? 'ok' : 'error: last response from heatmiser unit was invalid'
         
     | 
| 
      
 37 
     | 
    
         
            +
                            }
         
     | 
| 
      
 38 
     | 
    
         
            +
                            @log.info "client #{@ip} checking status - reply: #{reply}"
         
     | 
| 
      
 39 
     | 
    
         
            +
                            @client.write "#{reply}\r\n"
         
     | 
| 
      
 40 
     | 
    
         
            +
                            active = false
         
     | 
| 
      
 41 
     | 
    
         
            +
                          else
         
     | 
| 
      
 42 
     | 
    
         
            +
                            command = command.unpack('c*')
         
     | 
| 
      
 43 
     | 
    
         
            +
                            @log.debug "header: #{hexString command}" if @log.debug?
         
     | 
| 
      
 44 
     | 
    
         
            +
                            raise ClientDataError, "invalid pin" unless (command[3] & 0xFF) == config.pinLo and (command[4] & 0xFF) == config.pinHi
         
     | 
| 
      
 45 
     | 
    
         
            +
                            packetSize = (command[1] & 0xFF) | ((command[2] << 8) & 0xFF00)
         
     | 
| 
      
 46 
     | 
    
         
            +
                            raise ClientDataError, "invalid packet size" if packetSize < 7 or packetSize > 128
         
     | 
| 
      
 47 
     | 
    
         
            +
                            command += read(packetSize - 5).unpack('c*')
         
     | 
| 
      
 48 
     | 
    
         
            +
                            CommandQueue.instance.push @ip, command unless (command[0] & 0xFF) == 0x93
         
     | 
| 
      
 49 
     | 
    
         
            +
                            @status.get { @client.write @status.raw.pack('c*') if @status.valid }
         
     | 
| 
      
 50 
     | 
    
         
            +
                            @log.info "command received from client #{@ip} so it is alive"
         
     | 
| 
      
 51 
     | 
    
         
            +
                          end
         
     | 
| 
      
 52 
     | 
    
         
            +
                        rescue Timeout::Error
         
     | 
| 
      
 53 
     | 
    
         
            +
                          @log.info "timeout on client #{@ip} so presuming it dormant"
         
     | 
| 
      
 54 
     | 
    
         
            +
                          active = false
         
     | 
| 
      
 55 
     | 
    
         
            +
                        rescue ClientDataError => error
         
     | 
| 
      
 56 
     | 
    
         
            +
                          @log.info "data error from client #{@ip}: #{error.message}"
         
     | 
| 
      
 57 
     | 
    
         
            +
                          active = false
         
     | 
| 
      
 58 
     | 
    
         
            +
                        rescue => error
         
     | 
| 
      
 59 
     | 
    
         
            +
                          @log.error error
         
     | 
| 
      
 60 
     | 
    
         
            +
                          active = false
         
     | 
| 
      
 61 
     | 
    
         
            +
                        end
         
     | 
| 
      
 62 
     | 
    
         
            +
                      end
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    def read size
         
     | 
| 
      
 66 
     | 
    
         
            +
                      data = @client.read size
         
     | 
| 
      
 67 
     | 
    
         
            +
                      raise ClientDataError, "nothing received so presuming it has disconnected" unless data and data.size == size
         
     | 
| 
      
 68 
     | 
    
         
            +
                      data
         
     | 
| 
      
 69 
     | 
    
         
            +
                    end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    class ClientDataError < Interrupt
         
     | 
| 
      
 72 
     | 
    
         
            +
                    end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,48 +1,48 @@ 
     | 
|
| 
       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 
     | 
    
         
            -
                  class HeatmiserCRC
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                    LookupHi = [
         
     | 
| 
       13 
     | 
    
         
            -
                        0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
         
     | 
| 
       14 
     | 
    
         
            -
                        0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1
         
     | 
| 
       15 
     | 
    
         
            -
                    ]
         
     | 
| 
       16 
     | 
    
         
            -
                    LookupLo = [
         
     | 
| 
       17 
     | 
    
         
            -
                        0x00, 0x21, 0x42, 0x63, 0x84, 0xA5, 0xC6, 0xE7,
         
     | 
| 
       18 
     | 
    
         
            -
                        0x08, 0x29, 0x4A, 0x6B, 0x8C, 0xAD, 0xCE, 0xEF
         
     | 
| 
       19 
     | 
    
         
            -
                    ]
         
     | 
| 
       20 
     | 
    
         
            -
                    attr_reader :crcHi, :crcLo
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                    def initialize bytes
         
     | 
| 
       23 
     | 
    
         
            -
                      @bytes = bytes
         
     | 
| 
       24 
     | 
    
         
            -
                      @crcHi = 0xFF
         
     | 
| 
       25 
     | 
    
         
            -
                      @crcLo = 0xFF
         
     | 
| 
       26 
     | 
    
         
            -
                      bytes.each do |byte|
         
     | 
| 
       27 
     | 
    
         
            -
                        addNibble byte >> 4
         
     | 
| 
       28 
     | 
    
         
            -
                        addNibble byte & 0x0F
         
     | 
| 
       29 
     | 
    
         
            -
                      end
         
     | 
| 
       30 
     | 
    
         
            -
                    end
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                    def appendCRC
         
     | 
| 
       33 
     | 
    
         
            -
                      @bytes << @crcLo << @crcHi
         
     | 
| 
       34 
     | 
    
         
            -
                    end
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                    private
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                    def addNibble nibble
         
     | 
| 
       39 
     | 
    
         
            -
                      t = ((@crcHi >> 4) ^ nibble) & 0x0F
         
     | 
| 
       40 
     | 
    
         
            -
                      @crcHi = (((@crcHi << 4) & 0xFF) | (@crcLo >> 4)) ^ LookupHi[t]
         
     | 
| 
       41 
     | 
    
         
            -
                      @crcLo = ((@crcLo << 4) & 0xFF) ^ LookupLo[t]
         
     | 
| 
       42 
     | 
    
         
            -
                    end
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                  end
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                end
         
     | 
| 
       47 
     | 
    
         
            -
              end
         
     | 
| 
       48 
     | 
    
         
            -
            end
         
     | 
| 
      
 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 
     | 
    
         
            +
                  class HeatmiserCRC
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    LookupHi = [
         
     | 
| 
      
 13 
     | 
    
         
            +
                        0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
         
     | 
| 
      
 14 
     | 
    
         
            +
                        0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1
         
     | 
| 
      
 15 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 16 
     | 
    
         
            +
                    LookupLo = [
         
     | 
| 
      
 17 
     | 
    
         
            +
                        0x00, 0x21, 0x42, 0x63, 0x84, 0xA5, 0xC6, 0xE7,
         
     | 
| 
      
 18 
     | 
    
         
            +
                        0x08, 0x29, 0x4A, 0x6B, 0x8C, 0xAD, 0xCE, 0xEF
         
     | 
| 
      
 19 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 20 
     | 
    
         
            +
                    attr_reader :crcHi, :crcLo
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    def initialize bytes
         
     | 
| 
      
 23 
     | 
    
         
            +
                      @bytes = bytes
         
     | 
| 
      
 24 
     | 
    
         
            +
                      @crcHi = 0xFF
         
     | 
| 
      
 25 
     | 
    
         
            +
                      @crcLo = 0xFF
         
     | 
| 
      
 26 
     | 
    
         
            +
                      bytes.each do |byte|
         
     | 
| 
      
 27 
     | 
    
         
            +
                        addNibble byte >> 4
         
     | 
| 
      
 28 
     | 
    
         
            +
                        addNibble byte & 0x0F
         
     | 
| 
      
 29 
     | 
    
         
            +
                      end
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                    def appendCRC
         
     | 
| 
      
 33 
     | 
    
         
            +
                      @bytes << @crcLo << @crcHi
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                    private
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                    def addNibble nibble
         
     | 
| 
      
 39 
     | 
    
         
            +
                      t = ((@crcHi >> 4) ^ nibble) & 0x0F
         
     | 
| 
      
 40 
     | 
    
         
            +
                      @crcHi = (((@crcHi << 4) & 0xFF) | (@crcLo >> 4)) ^ LookupHi[t]
         
     | 
| 
      
 41 
     | 
    
         
            +
                      @crcLo = ((@crcLo << 4) & 0xFF) ^ LookupLo[t]
         
     | 
| 
      
 42 
     | 
    
         
            +
                    end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,136 +1,131 @@ 
     | 
|
| 
       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 'singleton'
         
     | 
| 
       11 
     | 
    
         
            -
                  require 'thread'
         
     | 
| 
       12 
     | 
    
         
            -
                  require 'sappho-basics/auto_flush_log'
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                  class HeatmiserStatus
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                    include Singleton, Sappho::LogUtilities
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                    attr_reader :valid, :timestamp, :sampleTime, :timeSinceLastValid, :sensedTemperature,
         
     | 
| 
       19 
     | 
    
         
            -
                        :requestedTemperature, :heatOn, :keyLockOn, :frostProtectOn, :deviceTimeOffset,
         
     | 
| 
       20 
     | 
    
         
            -
                        :dayOfWeek, :schedule
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                    class TimedTemperature
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                      attr_reader :hour, :minute, :temperature
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                      def initialize raw, bytePosition
         
     | 
| 
       27 
     | 
    
         
            -
                        @hour = raw[bytePosition] & 0xFF
         
     | 
| 
       28 
     | 
    
         
            -
                        @minute = raw[bytePosition + 1] & 0xFF
         
     | 
| 
       29 
     | 
    
         
            -
                        @temperature = raw[bytePosition + 2] & 0xFF
         
     | 
| 
       30 
     | 
    
         
            -
                      end
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                      def valid?
         
     | 
| 
       33 
     | 
    
         
            -
                        @hour < 24 and @minute < 60
         
     | 
| 
       34 
     | 
    
         
            -
                      end
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                      def description
         
     | 
| 
       37 
     | 
    
         
            -
                        "#{@hour}:#{@minute}-#{@temperature}"
         
     | 
| 
       38 
     | 
    
         
            -
                      end
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                    end
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                    class Schedule
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                      attr_reader :schedule
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                      def initialize raw, bytePosition
         
     | 
| 
       47 
     | 
    
         
            -
                        @schedule = []
         
     | 
| 
       48 
     | 
    
         
            -
                        (0 ... 4).map do |position|
         
     | 
| 
       49 
     | 
    
         
            -
                          timedTemperature = TimedTemperature.new(raw, bytePosition + 3 * position)
         
     | 
| 
       50 
     | 
    
         
            -
                          @schedule << timedTemperature if timedTemperature.valid?
         
     | 
| 
       51 
     | 
    
         
            -
                        end
         
     | 
| 
       52 
     | 
    
         
            -
                      end
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                      def description
         
     | 
| 
       55 
     | 
    
         
            -
                        (@schedule.collect {|timedTemperature| timedTemperature.description}).join(' ')
         
     | 
| 
       56 
     | 
    
         
            -
                      end
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                    end
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                    def initialize
         
     | 
| 
       61 
     | 
    
         
            -
                      @mutex = Mutex.new
         
     | 
| 
       62 
     | 
    
         
            -
                      @log = Sappho::ApplicationAutoFlushLog.instance
         
     | 
| 
       63 
     | 
    
         
            -
                      @valid = false
         
     | 
| 
       64 
     | 
    
         
            -
                      @raw = []
         
     | 
| 
       65 
     | 
    
         
            -
                      @timestamp = Time.now
         
     | 
| 
       66 
     | 
    
         
            -
                      @sampleTime = 0.0
         
     | 
| 
       67 
     | 
    
         
            -
                      @timeSinceLastValid = 0.0
         
     | 
| 
       68 
     | 
    
         
            -
                      @sensedTemperature = 0.0
         
     | 
| 
       69 
     | 
    
         
            -
                      @requestedTemperature = 0
         
     | 
| 
       70 
     | 
    
         
            -
                      @holidayReturnTime = Time.now
         
     | 
| 
       71 
     | 
    
         
            -
                      @holdMinutes = 0
         
     | 
| 
       72 
     | 
    
         
            -
                      @heatOn = false
         
     | 
| 
       73 
     | 
    
         
            -
                      @keyLockOn = false
         
     | 
| 
       74 
     | 
    
         
            -
                      @frostProtectOn = false
         
     | 
| 
       75 
     | 
    
         
            -
                      @holidayOn = false
         
     | 
| 
       76 
     | 
    
         
            -
                      @deviceTimeOffset = 0.0
         
     | 
| 
       77 
     | 
    
         
            -
                      @dayOfWeek = 0
         
     | 
| 
       78 
     | 
    
         
            -
                      @schedule = {}
         
     | 
| 
       79 
     | 
    
         
            -
                    end
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
                    def raw
         
     | 
| 
       82 
     | 
    
         
            -
                      @raw.dup
         
     | 
| 
       83 
     | 
    
         
            -
                    end
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                    def get
         
     | 
| 
       86 
     | 
    
         
            -
                      @mutex.synchronize { yield }
         
     | 
| 
       87 
     | 
    
         
            -
                    end
         
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
                    def set raw, timestamp, sampleTime
         
     | 
| 
       90 
     | 
    
         
            -
                      @mutex.synchronize do
         
     | 
| 
       91 
     | 
    
         
            -
                        @valid =  
     | 
| 
       92 
     | 
    
         
            -
                         
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
                  end
         
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
                end
         
     | 
| 
       135 
     | 
    
         
            -
              end
         
     | 
| 
       136 
     | 
    
         
            -
            end
         
     | 
| 
      
 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 'singleton'
         
     | 
| 
      
 11 
     | 
    
         
            +
                  require 'thread'
         
     | 
| 
      
 12 
     | 
    
         
            +
                  require 'sappho-basics/auto_flush_log'
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  class HeatmiserStatus
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    include Singleton, Sappho::LogUtilities
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    attr_reader :valid, :timestamp, :sampleTime, :timeSinceLastValid, :sensedTemperature,
         
     | 
| 
      
 19 
     | 
    
         
            +
                        :requestedTemperature, :heatOn, :keyLockOn, :frostProtectOn, :deviceTimeOffset,
         
     | 
| 
      
 20 
     | 
    
         
            +
                        :dayOfWeek, :schedule
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    class TimedTemperature
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                      attr_reader :hour, :minute, :temperature
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                      def initialize raw, bytePosition
         
     | 
| 
      
 27 
     | 
    
         
            +
                        @hour = raw[bytePosition] & 0xFF
         
     | 
| 
      
 28 
     | 
    
         
            +
                        @minute = raw[bytePosition + 1] & 0xFF
         
     | 
| 
      
 29 
     | 
    
         
            +
                        @temperature = raw[bytePosition + 2] & 0xFF
         
     | 
| 
      
 30 
     | 
    
         
            +
                      end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                      def valid?
         
     | 
| 
      
 33 
     | 
    
         
            +
                        @hour < 24 and @minute < 60
         
     | 
| 
      
 34 
     | 
    
         
            +
                      end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                      def description
         
     | 
| 
      
 37 
     | 
    
         
            +
                        "#{@hour}:#{@minute}-#{@temperature}"
         
     | 
| 
      
 38 
     | 
    
         
            +
                      end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                    end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                    class Schedule
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                      attr_reader :schedule
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                      def initialize raw, bytePosition
         
     | 
| 
      
 47 
     | 
    
         
            +
                        @schedule = []
         
     | 
| 
      
 48 
     | 
    
         
            +
                        (0 ... 4).map do |position|
         
     | 
| 
      
 49 
     | 
    
         
            +
                          timedTemperature = TimedTemperature.new(raw, bytePosition + 3 * position)
         
     | 
| 
      
 50 
     | 
    
         
            +
                          @schedule << timedTemperature if timedTemperature.valid?
         
     | 
| 
      
 51 
     | 
    
         
            +
                        end
         
     | 
| 
      
 52 
     | 
    
         
            +
                      end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                      def description
         
     | 
| 
      
 55 
     | 
    
         
            +
                        (@schedule.collect {|timedTemperature| timedTemperature.description}).join(' ')
         
     | 
| 
      
 56 
     | 
    
         
            +
                      end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                    end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                    def initialize
         
     | 
| 
      
 61 
     | 
    
         
            +
                      @mutex = Mutex.new
         
     | 
| 
      
 62 
     | 
    
         
            +
                      @log = Sappho::ApplicationAutoFlushLog.instance
         
     | 
| 
      
 63 
     | 
    
         
            +
                      @valid = false
         
     | 
| 
      
 64 
     | 
    
         
            +
                      @raw = []
         
     | 
| 
      
 65 
     | 
    
         
            +
                      @timestamp = Time.now
         
     | 
| 
      
 66 
     | 
    
         
            +
                      @sampleTime = 0.0
         
     | 
| 
      
 67 
     | 
    
         
            +
                      @timeSinceLastValid = 0.0
         
     | 
| 
      
 68 
     | 
    
         
            +
                      @sensedTemperature = 0.0
         
     | 
| 
      
 69 
     | 
    
         
            +
                      @requestedTemperature = 0
         
     | 
| 
      
 70 
     | 
    
         
            +
                      @holidayReturnTime = Time.now
         
     | 
| 
      
 71 
     | 
    
         
            +
                      @holdMinutes = 0
         
     | 
| 
      
 72 
     | 
    
         
            +
                      @heatOn = false
         
     | 
| 
      
 73 
     | 
    
         
            +
                      @keyLockOn = false
         
     | 
| 
      
 74 
     | 
    
         
            +
                      @frostProtectOn = false
         
     | 
| 
      
 75 
     | 
    
         
            +
                      @holidayOn = false
         
     | 
| 
      
 76 
     | 
    
         
            +
                      @deviceTimeOffset = 0.0
         
     | 
| 
      
 77 
     | 
    
         
            +
                      @dayOfWeek = 0
         
     | 
| 
      
 78 
     | 
    
         
            +
                      @schedule = {}
         
     | 
| 
      
 79 
     | 
    
         
            +
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                    def raw
         
     | 
| 
      
 82 
     | 
    
         
            +
                      @raw.dup
         
     | 
| 
      
 83 
     | 
    
         
            +
                    end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                    def get
         
     | 
| 
      
 86 
     | 
    
         
            +
                      @mutex.synchronize { yield }
         
     | 
| 
      
 87 
     | 
    
         
            +
                    end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                    def set raw, timestamp, sampleTime
         
     | 
| 
      
 90 
     | 
    
         
            +
                      @mutex.synchronize do
         
     | 
| 
      
 91 
     | 
    
         
            +
                        @valid = false
         
     | 
| 
      
 92 
     | 
    
         
            +
                        @raw = raw.dup
         
     | 
| 
      
 93 
     | 
    
         
            +
                        @sensedTemperature = ((raw[44] & 0xFF) | ((raw[45] << 8) & 0xFF00)) / 10.0
         
     | 
| 
      
 94 
     | 
    
         
            +
                        @holdMinutes = (raw[38] & 0xFF) | ((raw[39] << 8) & 0xFF00)
         
     | 
| 
      
 95 
     | 
    
         
            +
                        @heatOn = raw[47] == 1
         
     | 
| 
      
 96 
     | 
    
         
            +
                        @keyLockOn = raw[29] == 1
         
     | 
| 
      
 97 
     | 
    
         
            +
                        @frostProtectOn = raw[30] == 1
         
     | 
| 
      
 98 
     | 
    
         
            +
                        @holidayOn = raw[37] == 1
         
     | 
| 
      
 99 
     | 
    
         
            +
                        @holidayReturnTime = Time.local(2000 + (raw[32] & 0xFF), raw[33], raw[34], raw[35], raw[36], 0)
         
     | 
| 
      
 100 
     | 
    
         
            +
                        @requestedTemperature = @frostProtectOn ? raw[24] & 0xFF : raw[25] & 0xFF
         
     | 
| 
      
 101 
     | 
    
         
            +
                        @deviceTimeOffset = Time.local(2000 + (raw[48] & 0xFF), raw[49], raw[50],
         
     | 
| 
      
 102 
     | 
    
         
            +
                                                       raw[52], raw[53], raw[54]) - timestamp
         
     | 
| 
      
 103 
     | 
    
         
            +
                        dayOfWeek = raw[51]
         
     | 
| 
      
 104 
     | 
    
         
            +
                        @dayOfWeek = dayOfWeek == 7 ? 0 : dayOfWeek
         
     | 
| 
      
 105 
     | 
    
         
            +
                        @schedule = {
         
     | 
| 
      
 106 
     | 
    
         
            +
                            :weekday => Schedule.new(@raw, 55),
         
     | 
| 
      
 107 
     | 
    
         
            +
                            :weekend => Schedule.new(@raw, 67)
         
     | 
| 
      
 108 
     | 
    
         
            +
                        }
         
     | 
| 
      
 109 
     | 
    
         
            +
                        @timeSinceLastValid = timestamp - @timestamp
         
     | 
| 
      
 110 
     | 
    
         
            +
                        @timestamp = timestamp
         
     | 
| 
      
 111 
     | 
    
         
            +
                        @sampleTime = sampleTime
         
     | 
| 
      
 112 
     | 
    
         
            +
                        @valid = true
         
     | 
| 
      
 113 
     | 
    
         
            +
                        if @log.debug?
         
     | 
| 
      
 114 
     | 
    
         
            +
                          @log.debug "#{hexString raw}"
         
     | 
| 
      
 115 
     | 
    
         
            +
                          @log.debug "#{@requestedTemperature} #{@holdMinutes / 60}:#{@holdMinutes % 60} #{@sensedTemperature} #{@heatOn} #{@keyLockOn} #{@frostProtectOn} #{@timeSinceLastValid} #{@dayOfWeek} #{@deviceTimeOffset} #{sampleTime} #{@holidayOn} #{@holidayReturnTime}"
         
     | 
| 
      
 116 
     | 
    
         
            +
                          @log.debug "weekday: #{@schedule[:weekday].description} weekend: #{@schedule[:weekend].description}"
         
     | 
| 
      
 117 
     | 
    
         
            +
                        else
         
     | 
| 
      
 118 
     | 
    
         
            +
                          @log.info "received status: heating is #{@heatOn ? "on" : "off"} because required temperature is #{@requestedTemperature} and actual is #{@sensedTemperature}"
         
     | 
| 
      
 119 
     | 
    
         
            +
                        end
         
     | 
| 
      
 120 
     | 
    
         
            +
                      end
         
     | 
| 
      
 121 
     | 
    
         
            +
                    end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                    def invalidate
         
     | 
| 
      
 124 
     | 
    
         
            +
                      @mutex.synchronize { @valid = false }
         
     | 
| 
      
 125 
     | 
    
         
            +
                    end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                  end
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                end
         
     | 
| 
      
 130 
     | 
    
         
            +
              end
         
     | 
| 
      
 131 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 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 Model
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  require 'mongo_mapper'
         
     | 
| 
      
 11 
     | 
    
         
            +
                  require 'mongo_mapper/document'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  class HeatmiserLog
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    include MongoMapper::Document
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    key :deviceId, String
         
     | 
| 
      
 18 
     | 
    
         
            +
                    key :timestamp, Time
         
     | 
| 
      
 19 
     | 
    
         
            +
                    key :sensedTemperature, Float
         
     | 
| 
      
 20 
     | 
    
         
            +
                    key :requestedTemperature, Integer
         
     | 
| 
      
 21 
     | 
    
         
            +
                    key :heatOn, Boolean
         
     | 
| 
      
 22 
     | 
    
         
            +
                    key :frostProtectOn, Boolean
         
     | 
| 
      
 23 
     | 
    
         
            +
                    key :deviceTimeOffset, Float
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,33 +1,48 @@ 
     | 
|
| 
       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 'singleton'
         
     | 
| 
       11 
     | 
    
         
            -
                  require 'yaml'
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                       
     | 
| 
       25 
     | 
    
         
            -
                       
     | 
| 
       26 
     | 
    
         
            -
                       
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
      
 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 'singleton'
         
     | 
| 
      
 11 
     | 
    
         
            +
                  require 'yaml'
         
     | 
| 
      
 12 
     | 
    
         
            +
                  require 'sappho-basics/auto_flush_log'
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  class SystemConfiguration
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    include Singleton
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    attr_reader :heatmiserId, :heatmiserHostname, :heatmiserPort, :heatmiserHardware,
         
     | 
| 
      
 19 
     | 
    
         
            +
                                :pinLo, :pinHi, :maxClients,
         
     | 
| 
      
 20 
     | 
    
         
            +
                                :mongoLogging, :mongodbHostname, :mongodbPort, :mongodbDatabase,
         
     | 
| 
      
 21 
     | 
    
         
            +
                                :detailedLogging
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                    def initialize
         
     | 
| 
      
 24 
     | 
    
         
            +
                      log = Sappho::ApplicationAutoFlushLog.instance
         
     | 
| 
      
 25 
     | 
    
         
            +
                      filename = File.expand_path(ARGV[0] || 'heatmiser-proxy.yml')
         
     | 
| 
      
 26 
     | 
    
         
            +
                      log.info "loading application configuration from #{filename}"
         
     | 
| 
      
 27 
     | 
    
         
            +
                      data = YAML.load_file(filename)
         
     | 
| 
      
 28 
     | 
    
         
            +
                      @heatmiserId = data['heatmiser.id']
         
     | 
| 
      
 29 
     | 
    
         
            +
                      @heatmiserHostname = data['heatmiser.address']
         
     | 
| 
      
 30 
     | 
    
         
            +
                      @heatmiserPort = data.has_key?('heatmiser.port') ? Integer(data['heatmiser.port']) : 8068
         
     | 
| 
      
 31 
     | 
    
         
            +
                      @heatmiserHardware = data.has_key? 'heatmiser.hardware'
         
     | 
| 
      
 32 
     | 
    
         
            +
                      pin = Integer data['heatmiser.pin']
         
     | 
| 
      
 33 
     | 
    
         
            +
                      @pinLo = pin & 0xFF
         
     | 
| 
      
 34 
     | 
    
         
            +
                      @pinHi = (pin >> 8) & 0xFF
         
     | 
| 
      
 35 
     | 
    
         
            +
                      @maxClients = data.has_key?('clients.max') ? Integer(data['clients.max']) : 10
         
     | 
| 
      
 36 
     | 
    
         
            +
                      @mongoLogging = data.has_key?('mongodb.address') and data.has_key?('mongodb.database')
         
     | 
| 
      
 37 
     | 
    
         
            +
                      @mongodbHostname = data['mongodb.address']
         
     | 
| 
      
 38 
     | 
    
         
            +
                      @mongodbPort = data.has_key?('mongodb.port') ? Integer(data['mongodb.port']) : 27017
         
     | 
| 
      
 39 
     | 
    
         
            +
                      @mongodbDatabase = data['mongodb.database']
         
     | 
| 
      
 40 
     | 
    
         
            +
                      @detailedLogging = data.has_key? 'logging.detailed'
         
     | 
| 
      
 41 
     | 
    
         
            +
                      raise "missing settings in #{filename}" unless @heatmiserId and @heatmiserHostname
         
     | 
| 
      
 42 
     | 
    
         
            +
                    end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,18 +1,18 @@ 
     | 
|
| 
       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 
     | 
    
         
            -
                  NAME = 'sappho-heatmiser-proxy'
         
     | 
| 
       10 
     | 
    
         
            -
                  VERSION = '0.1. 
     | 
| 
       11 
     | 
    
         
            -
                  AUTHORS = ['Andrew Heald']
         
     | 
| 
       12 
     | 
    
         
            -
                  EMAILS = ['andrew@heald.co.uk']
         
     | 
| 
       13 
     | 
    
         
            -
                  HOMEPAGE = 'https://github.com/sappho/sappho-heatmiser-proxy/wiki'
         
     | 
| 
       14 
     | 
    
         
            -
                  SUMMARY = 'Acts as a proxy for Heatmiser hardware to allow continuous monitoring and control by many controllers'
         
     | 
| 
       15 
     | 
    
         
            -
                  DESCRIPTION = 'See the project home page for more information'
         
     | 
| 
       16 
     | 
    
         
            -
                end
         
     | 
| 
       17 
     | 
    
         
            -
              end
         
     | 
| 
       18 
     | 
    
         
            -
            end
         
     | 
| 
      
 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 
     | 
    
         
            +
                  NAME = 'sappho-heatmiser-proxy'
         
     | 
| 
      
 10 
     | 
    
         
            +
                  VERSION = '0.1.2'
         
     | 
| 
      
 11 
     | 
    
         
            +
                  AUTHORS = ['Andrew Heald']
         
     | 
| 
      
 12 
     | 
    
         
            +
                  EMAILS = ['andrew@heald.co.uk']
         
     | 
| 
      
 13 
     | 
    
         
            +
                  HOMEPAGE = 'https://github.com/sappho/sappho-heatmiser-proxy/wiki'
         
     | 
| 
      
 14 
     | 
    
         
            +
                  SUMMARY = 'Acts as a proxy for Heatmiser hardware to allow continuous monitoring and control by many controllers'
         
     | 
| 
      
 15 
     | 
    
         
            +
                  DESCRIPTION = 'See the project home page for more information'
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
    
        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: 31
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: 
         
     | 
| 
       6 
6 
     | 
    
         
             
              segments: 
         
     | 
| 
       7 
7 
     | 
    
         
             
              - 0
         
     | 
| 
       8 
8 
     | 
    
         
             
              - 1
         
     | 
| 
       9 
     | 
    
         
            -
              -  
     | 
| 
       10 
     | 
    
         
            -
              version: 0.1. 
     | 
| 
      
 9 
     | 
    
         
            +
              - 2
         
     | 
| 
      
 10 
     | 
    
         
            +
              version: 0.1.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-03- 
     | 
| 
      
 18 
     | 
    
         
            +
            date: 2012-03-19 00:00:00 Z
         
     | 
| 
       19 
19 
     | 
    
         
             
            dependencies: 
         
     | 
| 
       20 
20 
     | 
    
         
             
            - !ruby/object:Gem::Dependency 
         
     | 
| 
       21 
21 
     | 
    
         
             
              name: rake
         
     | 
| 
         @@ -50,6 +50,54 @@ dependencies: 
     | 
|
| 
       50 
50 
     | 
    
         
             
                    version: 0.1.1
         
     | 
| 
       51 
51 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       52 
52 
     | 
    
         
             
              version_requirements: *id002
         
     | 
| 
      
 53 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 54 
     | 
    
         
            +
              name: mongo_mapper
         
     | 
| 
      
 55 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 56 
     | 
    
         
            +
              requirement: &id003 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 57 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 58 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 59 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 60 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 61 
     | 
    
         
            +
                    hash: 51
         
     | 
| 
      
 62 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 63 
     | 
    
         
            +
                    - 0
         
     | 
| 
      
 64 
     | 
    
         
            +
                    - 11
         
     | 
| 
      
 65 
     | 
    
         
            +
                    - 0
         
     | 
| 
      
 66 
     | 
    
         
            +
                    version: 0.11.0
         
     | 
| 
      
 67 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 68 
     | 
    
         
            +
              version_requirements: *id003
         
     | 
| 
      
 69 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 70 
     | 
    
         
            +
              name: mongo
         
     | 
| 
      
 71 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 72 
     | 
    
         
            +
              requirement: &id004 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 73 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 74 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 75 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 76 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 77 
     | 
    
         
            +
                    hash: 13
         
     | 
| 
      
 78 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 79 
     | 
    
         
            +
                    - 1
         
     | 
| 
      
 80 
     | 
    
         
            +
                    - 6
         
     | 
| 
      
 81 
     | 
    
         
            +
                    - 1
         
     | 
| 
      
 82 
     | 
    
         
            +
                    version: 1.6.1
         
     | 
| 
      
 83 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 84 
     | 
    
         
            +
              version_requirements: *id004
         
     | 
| 
      
 85 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 86 
     | 
    
         
            +
              name: bson_ext
         
     | 
| 
      
 87 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 88 
     | 
    
         
            +
              requirement: &id005 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 89 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 90 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 91 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 92 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 93 
     | 
    
         
            +
                    hash: 13
         
     | 
| 
      
 94 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 95 
     | 
    
         
            +
                    - 1
         
     | 
| 
      
 96 
     | 
    
         
            +
                    - 6
         
     | 
| 
      
 97 
     | 
    
         
            +
                    - 1
         
     | 
| 
      
 98 
     | 
    
         
            +
                    version: 1.6.1
         
     | 
| 
      
 99 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 100 
     | 
    
         
            +
              version_requirements: *id005
         
     | 
| 
       53 
101 
     | 
    
         
             
            description: See the project home page for more information
         
     | 
| 
       54 
102 
     | 
    
         
             
            email: 
         
     | 
| 
       55 
103 
     | 
    
         
             
            - andrew@heald.co.uk
         
     | 
| 
         @@ -61,14 +109,15 @@ extra_rdoc_files: [] 
     | 
|
| 
       61 
109 
     | 
    
         | 
| 
       62 
110 
     | 
    
         
             
            files: 
         
     | 
| 
       63 
111 
     | 
    
         
             
            - bin/sappho-heatmiser-proxy
         
     | 
| 
       64 
     | 
    
         
            -
            - lib/sappho-heatmiser-proxy.rb
         
     | 
| 
       65 
     | 
    
         
            -
            - lib/sappho-heatmiser-proxy/version.rb
         
     | 
| 
      
 112 
     | 
    
         
            +
            - lib/sappho-heatmiser-proxy/command_queue.rb
         
     | 
| 
       66 
113 
     | 
    
         
             
            - lib/sappho-heatmiser-proxy/heatmiser.rb
         
     | 
| 
      
 114 
     | 
    
         
            +
            - lib/sappho-heatmiser-proxy/heatmiser_client.rb
         
     | 
| 
       67 
115 
     | 
    
         
             
            - lib/sappho-heatmiser-proxy/heatmiser_crc.rb
         
     | 
| 
       68 
     | 
    
         
            -
            - lib/sappho-heatmiser-proxy/system_configuration.rb
         
     | 
| 
       69 
116 
     | 
    
         
             
            - lib/sappho-heatmiser-proxy/heatmiser_status.rb
         
     | 
| 
       70 
     | 
    
         
            -
            - lib/sappho-heatmiser-proxy/ 
     | 
| 
       71 
     | 
    
         
            -
            - lib/sappho-heatmiser-proxy/ 
     | 
| 
      
 117 
     | 
    
         
            +
            - lib/sappho-heatmiser-proxy/model/heatmiser_log.rb
         
     | 
| 
      
 118 
     | 
    
         
            +
            - lib/sappho-heatmiser-proxy/system_configuration.rb
         
     | 
| 
      
 119 
     | 
    
         
            +
            - lib/sappho-heatmiser-proxy/version.rb
         
     | 
| 
      
 120 
     | 
    
         
            +
            - lib/sappho-heatmiser-proxy.rb
         
     | 
| 
       72 
121 
     | 
    
         
             
            homepage: https://github.com/sappho/sappho-heatmiser-proxy/wiki
         
     | 
| 
       73 
122 
     | 
    
         
             
            licenses: []
         
     | 
| 
       74 
123 
     | 
    
         | 
| 
         @@ -98,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       98 
147 
     | 
    
         
             
            requirements: []
         
     | 
| 
       99 
148 
     | 
    
         | 
| 
       100 
149 
     | 
    
         
             
            rubyforge_project: sappho-heatmiser-proxy
         
     | 
| 
       101 
     | 
    
         
            -
            rubygems_version: 1.8. 
     | 
| 
      
 150 
     | 
    
         
            +
            rubygems_version: 1.8.11
         
     | 
| 
       102 
151 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       103 
152 
     | 
    
         
             
            specification_version: 3
         
     | 
| 
       104 
153 
     | 
    
         
             
            summary: Acts as a proxy for Heatmiser hardware to allow continuous monitoring and control by many controllers
         
     |