<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>web/db/migrate/20080627181229_switch_blower_sensor_relationship.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,5 +1,3 @@
-* figure out how to communicate with and kill a spawned rails process
-* find a good chart library
 * finish web interface :)
-* resolve gem dependencies (hpricot, rails 2.1, sqlite3-ruby, will_paginate, scruffy?)
+* resolve gem dependencies (hpricot, rails 2.1, sqlite3-ruby, will_paginate, mechanize)
 * maybe make a shoes app to make it as easy as possible to install stoker gem and then start/stop web interface
\ No newline at end of file</diff>
      <filename>TODO</filename>
    </modified>
    <modified>
      <diff>@@ -5,7 +5,8 @@ module Net
     attr_reader :stoker
 
     FORM_PREFIXES = {
-      &quot;name&quot;    =&gt; &quot;n2&quot;
+      &quot;name&quot;    =&gt; &quot;n2&quot;,
+      &quot;sensor_serial_number&quot; =&gt; &quot;sw&quot;
     }
 
     def initialize(stoker, options = {})
@@ -21,7 +22,10 @@ module Net
     end
 
     def sensor_serial_number=(str)
-      if @sensor_serial_number = @stoker.sensor(str).serial_number
+      if str.to_s == &quot;&quot; or str == &quot;None&quot;
+        @stoker.post(@stoker.sensor(self.sensor.serial_number).form_variable(&quot;blower&quot;) =&gt; &quot;None&quot;) rescue nil
+        @sensor_serial_number = nil
+      elsif @sensor_serial_number = @stoker.sensor(str).serial_number
         @stoker.blowers.each do |b|
           if b.sensor_serial_number == @sensor_serial_number
             s.change_without_update(&quot;blower_serial_number&quot;, nil) unless b == self
@@ -35,7 +39,7 @@ module Net
     end
 
     def sensor=(s)
-      self.sensor_serial_number = s.serial_number
+      self.sensor_serial_number = s.serial_number rescue nil
     end
 
     def sensor
@@ -49,32 +53,65 @@ module Net
 
     # updates internal state of object variable without posting an update to the stoker
     def change_without_update(var, val)
