【问题标题】:How to send commands to iot-sensors using android application如何使用 android 应用程序向物联网传感器发送命令
【发布时间】:2019-02-02 18:44:50
【问题描述】:

我在 FIWARE-lab 上的 Ubuntu 16.04 实例中设置了 fiware201:iot-sensor,目前正在构建一个 android 应用程序,以便能够发送命令来访问上下文提供程序提供的虚拟设备,我设置了一个类格式化数据并将其发送到教程提供的端点,但我似乎无法让它工作,每当我尝试发送任何命令时都会收到 422 错误。

其他细节:
我正在使用 volley -> 一个包发送帖子,在 android 中获取请求
fiware-lab 区域:克里特岛

代码如下:


import android.content.Context;
import android.util.Log;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;


public class ApiController {
    private String urlString
    public String serverResponse;
    private RequestQueue queue ;

    public ApiController(Context context) {
        //set context variables if required

        serverResponse = "";
        queue = Volley.newRequestQueue(context);


    }

    public void setDevice(String device) {
        this.device = device;
        urlString = "http://myFloatingIp:3001/iot/" +"Lamp001"; // URL to call

}


    public void send() {
        String uri = String.format(Locale.US, urlString);

        // Request a string response from the provided URL.
        StringRequest stringRequest = new StringRequest(Request.Method.POST,uri,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                               serverResponse = response;
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
              serverResponse = "Error";
            }
        }
                      ) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String,String> params=new HashMap<String,String>();
                params.put("data","urn:ngsi-ld:Lamp:001"@On");
                return params;

            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String,String> headers=new HashMap<String,String>();
                headers.put("Content-Type","text/plain");
                return headers;
            }

        };

// Add the request to the RequestQueue.
        queue.add(stringRequest);
    }


}

【问题讨论】:

    标签: iot fiware fiware-orion


    【解决方案1】:

    422 无法处理的实体

    服务器理解请求实体的内容类型(因此 415 Unsupported Media Type 状态码是不合适的),并且请求实体的语法是正确的(因此 400 Bad请求状态码不合适)但无法处理包含的指令。

    所以这意味着你已经设置了正确的内容类型,并且有效载荷被理解了。

    如果您查看虚拟传感器后面的code,您将看到以下内容:

    // Check for a valid device and command
      if (
        _.indexOf(myCache.keys(), deviceId) === -1 ||
        _.indexOf(['on', 'off'], command) === -1
      ) {
        return res.status(422).send(result + NOT_OK);
    }
    

    因此无法识别设备 ID 或命令。 array of dummy devices 在启动时初始化

    myCache.set('lamp001', LAMP_OFF);
    myCache.set('lamp002', LAMP_OFF);
    myCache.set('lamp003', LAMP_OFF);
    myCache.set('lamp004', LAMP_OFF);
    

    ID 区分大小写,因此您应该发送lamp001 而不是Lamp001。是的,它可以发送更熟悉的 404。语句的另一半确保在无法识别命令时返回 422,您当前发送的是 On 而不是 on

    但是,直接使用 3001 端口发送命令不是用户访问设备的正确方式。在教程材料中,虚拟设备正在模仿通过 HTTP 侦听的 Ultralight 设备 - 它们应该由 IoT 代理连接,而不是由最终用户访问。

    正确的设置方法是按照IoT Agent Tutorial 进行连接 - 这样最终用户可以通过 Orion 上下文代理间接访问设备,并且最终用户不需要知道使用的协议和传输每个设备。

    请记住,南港以南可能发生任何事情 - 由 IoT 代理来处理来自设备的任何响应。然而,一切都将很好地定义来自北端口的 NGSI v2 响应。如果实体未在上下文代理中注册,它将返回熟悉的 404。如果实体已注册,但命令上出现422之类的奇怪情况,则该命令将处于挂起状态,因为它无法处理等等。可能是设备使用 MQTT 连接,并且只定期唤醒以处理命令。

    要更新具有已知 ID 的实体的状态,您只需向上下文代理中的实体发送 PATCH 请求。以编程方式,代码可以看到here - 类似于

    PATCH http://localhost:1026/v2/entities/'urn:ngsi-ld:lamp001/attrs
    

    有效载荷是您要发送的数据。

    【讨论】:

    • 我尝试从 Lamp001 更改为 lamp001 仍然出现相同的错误-> BasicNetwork.performRequest: Unexpected response code 422 for "myfloatingip:3001/iot/lamp001" ,我知道我应该使用 iot 代理,但我正在做用于项目测试目的的固件 201。
    • 第 116 行正在寻找 onoff(区分大小写) - 您发送的是 On
    • 也改变了它,但问题仍然存在,我不明白的是为什么当我使用邮递员发送相同的命令时,即使我改变了大写或小写,也不会出现这个错误(422),它运行通常没有任何问题
    • 在我看来,您的有效负载不正确。查看 Ultralight documentation,您应该发送一个 纯文本 字符串。您正在发送参数,您需要覆盖getBody() 而不是getParams() stackoverflow.com/a/26270185/1179828
    猜你喜欢
    • 2016-05-11
    • 2013-08-16
    • 2011-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    相关资源
    最近更新 更多