Skip to content

Commit f8e2346

Browse files
committed
Merge branch 'master'
2 parents a82e16d + 3aa362f commit f8e2346

39 files changed

+1638
-1198
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ hardware/MySensorsBase.cpp
208208
hardware/MySensorsSerial.cpp
209209
hardware/MySensorsTCP.cpp
210210
hardware/Nest.cpp
211-
hardware/NetatmoWeatherStation.cpp
211+
hardware/Netatmo.cpp
212212
hardware/OpenZWave.cpp
213213
hardware/openzwave/control_panel/ozwcp.cpp
214214
hardware/openzwave/control_panel/zwavelib.cpp

History.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ Version 2.3xxx
2121
- Implemented: Netatmo, support for multiple weather stations (from the weathermap) and multiple rain sensors
2222
- Changed: OpenZwave, not sending cold-white in the colorclass, solved issues on different zipato bulbs
2323
- Changed: OpenZwave, kWh sensor now maybe compatible with more hardware
24+
- Fixed: Blockly, string uservariables where saved with quotes when not using with set-after
25+
- Implemented: Wind Graph, option to delete a short-log data point
26+
- Implemented: Wind Beaufort scale
27+
- Implemented: Nest Thermostat, support for multiple thermostats
28+
- Implemented: MySensors Ethernet gateway will now request the gateway version on startup
2429

2530
Version 2.3530 (November 1th 2015)
2631
- Implemented: Degree Days in Temperature report

hardware/ASyncTCP.cpp

Lines changed: 86 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414

1515
ASyncTCP::ASyncTCP()
1616
: mIsConnected(false), mIsClosing(false),
17-
mSocket(mIos), mReconnectTimer(mIos)
17+
mSocket(mIos), mReconnectTimer(mIos),
18+
mDoReconnect(true), mIsReconnecting(false)
1819
{
1920
}
2021

@@ -144,18 +145,6 @@ bool ASyncTCP::set_tcp_keepalive()
144145
}
145146
*/
146147

147-
void ASyncTCP::read()
148-
{
149-
if(!mIsConnected) return;
150-
if(mIsClosing) return;
151-
152-
mSocket.async_read_some(boost::asio::buffer(m_buffer,sizeof(m_buffer)),
153-
boost::bind(&ASyncTCP::handle_read,
154-
this,
155-
boost::asio::placeholders::error,
156-
boost::asio::placeholders::bytes_transferred));
157-
}
158-
159148
// callbacks
160149

161150
void ASyncTCP::handle_connect(const boost::system::error_code& error)
@@ -183,20 +172,42 @@ void ASyncTCP::handle_connect(const boost::system::error_code& error)
183172
mIsConnected = false;
184173

185174
OnError(error);
186-
_log.Log(LOG_ERROR,"TCP: Error: %s", error.message().c_str());
175+
OnErrorInt(error);
187176

188-
// schedule a timer to reconnect after 30 seconds
189-
mReconnectTimer.expires_from_now(boost::posix_time::seconds(RECONNECT_TIME));
190-
mReconnectTimer.async_wait(boost::bind(&ASyncTCP::do_reconnect, this, boost::asio::placeholders::error));
177+
if (!mDoReconnect)
178+
{
179+
OnDisconnect();
180+
return;
181+
}
182+
if (!mIsReconnecting)
183+
{
184+
mIsReconnecting = true;
185+
_log.Log(LOG_STATUS, "TCP: Reconnecting in %d seconds...", RECONNECT_TIME);
186+
// schedule a timer to reconnect after 30 seconds
187+
mReconnectTimer.expires_from_now(boost::posix_time::seconds(RECONNECT_TIME));
188+
mReconnectTimer.async_wait(boost::bind(&ASyncTCP::do_reconnect, this, boost::asio::placeholders::error));
189+
}
191190
}
192191
}
193192