-      eval(&quot;@#{var} = val&quot;)
+      eval(&quot;@#{var.to_s} = val&quot;)
     end
 
     def update_attributes(params)
       variables = {}
-      params.each do |k,v|
-        if k.to_s == &quot;sensor&quot;
-          k = v.form_variable(&quot;blower&quot;)
-          v = self.serial_number
-        else
-          k = self.form_variable(k.to_s)
+
+      tp = params
+      params = {}
+      tp.each{|name,value| params[name.to_s] = value}
+
+      params.each do |name, value|
+        case name
+        when &quot;sensor&quot;
+          name = &quot;sensor_serial_number&quot;
+          if value.to_s == &quot;&quot;
+            value = &quot;None&quot;
+          else
+            value = value.serial_number
+          end
+        when &quot;sensor_serial_number&quot;
+          if value.to_s == &quot;&quot;
+            value = &quot;None&quot;
+          end
         end
-        variables[k] = v unless k.to_s == &quot;serial_number&quot;
-        
-        if k.to_s == &quot;sensor&quot;
-          @stoker.blowers.each do |b|
-            if b.sensor_serial_number == v
-              b.change_without_update(&quot;sensor_serial_number&quot;, nil) unless b == self
-            end
+
+        if name == &quot;sensor_serial_number&quot;          
+          # update internal state of any other sensors that have this blower
+          @stoker.sensors.each do |s|
+            s.change_without_update(&quot;blower_serial_number&quot;, nil) if s.blower_serial_number == self.serial_number
           end
-          self.change_without_update(&quot;sensor_serial_number&quot;, v)
+
+          # set the specific sensor blower to myself
+          if value != &quot;None&quot;
+            @stoker.sensor(value).blower_serial_number = self.serial_number
+          end          
+        end
+        
+        variables[name] = value unless name == &quot;serial_number&quot;
+      end
+
+      # update internal state
+      variables.each do |name, value|
+        self.change_without_update(name, value)
+      end
+      
+      params = {}
+      variables.each do |name, value|
+        if name == &quot;sensor_serial_number&quot; and value != &quot;None&quot;
+          params[self.sensor.form_variable(&quot;blower_serial_number&quot;)] = self.serial_number
         else
-          self.change_without_update(k, v)
+          params[self.form_variable(name)] = value
         end
       end
-      @stoker.post(variables)
+      
+      @stoker.post(params)
+    end
+    
+    def to_s
+      @name || @serial_number
     end
   end
 end
\ No newline at end of file</diff>
      <filename>lib/blower.rb</filename>
    </modified>
    <modified>
      <diff>@@ -10,7 +10,8 @@ module Net
       &quot;target&quot;  =&gt; &quot;ta&quot;,
       &quot;high&quot;    =&gt; &quot;th&quot;,
       &quot;low&quot;     =&gt; &quot;tl&quot;,
-      &quot;blower&quot;  =&gt; &quot;sw&quot;
+      &quot;blower&quot;  =&gt; &quot;sw&quot;,
+      &quot;blower_serial_number&quot; =&gt; &quot;sw&quot;
     }
 
     def initialize(stoker, options = {})
@@ -62,14 +63,17 @@ module Net
     end
 
     def blower_serial_number=(str)
-      if @blower_serial_number = @stoker.blower(str).serial_number
+      if str.to_s == &quot;&quot; or str == &quot;None&quot;
+        @blower_serial_number = nil
+        @stoker.post(self.form_variable(&quot;blower&quot;) =&gt; &quot;None&quot;)
+      elsif @blower_serial_number = @stoker.blower(str).serial_number
         self.blower.change_without_update(&quot;sensor_serial_number&quot;, @serial_number)
         @stoker.sensors.each do |s|
           if s.blower_serial_number == @blower_serial_number
             s.change_without_update(&quot;blower_serial_number&quot;, nil) unless s == self
           end
         end
-        @stoker.post(self.form_variable(&quot;blower&quot;) =&gt; @blower_serial_number)
+        @stoker.post(self.form_variable(&quot;blower_serial_number&quot;) =&gt; @blower_serial_number)
       else
         raise &quot;Blower not found&quot;
       end
@@ -91,24 +95,65 @@ module Net
     
     def update_attributes(params)
       variables = {}
-      params.each do |k,v|
-        if k.to_s == &quot;blower&quot;
-          v = v.serial_number
-        end
-        variables[self.form_variable(k.to_s)] = v unless k.to_s == &quot;serial_number&quot;
-        
-        if k.to_s == &quot;blower&quot;
-          @stoker.sensors.each do |s|
-            if s.blower_serial_number == v
-              s.change_without_update(&quot;blower_serial_number&quot;, nil) unless s == self
+
+      tp = params
+      params = {}
+      tp.each{|name,value| params[name.to_s] = value}
+
+      params.each do |name, value|
+        case name
+        when &quot;blower&quot;
+          name = &quot;blower_serial_number&quot;
+          if value.to_s == &quot;&quot;
+            value = &quot;None&quot;
+          else
+            value = value.serial_number
+          end
+        when &quot;blower_serial_number&quot;
+          if value.to_s == &quot;&quot;
+            value = &quot;None&quot;
+          end
+        when &quot;alarm&quot;
+          value = Net::Stoker::ALARMS.index(value.capitalize)
+        end        
+
+        if name == &quot;blower_serial_number&quot;          
+          if value != &quot;None&quot;
+            # update internal state of any other sensors that have this blower
+            @stoker.sensors.each do |s|
+              s.change_without_update(&quot;blower_serial_number&quot;, nil) if s.blower_serial_number == value
+            end
+            
+            # update the blower's internal state to this sensor
+            @stoker.blower(value).change_without_update(&quot;sensor_serial_number&quot;, self.serial_number)
+          end
+          
+          # update internal state of any blowers pointing to this sensor if we're setting to None
+          if value == &quot;None&quot;
+            @stoker.blowers.each do |b|
+              b.change_without_update(&quot;sensor_serial_number&quot;, nil) if b.sensor_serial_number == self.serial_number
             end
           end
-          self.change_without_update(&quot;blower_serial_number&quot;, v)
-        else
-          self.change_without_update(k, v)
         end
+        
+        variables[name] = value unless name == &quot;serial_number&quot;
       end
-      @stoker.post(variables)
+
+      # update internal state
+      variables.each do |name, value|
+        self.change_without_update(name, value)
+      end
+      
+      params = {}
+      variables.each do |name, value|
+        params[self.form_variable(name)] = value
+      end
+      
+      @stoker.post(params)
     end
+    
+    def to_s
+      @name || @serial_number
+    end    
   end
 end
\ No newline at end of file</diff>
      <filename>lib/sensor.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,6 +3,7 @@
 require &quot;rubygems&quot;
 require &quot;hpricot&quot;
 require &quot;net/http&quot;
+require &quot;mechanize&quot;
 require &quot;cgi&quot;
 require &quot;open-uri&quot;
 require &quot;net/telnet&quot;
@@ -278,15 +279,21 @@ module Net
 
       warn &quot;Posting #{post_url}?#{q}&quot;
 
+      # agent = WWW::Mechanize.new
+      # agent.read_timeout = 120
+      # page = agent.post(post_url, params)
+      # puts page.body
+
       # res = HTTP.post_form(URI.parse(post_url), params)
       url = URI.parse(post_url)
       req = Net::HTTP::Post.new(url.path)
-      req[&quot;Keep-Alive&quot;] = 300
-      req[&quot;Connection&quot;] = &quot;keep-alive&quot;
-      req[&quot;Referer&quot;] = &quot;http://#{@host}:#{@http_port}/index.html&quot;
+      # req[&quot;Keep-Alive&quot;] = false
+      # req[&quot;Keep-Alive&quot;] = 300
+      # req[&quot;Connection&quot;] = &quot;keep-alive&quot;
+      # req[&quot;Referer&quot;] = &quot;http://#{@host}:#{@port}/index.html&quot;
       req.set_form_data(params)
       http = Net::HTTP.new(url.host, url.port)
-      http.read_timeout = 600
+      # http.read_timeout = 0
       res = http.start {|http| http.request(req)}
       case res
       when Net::HTTPSuccess, Net::HTTPRedirection
@@ -309,5 +316,8 @@ module Net
       @blowers.find{|b| b.name.downcase == str or b.serial_number.downcase == str}
     end
       
+    def to_s
+      @name || @host
+    end    
   end
 end
\ No newline at end of file</diff>
      <filename>lib/stoker.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,6 +11,13 @@ stoker = Net::Stoker.new(&quot;10.1.1.8&quot;, :connection =&gt; &quot;http&quot;)
 puts &quot;Getting data...&quot;
 stoker.get
 
+# 530000112A584E30: Yellow
+# 440000112A621E30: Pit Temp
+# 0E0000112A5D1630: Blue
+# 9C00001195DEE430: Red
+
+# 140000002AA65105: Fan
+
 puts &quot;Listing blowers:&quot;
 stoker.blowers.each do |blower|
   puts &quot;#{blower.serial_number}, #{blower.name}, #{blower.sensor.name rescue ''}&quot;
@@ -21,7 +28,10 @@ stoker.sensors.each do |sensor|
   puts &quot;#{sensor.serial_number}, #{sensor.name}, #{sensor.temp}, #{sensor.target}, #{sensor.alarm}, #{sensor.low}, #{sensor.high}, #{sensor.blower.name rescue ''}&quot;
 end
 
-# sensor = stoker.sensors[0]
+sensor = stoker.sensor(&quot;530000112A584E30&quot;)
+res = sensor.update_attributes(:name =&gt; &quot;Yellow Foo&quot;, :blower_serial_number =&gt; stoker.blower(&quot;140000002AA65105&quot;).serial_number)
+puts res.to_s
+
 # name = sensor.name
 # serial_number = sensor.serial_number
 # </diff>
      <filename>test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,6 @@
 class Blower &lt; ActiveRecord::Base
   belongs_to :stoker
-  
-  has_one :sensor
+  belongs_to :sensor
   
   has_many :adjustments
   
@@ -12,19 +11,17 @@ class Blower &lt; ActiveRecord::Base
 
   def update_net_stoker
     if !Stoker.skip_update and (self.changed &amp; [&quot;name&quot;, &quot;sensor_id&quot;]).size &gt; 0
-      spawn do
+      # spawn do
         begin
-          self.stoker.net.get
-
           params = {}
           
           [&quot;name&quot;, &quot;sensor_id&quot;].each do |field|
             if self.changed.include?(field)
               if field == &quot;sensor_id&quot;
                 if self.sensor_id.to_s == &quot;&quot;
-                  params[:sensor] = nil
+                  params[:sensor_serial_number] = nil
                 else
-                  params[:sensor] = self.stoker.net.sensor(self.sensor.serial_number)
+                  params[:sensor_serial_number] = self.sensor.serial_number
                 end
               else
                 params[field] = self.send(field)
@@ -36,7 +33,7 @@ class Blower &lt; ActiveRecord::Base
         rescue Exception =&gt; e
           raise &quot;#{e.message}\n#{e.backtrace.to_yaml}&quot;
         end
-      end
+      # end
     end
   end
 </diff>
      <filename>web/app/models/blower.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,11 @@
 class Sensor &lt; ActiveRecord::Base
   ALARMS = [&quot;None&quot;, &quot;Food&quot;, &quot;Fire&quot;]
   
+  attr_accessor :blower_id
+  
   belongs_to :stoker
-  belongs_to :blower
+
+  has_one :blower
   
   has_many :events
   has_many :adjustments
@@ -11,40 +14,43 @@ class Sensor &lt; ActiveRecord::Base
   validates_inclusion_of :alarm, :in =&gt; ALARMS
   validates_uniqueness_of :serial_number
   validates_uniqueness_of :name, :scope =&gt; :stoker_id, :unless =&gt; Proc.new {|s| s.stoker_id.to_s == &quot;&quot;}
+
+  before_update :set_blower  
+  before_update :update_net_stoker
   
-  after_update :update_net_stoker
-  
+  def blower_id
+    self.blower.id rescue nil
+  end
+    
   def temp
     self.events.find(:first, :order =&gt; &quot;created_at DESC&quot;).temp rescue nil
   end
 
   def update_net_stoker
     if !Stoker.skip_update and (self.changed &amp; [&quot;name&quot;, &quot;target&quot;, &quot;alarm&quot;, &quot;high&quot;, &quot;low&quot;, &quot;blower_id&quot;]).size &gt; 0
-      spawn do
-        begin
-          self.stoker.net.get
-      
+      # spawn do
+        begin      
           params = {}
           
           [&quot;name&quot;, &quot;target&quot;, &quot;alarm&quot;, &quot;high&quot;, &quot;low&quot;, &quot;blower_id&quot;].each do |field|
             if self.changed.include?(field)
               if field == &quot;blower_id&quot;
                 if self.blower_id.to_s == &quot;&quot;
-                  params[:blower] = nil
+                  params[:blower_serial_number] = nil
                 else
-                  params[:blower] = self.stoker.net.blower(self.blower.serial_number)
+                  params[:blower_serial_number] = self.blower.serial_number
                 end
               else
                 params[field] = self.send(field)
               end
             end
           end
-                
+          
           self.stoker.net.sensor(self.serial_number).update_attributes(params)
         rescue Exception =&gt; e
           raise &quot;#{e.message}\n#{e.backtrace.to_yaml}&quot;
         end          
-      end
+      # end
     end
   end
 
@@ -64,5 +70,24 @@ class Sensor &lt; ActiveRecord::Base
     
     alarm_status
   end
+
+  private
+  
+  def set_blower
+    Stoker.no_update do
+    
+      puts &quot;Updating blower assignment in sensor model&quot;
+      if b = self.blower
+        if @blower_id.to_s == &quot;&quot;
+          b.sensor_id = nil
+        else
+          b.sensor_id = self.id
+        end
+        b.save!
+      end
+      
+    end
+    true
+  end
   
 end</diff>
      <filename>web/app/models/sensor.rb</filename>
    </modified>
    <modified>
      <diff>@@ -25,12 +25,40 @@ class Stoker &lt; ActiveRecord::Base
   end
   
   def net
-    @net ||= Net::Stoker.new(host,
-      :connection  =&gt; self.connection_type, 
-      :port        =&gt; self.port,
-      :output_port =&gt; self.output_port, 
-      :telnet_port =&gt; self.telnet_port
-    )
+    if @net.nil?
+      @net = Net::Stoker.new(host,
+        :connection  =&gt; self.connection_type, 
+        :port        =&gt; self.port,
+        :output_port =&gt; self.output_port, 
+        :telnet_port =&gt; self.telnet_port
+      )
+    
+      self.sensors.each do |s|
+        @net.sensors &lt;&lt; Net::Sensor.new(@net,
+          {
+            :serial_number        =&gt; s.serial_number,
+            :name                 =&gt; s.name,
+            :blower_serial_number =&gt; (s.blower.serial_number rescue nil),
+            :alarm                =&gt; s.alarm,
+            :high                 =&gt; s.high,
+            :low                  =&gt; s.low,
+            :target               =&gt; s.target
+          }
+        )
+      end
+
+      self.blowers.each do |b|
+        @net.blowers &lt;&lt; Net::Blower.new(@net,
+          {
+            :serial_number        =&gt; b.serial_number,
+            :name                 =&gt; b.name,
+            :sensor_serial_number =&gt; (b.sensor.serial_number rescue nil)
+          }
+        )
+      end
+    end
+    
+    @net
   end
   
   def sync!
@@ -43,6 +71,7 @@ class Stoker &lt; ActiveRecord::Base
       net_stoker.get
 
       Stoker.no_update do
+        puts &quot;Updating blowers&quot;
         net_stoker.blowers.each do |nb|
           if blower = Blower.find_or_create_by_serial_number(nb.serial_number)
             blower.update_attributes!(
@@ -54,6 +83,7 @@ class Stoker &lt; ActiveRecord::Base
           end
         end
 
+        puts &quot;Updating sensors&quot;
         net_stoker.sensors.each do |ns|
           if sensor = Sensor.find_or_create_by_serial_number(ns.serial_number)
             sensor.update_attributes!(
@@ -66,10 +96,13 @@ class Stoker &lt; ActiveRecord::Base
             )
 
             if ns.blower_serial_number.to_s != &quot;&quot;
-              sensor.blower = Blower.find_by_serial_number(ns.blower_serial_number)
-              sensor.save!
+              b = Blower.find_by_serial_number(ns.blower_serial_number)
+              puts &quot;Sensor #{sensor.name} assigning to blower #{b.name}&quot;
+              b.sensor_id = sensor.id
+              b.save!
             end
         
+            puts &quot;Creating events&quot;
             Event.create!(
               :stoker =&gt; self,
               :sensor =&gt; sensor,</diff>
      <filename>web/app/models/stoker.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,6 +11,11 @@
 &lt;/p&gt;
 
 &lt;p&gt;
+  &lt;b&gt;Sensor&lt;/b&gt;&lt;br /&gt;
+  &lt;%= f.collection_select :sensor_id, Sensor.find(:all), :id, :name, {:include_blank =&gt; true} %&gt;
+&lt;/p&gt;
+
+&lt;p&gt;
   &lt;b&gt;Stoker&lt;/b&gt;&lt;br /&gt;
   &lt;%= f.collection_select :stoker_id, Stoker.find(:all), :id, :name %&gt;
 &lt;/p&gt;</diff>
      <filename>web/app/views/blowers/_form.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,5 @@
 &lt;%= error_messages_for :sensor %&gt;
+&lt;%= error_messages_for :blower %&gt;
 
 &lt;p&gt;
   &lt;b&gt;Serial number&lt;/b&gt;&lt;br /&gt;</diff>
      <filename>web/app/views/sensors/_form.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -9,7 +9,7 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version =&gt; 20080626215857) do
+ActiveRecord::Schema.define(:version =&gt; 20080627181229) do
 
   create_table &quot;adjustments&quot;, :force =&gt; true do |t|
     t.integer  &quot;cook_id&quot;
@@ -34,6 +34,7 @@ ActiveRecord::Schema.define(:version =&gt; 20080626215857) do
     t.integer  &quot;stoker_id&quot;
     t.datetime &quot;created_at&quot;
     t.datetime &quot;updated_at&quot;
+    t.integer  &quot;sensor_id&quot;
   end
 
   add_index &quot;blowers&quot;, [&quot;stoker_id&quot;], :name =&gt; &quot;index_blowers_on_stoker_id&quot;
@@ -76,14 +77,12 @@ ActiveRecord::Schema.define(:version =&gt; 20080626215857) do
     t.string   &quot;alarm&quot;,         :default =&gt; &quot;None&quot;
     t.integer  &quot;low&quot;
     t.integer  &quot;high&quot;
-    t.integer  &quot;blower_id&quot;
     t.integer  &quot;stoker_id&quot;
     t.datetime &quot;created_at&quot;
     t.datetime &quot;updated_at&quot;
   end
 
   add_index &quot;sensors&quot;, [&quot;alarm&quot;], :name =&gt; &quot;index_sensors_on_alarm&quot;
-  add_index &quot;sensors&quot;, [&quot;blower_id&quot;], :name =&gt; &quot;index_sensors_on_blower_id&quot;
   add_index &quot;sensors&quot;, [&quot;stoker_id&quot;], :name =&gt; &quot;index_sensors_on_stoker_id&quot;
   add_index &quot;sensors&quot;, [&quot;name&quot;], :name =&gt; &quot;index_sensors_on_name&quot;
   add_index &quot;sensors&quot;, [&quot;serial_number&quot;], :name =&gt; &quot;index_sensors_on_serial_number&quot;</diff>
      <filename>web/db/schema.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>f2e1ca6c69ede318d6910fd46e10559006e1cd8c</id>
    </parent>
  </parents>
  <author>
    <name>Tony Buser</name>
    <email>tbuser@gmail.com</email>
  </author>
  <url>http://github.com/tbuser/stoker/commit/7e376814c1fa98a421f6c9513f8a67377b0848bb</url>
  <id>7e376814c1fa98a421f6c9513f8a67377b0848bb</id>
  <committed-date>2008-06-27T14:01:05-07:00</committed-date>
  <authored-date>2008-06-27T14:01:05-07:00</authored-date>
  <message>fixing bugs... setting fan to sensor still isn't working right yet...</message>
  <tree>23ba6b27821b37b83b8dd5428a09004033a5d65a</tree>
  <committer>
    <name>Tony Buser</name>
    <email>tbuser@gmail.com</email>
  </committer>
</commit>
