基于mini2440嵌入式linux上整合一套Domoticz智能家居系统(九)使用domoticz+mosquitto+Android客户端实现控制mini2440上的LED(二)

本文介绍如何在mini2440嵌入式系统上,利用Domoticz、mosquitto和MQTT消息解析控制LED。通过分析domoticz/out主题的MQTT消息,设计了一个简单框架处理固定参数和svalue参数,实现了LED开关控制。虽然目前仅处理了固定数量的svalue,但该框架适用于C99编译器,为后续STM32平台开发奠定了基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了充分利用domoticz平台的对MQTT客户端的控制功能,现在,受控设备端代码的核心任务转移到了对domoticz/out主题的MQTT消息解析上。本文将设计一个简单框架来实现对其消息的解析和功能回调。


一、对消息参数名字稍作研究。



domoticz/out的MQTT消息格式参考:
https://www.domoticz.com/wiki/MQTT
根据官方资料,并没有指明参数个数。
实际上看domoticz-3.5877版本源代码,可以在domoticz-3.5877/hardware/MQTT.cpp中看出,
domoticz/out消息大概有两类:
1、普通设备信息。
在void MQTT::SendDeviceInfo(const int m_HwdID, const unsigned long long DeviceRowIdx, const std::string &DeviceName, const unsigned char *pRXCommand)
中进行封装。

我们的开关设备也就在这里封装的。



从这段代码中可以看到:

10个参数名字是固定的

["idx"]

["id"] 

["unit"]

["name"] 

["dtype"] 

["stype"] 

["switchType"]

["RSSI"]

["Battery"]

["nvalue"]

还有个参数名字不固定:

"svalue" 

它可以是以后缀1为开头:"svalue1" 或者"svalue2"、……"svalue(n)" 

这意味着参数数量总体是不固定的。


我们实际的开关量收到的消息如下:

{
   "Battery" : 255,
   "RSSI" : 12,
   "dtype" : "Light/Switch",
   "id" : "00014051",
   "idx" : 1,
   "name" : "LED鐏,
   "nvalue" : 1,
   "stype" : "Switch",
   "svalue1" : "0",
   "switchType" : "On/Off",
   "unit" : 1
}

收到了"svalue1"

要写出一个灵活的框架来适应svalue数量可变,还是有点难度的,先不做这么复杂的。

后文中将写一个能够接收名字固定的参数,再加上"svalue1" "svalue2" ,共处理12个参数类型。(或许有时间写个对"svalue"参数数量可变的处理函数?)

当然,domoticz源码是公开的,我们也可以在c++级别源代码上添加自己所需要的参数。


2、场景消息。

void MQTT::SendSceneInfo(const unsigned long long SceneIdx, const std::string &SceneName)

中进行封装的。

暂时没用到,暂不分析。

详情请参考相关资料和源代码。


二、编写一个简单的消息解析框架。

框架设计如下:



图中红色箭头的过程就是我们主要要实现的过程。

右边两个虚边框就是我们设计的框架。

具体实现代码如下:

CommonTypes.h:

/******************************************************************************
*filename: CommonTypes.h
******************************************************************************/


#ifndef COMMON_TYPES_H
#define COMMON_TYPES_H

#ifdef __cplusplus
extern "C"
{
#endif

//------------------------------------------------------------------------------
//common defines

#define KEY_IDX		0
#define KEY_NAME	1
#define KEY_ID		2
#define KEY_UINT	3
#define KEY_DTYPE	4
#define KEY_STYPE	5
#define KEY_NVALUE	6
#define KEY_SVALUE1	7
#define KEY_SVALUE2	8
#define KEY_BATTERY	9
#define KEY_RSSI	10
#define KEY_SWITCH_TYPE	11

#define MSG_MAX_LEN 128
#define KEY_WORDS_NUM 12

//------------------------------------------------------------------------------
//common types
typedef enum 
{
	STRING=0,
	INT=1,
	UINT=2
}ARG_TYPE_t;

#ifdef __cplusplus
}
#endif

#endif /* #ifndef COMMON_TYPES_H */
/*-- File end --*/


HardwareInterface.h:


/******************************************************************************
*filename: HardwareInterface.h
******************************************************************************/
#ifndef HARDWARE_INTERFACE_H
#define HARDWARE_INTERFACE_H

#ifdef __cplusplus
extern "C"
{
#endif

#include "CommonTypes.h"

//------------------------------------------------------------------------------
//common Hardware interface
typedef struct
{ 
	//解析出来的消息参数类型(STRING、INT、UINT中的一种)
	ARG_TYPE_t type;
	
	//下面是解析出来的具体消息参数数据
	union
	{
		char strArg[MSG_MAX_LEN];
		int iVar;
		unsigned int uiVar;
	};
}ParserArg;


typedef struct
{
	//----------------respons parser interface----------------------------------
	//int(*IDX_ParserCallback)(ParserArg* arg);//无需处理idx
	int(*NAME_ParserCallback)(ParserArg* arg);
	int(*ID_ParserCallback)(ParserArg* arg);
	int(*UINT_ParserCallback)(ParserArg* arg);
	int(*DTYPE_ParserCallback)(ParserArg* arg);
	int(*STYPE_ParserCallback)(ParserArg* arg);
	int(*NVALUE_ParserCallback)(ParserArg* arg);
	int(*SVALUE1_ParserCallback)(ParserArg* arg);
	int(*SVALUE2_ParserCallback)(ParserArg* arg);
	int(*BATTERY_ParserCallback)(ParserArg* arg);
	int(*RSSI_ParserCallback)(ParserArg* arg);
	int(*SWITCH_TYPE_ParserCallback)(ParserArg* arg);
	ParserArg parseArg;
	int RegisterIDX;
	
	//--------------device base operation---------------------------------------
	//must be implement
	int (*Open)();
	void (*Init)();
	void (*Close)();
	
}Hardware;

typedef int(*ParserCallback)(ParserArg* arg);

#ifdef __cplusplus
}
#endif

#endif /* #ifndef HARDWARE_INTERFACE_H */
/*-- File end --*/


HardwareControl.h:


/******************************************************************************
* filename: HardwareControl.h
*****************
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值