<commit_before>require 'net/http'

module SAAL
  module DINRelay
    class Outlet < SensorUnderlying
      writeable!

      def initialize(num, outletgroup)
        @num = num
        @og = outletgroup
      end

      def sensor_type
        :onoff
      end

      def read(uncached = false)
        {'ON' => 1.0, 'OFF' => 0.0}[@og.state(@num)]
      end

      def write(value)
        newstate = {1.0 => 'ON', 0.0 => 'OFF'}[value]
        if newstate
          @og.set_state(@num,newstate)
          value 
        end
      end
    end

    class OutletGroup
      DEFAULT_TIMEOUT = 2
      DEFAULT_CACHE_TIMEOUT = 60

      attr_accessor :host, :port, :user, :pass, :timeout, :cache_timeout

      def initialize(opts={})
        @host = opts[:host] || opts['host'] || 'localhost'
        @port = opts[:port] || opts['port'] || 80
        @user = opts[:user] || opts['user'] || 'admin'
        @pass = opts[:pass] || opts['pass'] || '<PASSWORD>'
        @timeout = opts[:timeout] || opts['timeout'] || DEFAULT_TIMEOUT
        @cache_timeout = opts[:cache_timeout] || opts['cache_timeout'] || DEFAULT_CACHE_TIMEOUT
        @cache = nil
        @cachehit = nil
      end

      def state(num)
        if !@cachetime or @cachetime < Time.now - @cache_timeout
          @cache = do_get('/index.htm')
          @cachetime = Time.now
        end
        return @cache ? parse_index_html(@cache.body)[num] : nil
      end

      def set_state(num, state)
        @cachetime = nil
        response = do_get("/outlet?#{num}=#{state}")
        response != nil
      end

      private
      def do_get(path)
        begin
          http = Net::HTTP.new(@host,@port)
          # Timeout faster when the other side doesn't respond
          http.open_timeout = @timeout
          http.read_timeout = @timeout<commit_msg>Avoid crashing dinrelays by slowing down ON/OFF<commit_after>require 'net/http'

module SAAL
  module DINRelay
    class Outlet < SensorUnderlying
      writeable!

      def initialize(num, outletgroup)
        @num = num
        @og = outletgroup
      end

      def sensor_type
        :onoff
      end

      def read(uncached = false)
        {'ON' => 1.0, 'OFF' => 0.0}[@og.state(@num)]
      end

      def write(value)
        newstate = {1.0 => 'ON', 0.0 => 'OFF'}[value]
        if newstate
          @og.set_state(@num,newstate)
          value 
        end
      end
    end

    class OutletGroup
      DEFAULT_TIMEOUT = 2
      DEFAULT_CACHE_TIMEOUT = 60

      attr_accessor :host, :port, :user, :pass, :timeout, :cache_timeout

      def initialize(opts={})
        @host = opts[:host] || opts['host'] || 'localhost'
        @port = opts[:port] || opts['port'] || 80
        @user = opts[:user] || opts['user'] || 'admin'
        @pass = opts[:pass] || opts['pass'] || '<PASSWORD>'
        @timeout = opts[:timeout] || opts['timeout'] || DEFAULT_TIMEOUT
        @cache_timeout = opts[:cache_timeout] || opts['cache_timeout'] || DEFAULT_CACHE_TIMEOUT
        @cache = nil
        @cachehit = nil
      end

      def state(num)
        if !@cachetime or @cachetime < Time.now - @cache_timeout
          @cache = do_get('/index.htm')
          @cachetime = Time.now
        end
        return @cache ? parse_index_html(@cache.body)[num] : nil
      end

      def set_state(num, state)
        @cachetime = nil
        response = do_get("/outlet?#{num}=#{state}")
        #FIXME: Find a better workaround for dinrelay's crashing when you cycle
        #       through outlets too fast
        sleep 1
        response != nil
      end

      private
      def do_get(path)
        begin
          http = Net::HTTP.new(@host,@port)
          # Timeout faster when the other side doesn't respond
          http.open_timeout = @timeout
          http.read_timeout = @timeout
{'fraction_non_alphanumeric': 0.1275980005261773, 'fraction_numerical': 0.007103393843725336, 'mean_word_length': 2.046474358974359, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4641266', 'n_tokens_mistral': 1190, 'n_tokens_neox': 1150, 'n_words': 290}