我使用Libiota连接到Weave的Hvac主机设备(参见下面的界面),我在理解如何更新当前环境空气温度(在设备上测量)时遇到了一些麻烦。我可以测量它,但我不知道如何连续更新状态,以便我的Weave客户端显示最新的环境空气温度。
我不完全理解文档中的实施说明:
"应将测量环境温度的变化报告给 当温度值变化到最小水平时,云服务 设备UI的粒度,例如0.5或1度。如果 该设备不支持基于事件的报告和利用 轮询时,设备应确认温度值变化为0.5 或者1度,取决于UI的粒度级别,并进行更新 云服务最多每90秒一次。"
我能够在设备初始化时(hvac_controller.c内部)和设定温度设置(即加热温度变化时更新-inide 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);
答案 0 :(得分: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秒。来自documentation:
应将测量环境温度的变化报告给 当温度值变化到最小水平时,云服务 设备UI的粒度,例如0.5或1度。如果 该设备不支持基于事件的报告和利用 轮询时,设备应确认温度值变化为0.5 或者1度,取决于UI的粒度级别,并进行更新 云服务最多每90秒一次。
答案 1 :(得分:0)
从守护程序线程外部更改libiota拥有的状态可能会导致问题。您应该使用host_iota_daemon_queue_application_job
发布要在libiota守护程序线程上调用的回调,而不是直接从您的应用程序线程调用IOTA_MAP_SET。