HTTP请求从arduino更新rails模型

时间:2013-11-30 20:02:40

标签: ruby-on-rails arduino wifi

我有一个名为“桶”的铁轨模型,其属性为“加仑”。我想从arduino(Boarduino v2.0)和Adafruit CC3000 WiFi模块更新某些桶的“加仑”属性。

我的rails应用程序位于计算机上的端口3000。本地主机:3000 /桶

我制作了一个桶式脚手架,所以它有一个带有更新方法的控制器:

# 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

在arduino方面,我发送了一个HTTP请求。

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

它说它已成功发送,但当我检查第1桶的“加仑”属性时,它永远不会改变。我是否以错误的方式格式化HTTP请求?

编辑:

我从服务器收到错误:

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

在我的实际.ino文件中(我从arduino示例中获取),我注意到我发送了一个空白请求。目前正在调查是否删除它将解决WEBrick错误。

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

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

评论:client.println(F(“”));摆脱了这个错误。但更新仍然没有发生。

3 个答案:

答案 0 :(得分:0)

尝试使用gallons参数而不是barrel参数进行更新。这会破坏您的正常更新,因此您应检查gallons的参数,然后仅更新加仑(如果存在):

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

我还没有测试过这段代码,所以请尝试提交两种类型的更新,并检查它们是否都有效。

答案 1 :(得分:0)

另一种选择如下:

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

但我不确定PUT将如何正常运作。大多数网络界面限制对GETPOST的调用。

我必须在我的Arduino代码中调用此字符串:

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

并在我的 config / routes.rb 中我放了:

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

DevicesController.rb 包含:

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

答案 2 :(得分:0)

我遇到了与NODEMCU相同的问题,并从

更改了arduino代码
  Serial.println(String("GET /setLevel/" ) + value + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
                 "Connection: close\r\n" +
                 "\r\n"
                 );

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

解决了它:)