1 #pragma once
2 
3 #include "DomoticzHardware.h"
4 #include <boost/tuple/tuple.hpp>
5 #include <list>
6 #include <mutex>
7 
8 #define MAX_LOG_LINE_LENGTH (2048*3)
9 
10 class XiaomiGateway : public CDomoticzHardwareBase
11 {
12 public:
13 	explicit XiaomiGateway(const int ID);
14 	~XiaomiGateway(void);
15 	bool WriteToHardware(const char *pdata, const unsigned char length) override;
16 
GetGatewayHardwareID()17 	int GetGatewayHardwareID(){ return m_HwdID; };
GetGatewayIp()18 	std::string GetGatewayIp(){ return m_GatewayIp; };
GetGatewaySid()19 	std::string GetGatewaySid(){ if (m_GatewaySID == "") m_GatewaySID = XiaomiGatewayTokenManager::GetInstance().GetSID(m_GatewayIp); return m_GatewaySID; };
20 
IsMainGateway()21 	bool IsMainGateway(){ return m_ListenPort9898; };
SetAsMainGateway()22 	void SetAsMainGateway(){ m_ListenPort9898 = true; };
UnSetMainGateway()23 	void UnSetMainGateway(){ m_ListenPort9898 = false; };
24 
25 private:
26 	bool StartHardware() override;
27 	bool StopHardware() override;
28 	void Do_Work();
29 
30 	bool SendMessageToGateway(const std::string &controlmessage);
31 	void InsertUpdateSwitch(const std::string &nodeid, const std::string &Name, const bool bIsOn, const _eSwitchType switchtype, const int unittype, const int level, const std::string &messagetype, const std::string &load_power, const std::string &power_consumed, const int battery);
32 	void InsertUpdateRGBGateway(const std::string &nodeid, const std::string &Name, const bool bIsOn, const int brightness, const int hue);
33 	void InsertUpdateCubeText(const std::string &nodeid, const std::string &Name, const std::string &degrees);
34 	void InsertUpdateVoltage(const std::string &nodeid, const std::string &Name, const int VoltageLevel);
35 	void InsertUpdateLux(const std::string &nodeid, const std::string &Name, const int Illumination, const int battery);
36 
37 	void InsertUpdateTemperature(const std::string &nodeid, const std::string &Name, const float Temperature, const int battery);
38 	void InsertUpdateHumidity(const std::string &nodeid, const std::string &Name, const int Humidity, const int battery);
39 	void InsertUpdatePressure(const std::string &nodeid, const std::string &Name, const float Pressure, const int battery);
40 	void InsertUpdateTempHumPressure(const std::string &nodeid, const std::string &Name, const float Temperature, const int Humidity, const float Pressure, const int battery);
41 	void InsertUpdateTempHum(const std::string &nodeid, const std::string &Name, const float Temperature, const int Humidity, const int battery);
42 
43 	std::string GetGatewayKey();
44 	unsigned int GetShortID(const std::string & nodeid);
45 
46 	bool m_bDoRestart;
47 	std::shared_ptr<std::thread> m_thread;
48 	std::shared_ptr<std::thread> m_udp_thread;
49 	bool m_OutputMessage;
50 	bool m_IncludeVoltage;
51 	bool m_ListenPort9898;
52 	uint8_t m_GatewayRgbR;          //TODO: Remove, otherwise colors will be mixed up if controlling more than one bulb
53 	uint8_t m_GatewayRgbG;          //TODO: Remove, otherwise colors will be mixed up if controlling more than one bulb
54 	uint8_t m_GatewayRgbB;          //TODO: Remove, otherwise colors will be mixed up if controlling more than one bulb
55 	uint8_t m_GatewayBrightnessInt; //TODO: Remove, otherwise colors will be mixed up if controlling more than one bulb
56 	std::string m_GatewaySID;
57 	std::string m_GatewayIp;
58 	std::string m_LocalIp;
59 	std::string m_GatewayPassword;
60 	std::string m_GatewayMusicId;
61 	std::string m_GatewayVolume;
62 	std::mutex m_mutex;
63 
64 	XiaomiGateway * GatewayByIp( std::string ip );
65 	void AddGatewayToList();
66 	void RemoveFromGatewayList();
67 
68 	int get_local_ipaddr(std::vector<std::string>& ip_addrs);
69 
70 	std::string DetermineChannel(int32_t unitcode);
71 	std::string DetermineDevice(int32_t unitcode);
72 	std::string DetermineCommand(uint8_t commandcode);
73 
74 	class xiaomi_udp_server
75 	{
76 	public:
77 		xiaomi_udp_server(boost::asio::io_service & io_service, int m_HwdID, const std::string &gatewayIp, const std::string &localIp, const bool listenPort9898, const bool outputMessage, const bool includeVolage, XiaomiGateway *parent);
78 		~xiaomi_udp_server();
79 
80 	private:
81 		void start_receive();
82 		void handle_receive(const boost::system::error_code& error, std::size_t /*bytes_transferred*/);
83 
84 		boost::asio::ip::udp::socket socket_;
85 		boost::asio::ip::udp::endpoint remote_endpoint_;
86 		enum { max_length = 1024 };
87 		char data_[max_length];
88 		int m_HardwareID;
89 		std::string m_gatewayip;
90 		std::string m_localip;
91 		bool m_OutputMessage;
92 		bool m_IncludeVoltage;
93 		XiaomiGateway* m_XiaomiGateway;
94 	};
95 
96 	class XiaomiGatewayTokenManager {
97 	public:
98 		static XiaomiGateway::XiaomiGatewayTokenManager& GetInstance();
99 		void UpdateTokenSID(const std::string &ip, const std::string &token, const std::string &sid);
100 		std::string GetToken(const std::string &ip);
101 		std::string GetSID(const std::string &sid);
102 	private:
103 		std::mutex m_mutex;
104 		std::vector<boost::tuple<std::string, std::string, std::string> > m_GatewayTokens;
105 
XiaomiGatewayTokenManager()106 		XiaomiGatewayTokenManager() { ; }
~XiaomiGatewayTokenManager()107 		~XiaomiGatewayTokenManager() { ; }
108 	};
109 };
110