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.
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.
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
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 :)