193+
void ASyncTCP::read()
194+
{
195+
if (!mIsConnected) return;
196+
if (mIsClosing) return;
197+
198+
mSocket.async_read_some(boost::asio::buffer(m_buffer, sizeof(m_buffer)),
199+
boost::bind(&ASyncTCP::handle_read,
200+
this,
201+
boost::asio::placeholders::error,
202+
boost::asio::placeholders::bytes_transferred));
203+
}
204+
194205
void ASyncTCP::handle_read(const boost::system::error_code& error, size_t bytes_transferred)
195206
{
196207
if (!error)
197208
{
198-
//Read next
199209
OnData(m_buffer,bytes_transferred);
210+
//Read next
200211
//This gives some work to the io_service before it is started
201212
mIos.post(boost::bind(&ASyncTCP::read, this));
202213
}
@@ -209,10 +220,19 @@ void ASyncTCP::handle_read(const boost::system::error_code& error, size_t bytes_
209220

210221
// let listeners know
211222
OnError(error);
212-
213-
// schedule a timer to reconnect after 30 seconds
214-
mReconnectTimer.expires_from_now(boost::posix_time::seconds(RECONNECT_TIME));
215-
mReconnectTimer.async_wait(boost::bind(&ASyncTCP::do_reconnect, this, boost::asio::placeholders::error));
223+
if (!mDoReconnect)
224+
{
225+
OnDisconnect();
226+
return;
227+
}
228+
if (!mIsReconnecting)
229+
{
230+
mIsReconnecting = true;
231+
_log.Log(LOG_STATUS, "TCP: Reconnecting in %d seconds...", RECONNECT_TIME);
232+
// schedule a timer to reconnect after 30 seconds
233+
mReconnectTimer.expires_from_now(boost::posix_time::seconds(RECONNECT_TIME));
234+
mReconnectTimer.async_wait(boost::bind(&ASyncTCP::do_reconnect, this, boost::asio::placeholders::error));
235+
}
216236
}
217237
else
218238
do_close();
@@ -229,9 +249,20 @@ void ASyncTCP::write_end(const boost::system::error_code& error)
229249
OnError(error);
230250

231251
mIsConnected = false;
232-
// schedule a timer to reconnect after 30 seconds
233-
mReconnectTimer.expires_from_now(boost::posix_time::seconds(RECONNECT_TIME));
234-
mReconnectTimer.async_wait(boost::bind(&ASyncTCP::do_reconnect, this, boost::asio::placeholders::error));
252+
253+
if (!mDoReconnect)
254+
{
255+
OnDisconnect();
256+
return;
257+
}
258+
if (!mIsReconnecting)
259+
{
260+
mIsReconnecting = true;
261+
_log.Log(LOG_STATUS, "TCP: Reconnecting in %d seconds...", RECONNECT_TIME);
262+
// schedule a timer to reconnect after 30 seconds
263+
mReconnectTimer.expires_from_now(boost::posix_time::seconds(RECONNECT_TIME));
264+
mReconnectTimer.async_wait(boost::bind(&ASyncTCP::do_reconnect, this, boost::asio::placeholders::error));
265+
}
235266
}
236267
}
237268
}
@@ -270,7 +301,37 @@ void ASyncTCP::do_reconnect(const boost::system::error_code& error)
270301
// close current socket if necessary
271302
mSocket.close();
272303

304+
if (!mDoReconnect)
305+
{
306+
return;
307+
}
308+
mReconnectTimer.cancel();
273309
// try to reconnect, then call handle_connect
310+
_log.Log(LOG_STATUS, "TCP: Reconnecting...");
274311
mSocket.async_connect(mEndPoint,
275312
boost::bind(&ASyncTCP::handle_connect, this, boost::asio::placeholders::error));
313+
mIsReconnecting = false;
314+
}
315+
316+
void ASyncTCP::OnErrorInt(const boost::system::error_code& error)
317+
{
318+
if (
319+
(error == boost::asio::error::address_in_use) ||
320+
(error == boost::asio::error::connection_refused) ||
321+
(error == boost::asio::error::access_denied) ||
322+
(error == boost::asio::error::host_unreachable) ||
323+
(error == boost::asio::error::timed_out)
324+
)
325+
{
326+
_log.Log(LOG_STATUS, "TCP: Connection problem (Unable to connect to specified IP/Port)");
327+
}
328+
else if (
329+
(error == boost::asio::error::eof) ||
330+
(error == boost::asio::error::connection_reset)
331+
)
332+
{
333+
_log.Log(LOG_STATUS, "TCP: Connection reset! (Disconnected)");
334+
}
335+
else
336+
_log.Log(LOG_ERROR, "TCP: Error: %s", error.message().c_str());
276337
}

hardware/ASyncTCP.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,13 @@ class ASyncTCP
4444
virtual void OnError(const std::exception e)=0;
4545
virtual void OnError(const boost::system::error_code& error)=0;
4646

47+
void OnErrorInt(const boost::system::error_code& error);
48+
4749
protected:
4850
bool mIsConnected;
4951
bool mIsClosing;
52+
bool mDoReconnect;
53+
bool mIsReconnecting;
5054

5155
boost::asio::ip::tcp::endpoint mEndPoint;
5256

hardware/DomoticzHardware.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class CDomoticzHardwareBase
9898
friend class CNest;
9999
friend class CThermosmart;
100100
friend class CKodi;
101-
friend class CNetAtmoWeatherStation;
101+
friend class CNetatmo;
102102
friend class CAnnaThermostat;
103103
friend class SatelIntegra;
104104
friend class CLogitechMediaServer;

