在 Weave Hvac 主机设备上持续更新空气温度

Update air temperature continuously on Weave Hvac host device

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

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

"Changes to the measured ambient temperature should be reported to the cloud service when the temperature value changes by the minimum level of granularity for the device UI, for example in 0.5 or 1 degree. If the device does not support event-based reporting and utilizes polling, the device should confirm a temperature value change of 0.5 or 1 degree, whichever is the UI's level of granularity, and update the cloud service at most once every 90 seconds."

我可以在设备初始化(在 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);

在了解到设备(而不是 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 秒。来自 documentation:

Changes to the measured ambient temperature should be reported to the cloud service when the temperature value changes by the minimum level of granularity for the device UI, for example in 0.5 or 1 degree. If the device does not support event-based reporting and utilizes polling, the device should confirm a temperature value change of 0.5 or 1 degree, whichever is the UI's level of granularity, and update the cloud service at most once every 90 seconds.

从守护线程外部更改libiota-owned 状态可能会导致麻烦。您应该使用 host_iota_daemon_queue_application_job 到 post 在 libiota 守护进程线程上调用的回调,而不是直接从您的应用程序线程调用 IOTA_MAP_SET。