1

我有一个使用 Libiota 连接到 Weave 的 Hvac 主机设备(参见下面的界面),但我在理解如何更新当前环境空气温度(在设备上测量)时遇到了一些麻烦。我可以测量它,但我不知道如何持续更新状态,以便我的 Weave 客户端显示最新的环境空气温度。

我不完全理解文档中的这个实现说明:

“当温度值以设备 UI 的最小粒度级别(例如 0.5 或 1 度)变化时,应将测量的环境温度的变化报告给云服务。如果设备不支持基于事件的报告并利用轮询时,设备应确认温度值变化 0.5 度或 1 度,以 UI 的粒度级别为准,并且每 90 秒最多更新一次云服务。”

我可以在设备初始化时(在 hvac_controller.c 内)和设定温度设置(即当加热温度变化时 - 在 hvac_controller_traits.c- 内)更新当前空气温度。我正在使用它来更新环境空气温度:IOTA_MAP_SET(ambient_air_temperature_state, degrees_celsius, myvalue);

界面:

// Create the example hvac controller interface.
  g_hvac_controller = GoogHvacControllerDevice_create(
      GoogHvacControllerDevice_WITH_AMBIENT_AIR_TEMPERATURE |
      GoogHvacControllerDevice_WITH_AMBIENT_AIR_HUMIDITY |
      GoogHvacControllerDevice_WITH_DISPLAY_UNITS |
      GoogHvacControllerDevice_WITH_HEAT_SUBSYSTEM |
      GoogHvacControllerDevice_WITH_HEAT_SETTING);
4

2 回答 2

1

在了解设备(而不是 Weave)应该轮询并使用 更新空气温度状态后IOTA_MAP_SET(),我使用 pthread 解决了这个问题。

这是我的 main.c

...    
#include <pthread.h>

// Function ran by background thread
void *update_air_temperature() {
  GoogTempSensor* ambient_air_temperature =
      GoogHvacControllerDevice_get_ambient_air_temperature(g_hvac_controller);
  GoogTempSensor_State* ambient_air_temperature_state =
      GoogTempSensor_get_state(ambient_air_temperature);

  while(1) {
    // Update air temperature state every 90 seconds
    // Read air temperature from sensor
    // Code to read sensor and assign value to air_temperature
    float air_temperature;
    ...

    // Update air temperature state
    IOTA_MAP_SET(ambient_air_temperature_state, degrees_celsius, air_temperature);

    sleep(90);
  }
  return NULL;
}

static IotaDaemon* create_hvac_controller_daemon_(void) {
  IOTA_LOG_INFO("Inside create_hvac_controller_daemon_");

  // Create the example hvac controller interface.
  g_hvac_controller = GoogHvacControllerDevice_create(
      GoogHvacControllerDevice_WITH_AMBIENT_AIR_TEMPERATURE |
      GoogHvacControllerDevice_WITH_AMBIENT_AIR_HUMIDITY |
      GoogHvacControllerDevice_WITH_DISPLAY_UNITS |
      GoogHvacControllerDevice_WITH_HEAT_SUBSYSTEM |
      GoogHvacControllerDevice_WITH_HEAT_SETTING);

  IotaDevice* iota_device = iota_device_create_from_interface(
      (IotaInterface*)g_hvac_controller, (IotaModelManifestId){"AHXXX"});
  if (iota_device == NULL) {
    IOTA_LOG_ERROR("Device create from interface failed");
    GoogHvacControllerDevice_destroy(g_hvac_controller);
    return NULL;
  }

  g_iota_daemon = host_framework_create_daemon("hvac_controller", iota_device);

  // Set default state of traits on the hvac_controller.
  example_hvac_controller_configure(g_hvac_controller, g_iota_daemon,
                                    "Heating");

  // Background thread to update air temperature
  pthread_t thread1;
  pthread_create(&thread1, NULL, update_air_temperature, NULL);

  return g_iota_daemon;
}

int main(int argc, char** argv) {
  HostIotaFrameworkConfig config = (HostIotaFrameworkConfig){
      .base =
          (IotaFrameworkConfig){
              .cli_commands = NULL,
              .num_commands = 0,
              .builder = create_hvac_controller_daemon_,
          },
      .argc = argc,
      .argv = argv,
      .user_data = NULL,
      .name = "hvac controller",
  };

  return host_framework_main(&config);
}

不要忘记将 -lpthread 添加到 makefile 中:

...
EXTRA_LIBS=-lpthread

EXAMPLE_OUT_DIR := $(ARCH_OUT_DIR)/examples/$(EXAMPLE)
...

$(EXAMPLE_BIN): $(LIBIOTA_STATIC_LIB) $(PLATFORM_STATIC_LIB) \
        $(EXAMPLES_COMMON_LIB) $(HOST_DEVFW_LIB) \
        $(EXAMPLE_OBJECTS) | $(EXAMPLE_OUT_DIR)
        $(CC) -Wl,--start-group $^ -Wl,--end-group -o $@ $(LDLIBS) $(PLATFORM_LDLIBS) $(EXTRA_LIBS)
...

请记住,您应该只在新气温变化时报告新气温,并且最高频率为 90 秒。从文档中:

当温度值以设备 UI 的最小粒度级别(例如 0.5 或 1 度)发生变化时,应将测量的环境温度的变化报告给云服务。如果设备不支持基于事件的报告并使用轮询,则设备应确认温度值变化 0.5 或 1 度,以 UI 的粒度级别为准,并且每 90 秒最多更新一次云服务。

于 2017-02-03T22:30:02.430 回答
0

从守护线程外部更改 libiota 拥有的状态可能会导致麻烦。您应该使用host_iota_daemon_queue_application_job发布要在 libiota 守护程序线程上调用的回调,而不是直接从应用程序线程调用 IOTA_MAP_SET。

于 2017-02-19T23:50:37.537 回答