hardware/EnOceanESP3.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ typedef enum
136136
CO_RD_FILTER = 15, //! Read supplied filters
137137
CO_WR_WAIT_MATURITY = 16, //! Waiting till end of maturity time before received radio telegrams will transmitted
138138
CO_WR_SUBTEL = 17, //! Enable/Disable transmitting additional subtelegram info
139-
CO_WR_MEM = 18, //! Write x bytes of the Flash, XRAM, RAM0 ….
140-
CO_RD_MEM = 19, //! Read x bytes of the Flash, XRAM, RAM0 ….
139+
CO_WR_MEM = 18, //! Write x bytes of the Flash, XRAM, RAM0 ….
140+
CO_RD_MEM = 19, //! Read x bytes of the Flash, XRAM, RAM0 ….
141141
CO_RD_MEM_ADDRESS = 20, //! Feedback about the used address and length of the config area and the Smart Ack Table
142142
CO_RD_SECURITY = 21, //! Read security informations (level, keys)
143143
CO_WR_SECURITY = 22, //! Write security informations (level, keys)
@@ -1194,8 +1194,8 @@ void CEnOceanESP3::ParseRadioDatagram()
11941194
// [Eltako FTR55D, FTR55H, Thermokon SR04 *, Thanos SR *, untested]
11951195
// DATA_BYTE3 is the fan speed or night reduction for Eltako
11961196
// DATA_BYTE2 is the setpoint where 0x00 = min ... 0xFF = max or
1197-
// reference temperature for Eltako where 0x00 = 0°C ... 0xFF = 40°C
1198-
// DATA_BYTE1 is the temperature where 0x00 = +40°C ... 0xFF = 0°C
1197+
// reference temperature for Eltako where 0x00 = 0°C ... 0xFF = 40°C
1198+
// DATA_BYTE1 is the temperature where 0x00 = +40°C ... 0xFF = 0°C
11991199
// DATA_BYTE0_bit_0 is the occupy button, pushbutton or slide switch
12001200
float temp=GetValueRange(DATA_BYTE1,0,40);
12011201
if (Manufacturer == 0x0D)
@@ -1344,7 +1344,7 @@ void CEnOceanESP3::ParseRadioDatagram()
13441344
tsen.TEMP.temperaturel=(BYTE)(at10);
13451345
sDecodeRXMessage(this, (const unsigned char *)&tsen.TEMP);
13461346
}
1347-
else if (szST == "TempHum")
1347+
else if (szST.find("TempHum")==0)
13481348
{
13491349
//(EPP A5-04 01/02)
13501350
float ScaleMax = 0;

hardware/FritzboxTCP.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,25 @@ void FritzboxTCP::OnError(const std::exception e)
148148

149149
void FritzboxTCP::OnError(const boost::system::error_code& error)
150150
{
151-
_log.Log(LOG_ERROR,"Fritzbox: Error: %s",error.message().c_str());
151+
if (
152+
(error == boost::asio::error::address_in_use) ||
153+
(error == boost::asio::error::connection_refused) ||
154+
(error == boost::asio::error::access_denied) ||
155+
(error == boost::asio::error::host_unreachable) ||
156+
(error == boost::asio::error::timed_out)
157+
)
158+
{
159+
_log.Log(LOG_STATUS, "Fritzbox: Can not connect to: %s:%ld", m_szIPAddress.c_str(), m_usIPPort);
160+
}
161+
else if (
162+
(error == boost::asio::error::eof) ||
163+
(error == boost::asio::error::connection_reset)
164+
)
165+
{
166+
_log.Log(LOG_STATUS, "Fritzbox: Connection reset!");
167+
}
168+
else
169+
_log.Log(LOG_ERROR, "Fritzbox: %s", error.message().c_str());
152170
}
153171

154172
bool FritzboxTCP::WriteToHardware(const char *pdata, const unsigned char length)

hardware/MochadTCP.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ bool MochadTCP::StartHardware()
131131

132132
bool MochadTCP::StopHardware()
133133
{
134+
m_stoprequested = true;
134135
if (isConnected())
135136
{
136137
try {
@@ -222,7 +223,25 @@ void MochadTCP::OnError(const std::exception e)
222223

223224
void MochadTCP::OnError(const boost::system::error_code& error)
224225
{
225-
_log.Log(LOG_ERROR, "Mochad: Error: %s", error.message().c_str());
226+
if (
227+
(error == boost::asio::error::address_in_use) ||
228+
(error == boost::asio::error::connection_refused) ||
229+
(error == boost::asio::error::access_denied) ||
230+
(error == boost::asio::error::host_unreachable) ||
231+
(error == boost::asio::error::timed_out)
232+
)
233+
{
234+
_log.Log(LOG_STATUS, "Mochad: Can not connect to: %s:%ld", m_szIPAddress.c_str(), m_usIPPort);
235+
}
236+
else if (
237+
(error == boost::asio::error::eof) ||
238+
(error == boost::asio::error::connection_reset)
239+
)
240+
{
241+
_log.Log(LOG_STATUS, "Mochad: Connection reset!");
242+
}
243+
else
244+
_log.Log(LOG_ERROR, "Mochad: %s", error.message().c_str());
226245
}
227246

228247
bool MochadTCP::WriteToHardware(const char *pdata, const unsigned char length)

hardware/MySensorsBase.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ void MySensorsBase::LoadDevicesFromDatabase()
231231
boost::lock_guard<boost::mutex> l(readQueueMutex);
232232
m_nodes.clear();
233233

234-
std::vector<std::vector<std::string> > result;
234+
std::vector<std::vector<std::string> > result,result2;
235235
result = m_sql.safe_query("SELECT ID, Name, SketchName, SketchVersion FROM MySensors WHERE (HardwareID=%d) ORDER BY ID ASC", m_HwdID);
236236
if (result.size() > 0)
237237
{
@@ -251,6 +251,23 @@ void MySensorsBase::LoadDevicesFromDatabase()
251251
mNode.SketchName = SkectName;
252252
mNode.SketchVersion = SkectVersion;
253253
mNode.lastreceived = 0;
254+
//Load the Childs
255+
result2 = m_sql.safe_query("SELECT ChildID, [Type], [Name], UseAck FROM MySensorsChilds WHERE (HardwareID=%d) AND (NodeID=%d) ORDER BY ChildID ASC", m_HwdID, ID);
256+
if (result2.size() > 0)
257+
{
258+
std::vector<std::vector<std::string> >::const_iterator itt2;
259+
for (itt2 = result2.begin(); itt2 != result2.end(); ++itt2)
260+
{
261+
std::vector<std::string> sd2 = *itt2;
262+
_tMySensorChild mSensor;
263+
mSensor.nodeID = ID;
264+
mSensor.childID = atoi(sd2[0].c_str());
265+
mSensor.presType = (_ePresentationType)atoi(sd2[1].c_str());
266+
mSensor.childName = sd2[2];
267+
mSensor.useAck = atoi(sd2[3].c_str()) != 0;
268+
mNode.m_childs.push_back(mSensor);
269+
}
270+
}
254271
m_nodes[ID] = mNode;
255272
}
256273
}
@@ -1144,12 +1161,12 @@ bool MySensorsBase::WriteToHardware(const char *pdata, const unsigned char lengt
11441161
if ((light_command == light2_sOn) || (light_command == light2_sOff))
11451162
{
11461163
std::string lState = (light_command == light2_sOn) ? "1" : "0";
1147-
if (FindChildWithValueType(node_id, V_LOCK_STATUS) != NULL)
1164+
if (pChild->presType == S_LOCK)
11481165
{
11491166
//Door lock
11501167
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, V_LOCK_STATUS, lState, pChild->useAck);
11511168
}
1152-
else if ((FindChildWithValueType(node_id, V_SCENE_ON) != NULL) || (FindChildWithValueType(node_id, V_SCENE_OFF) != NULL))
1169+
else if (pChild->presType == S_SCENE_CONTROLLER)
11531170
{
11541171
//Scene Controller
11551172
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, (light_command == light2_sOn) ? V_SCENE_ON : V_SCENE_OFF, lState, pChild->useAck);
@@ -1515,6 +1532,10 @@ void MySensorsBase::ParseLine()
15151532
SendNodeCommand(node_id, child_sensor_id, message_type, I_TIME, sstr.str());
15161533
}
15171534
break;
1535+
case I_HEARTBEAT:
1536+
//Received a heartbeat
1537+
while (1 == 0);
1538+
break;
15181539
default:
15191540
while (1==0);
15201541
break;

hardware/MySensorsBase.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ class MySensorsBase : public CDomoticzHardwareBase
140140
I_REQUEST_SIGNING = 15, //Used between sensors when initiating signing.
141141
I_GET_NONCE = 16, //Used between sensors when requesting nonce.
142142
I_GET_NONCE_RESPONSE = 17, //Used between sensors for nonce response.
143+
I_HEARTBEAT = 18,
144+
I_PRESENTATION = 19
143145
};
144146

145147
struct _tMySensorValue

0 commit comments

Comments
 (0)