0

I have a rails model called "barrel" that has an attribute "gallons". I want to update the "gallons" attribute of certain barrels from an arduino (Boarduino v2.0) and Adafruit CC3000 WiFi module.

My rails app is living at port 3000 on my computer. localhost:3000/barrels

I made a barrels scaffold, so it has a controller with an update method:

# PUT /barrels/1
# PUT /barrels/1.json
def update
@barrel = Barrel.find(params[:id])
respond_to do |format|
  if @barrel.update_attributes(params[:barrel])
    format.html { redirect_to @barrel, notice: 'Barrel was successfully updated.' }
    format.json { head :no_content }
  else
    format.html { render action: "edit" }
    format.json { render json: @barrel.errors, status: :unprocessable_entity }
  end
end
end

On the arduino side I am sending an HTTP request.

Connect to 123.456.7.8:3000  (my IP edited out) 
PUT /barrels/1?gallons=49 HTTP/1.0
Connected & Data sent
Closing connection

It says that it has been sent succesfully, but when I check the "gallons" attribute of barrel 1, it never changes. Am I formatting the HTTP request the wrong way?

edit:

I was getting an error from the server:

[2013-11-30 14:47:45] ERROR WEBrick::HTTPStatus::LengthRequired

In my actual .ino file (that I got from arduino samples), I noticed that I send a blank request. Currently investigating whether removing this will resolve the WEBrick error.

// Send request
if (client.connected()) {

  client.println(request);      
  client.println(F(""));
  Serial.println("Connected & Data sent");
} 

commenting out: client.println(F("")); got rid of this error. But the the updates still don't occur.

tuna
  • 105
  • 2
  • 9

3 Answers3

0

Try updating using the gallons parameter instead of the barrel parameter. This would break your normal update, so you should check the parameters for gallons and then only update the gallons if it is present:

def update
  @barrel = Barrel.find(params[:id])
  respond_to do |format|
    if (params[:gallons] && @barrel.update_attribute(:gallons, params[:gallons]) || @barrel.update_attributes(params[:barrel])
      format.html { redirect_to @barrel, notice: 'Barrel was successfully updated.' }
      format.json { head :no_content }
    else
      format.html { render action: "edit" }
      format.json { render json: @barrel.errors, status: :unprocessable_entity }
    end
  end
end

I haven't tested this code, so try submitting both types of update and check that they both work.

jvperrin
  • 3,322
  • 1
  • 21
  • 33
  • thanks! I've updated this code. I edited the original post with the error I've noticed from the server. – tuna Nov 30 '13 at 20:50
0

Another option is as follows:

 PUT /barrels/1?barrel[gallons]=49 HTTP/1.0

But I'm not sure how well that PUT will exactly work. Most web interfaces limit calls to GET and POST.

I had to call this string in my Arduino code:

POST /device_update/1?device[gauge]=240 HTTP/1.1

and in my config/routes.rb I put:

post "device_update/:id", to: "devices#update"

with DevicesController.rb containing:

class DevicesController < ApplicationController
  skip_before_filter :verify_authenticity_token 
    //Until I figure out how to send an authenticity token from my Arduino
  ...
  def update
    @device = Device.find(params[:id])
    if @device.update_attributes(device_params)
      render @device
    else
      render 'edit'
    end
  end
  ...
  private
    def device_params
      params.require(:device).permit( :gauge )
    end
end
Okomikeruko
  • 985
  • 8
  • 20
0

I was facing the same problem with NODEMCU and changing arduino code from

  Serial.println(String("GET /setLevel/" ) + value + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
                 "Connection: close\r\n" +
                 "\r\n"
                 );

to

Serial.println(String("GET /setLevel/1/" + value )+ " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
                 "Connection: close\r\n" +
                 "\r\n"
                 );

solved it :)