Ok, I've digged a little in the topic.
I've read all what I could find, and I started to use PortMon to sniff USB traffic, and then I started to debug the answers of the stick to the domotiga commands.
I've realized that actually the powerinfo and getdeviceinfo were not failing systematically, but randomly. I've added some debugging options and I've modified a little the CPlugwise.class as follow (patch agains 594):
Code: Select all
--- CPlugwise.class 2011-05-15 17:30:44.000000000 +0200
+++ CPlugwise.class.new 2011-05-15 17:30:21.000000000 +0200
@@ -81,7 +81,7 @@ PUBLIC SUB Run()
tPlugwise.Delay = iPollTime * 1000 ' multiply for seconds
tPlugwise.Start
- IF iFirmware = 2009 THEN InitStick()
+ IF iFirmware = 2009 OR IF iFirmware = 2010 THEN InitStick()
CheckPlugs()
END
@@ -107,7 +107,7 @@ PUBLIC SUB InitStick()
Main.WriteDebugLog(("[Plugwise] String: ") & sString & (" CRC: ") & sCRC)
END IF
Send(sComplete)
- sResult = GetResult(STICKINITRESPONSECODE)
+ sResult = GetResult(STICKINITRESPONSECODE, sComplete)
IF sResult THEN
IF bPlugwiseDebug THEN
sSeq = Mid(sResult, 1, 4)
@@ -180,23 +180,25 @@ PUBLIC SUB GetDeviceInfo(sAddress AS Str
Main.WriteDebugLog(("[Plugwise] String: ") & sString & (" CRC: ") & sCRC)
END IF
- IF iFirmware = 2009 THEN iMinLength += 34
-
+ IF iFirmware = 2009 OR IF iFirmware = 2010 THEN iMinLength += 34
+
+
Send(sComplete)
- sResult = GetResult(DEVICEINFORESPONSECODE)
+ sResult = GetResult(DEVICEINFORESPONSECODE, sComplete)
IF Len(sResult) > iMinLength THEN
- IF iFirmware = 2009 THEN
- sMacRecv = Mid(sResult, 5, 16)
- sRelay = Mid(sResult, 37, 2)
- ELSE
- sMacRecv = Mid(sResult, 1, 16)
- sRelay = Mid(sResult, 33, 2)
- END IF
+ SELECT iFirmware
+ CASE 2010, 2009
+ sMacRecv = Mid(sResult, 5, 16)
+ sRelay = Mid(sResult, 37, 2)
+ CASE 2008
+ sMacRecv = Mid(sResult, 1, 16)
+ sRelay = Mid(sResult, 33, 2)
+ END SELECT
sState = IIf(sRelay = "01", "On", "Off")
IF bPlugwiseDebug THEN
Main.WriteDebugLog(("[Plugwise] GetDeviceInfo Result: ") & sResult)
Main.WriteDebugLog(("[Plugwise] MAC Address: ") & sMacRecv)
- IF iFirmware = 2009 THEN
+ IF iFirmware = 2009 OR IF iFirmware = 2010 THEN
sSeq = Mid(sResult, 1, 4)
sLogAddress = Mid(sResult, 29, 8)
iLogAddress = (HexToInt(sLogAddress) - 278528) / 32
@@ -237,27 +239,29 @@ PUBLIC SUB GetPowerInfo(sAddress AS Stri
Main.WriteDebugLog(("[Plugwise] String: ") & sString & (" CRC: ") & sCRC)
END IF
- IF iFirmware = 2009 THEN iMinLength += 24
+ IF iFirmware = 2009 OR IF iFirmware = 2010 THEN iMinLength += 24
+
Send(sComplete)
- sResult = GetResult(CALIBRATIONRESPONSECODE)
+ sResult = GetResult(CALIBRATIONRESPONSECODE, sComplete)
IF Len(sResult) > iMinLength THEN
- IF iFirmware = 2009 THEN
- sSeq = Mid(sResult, 8, 4)
- fGainA = HexToFloat(Mid(sResult, 28, 8))
- fGainB = HexToFloat(Mid(sResult, 36, 8))
- fOffTot = HexToFloat(Mid(sResult, 44, 8))
- fOffNoise = HexToFloat(Mid(sResult, 52, 8))
- ELSE
- fGainA = HexToFloat(Mid(sResult, 1, 8))
- fGainB = HexToFloat(Mid(sResult, 9, 8))
- fOffTot = HexToFloat(Mid(sResult, 17, 8))
- fOffNoise = HexToFloat(Mid(sResult, 25, 8))
- END IF
+ SELECT iFirmware
+ CASE 2010, 2009
+ sSeq = Mid(sResult, 8, 4)
+ fGainA = HexToFloat(Mid(sResult, 28, 8))
+ fGainB = HexToFloat(Mid(sResult, 36, 8))
+ fOffTot = HexToFloat(Mid(sResult, 44, 8))
+ fOffNoise = HexToFloat(Mid(sResult, 52, 8))
+ CASE 2008
+ fGainA = HexToFloat(Mid(sResult, 1, 8))
+ fGainB = HexToFloat(Mid(sResult, 9, 8))
+ fOffTot = HexToFloat(Mid(sResult, 17, 8))
+ fOffNoise = HexToFloat(Mid(sResult, 25, 8))
+ END SELECT
IF bPlugwiseDebug THEN
Main.WriteDebugLog(("[Plugwise] GetCalibration Result: ") & sResult)
- IF iFirmware = 2009 THEN Main.WriteDebugLog(("[Plugwise] Sequence Number: ") & sSeq)
+ IF iFirmware = 2009 OR IF iFirmware = 2010 THEN Main.WriteDebugLog(("[Plugwise] Sequence Number: ") & sSeq)
Main.WriteDebugLog(("[Plugwise] GainA: ") & Str(fGainA))
Main.WriteDebugLog(("[Plugwise] GainB: ") & Str(fGainB))
Main.WriteDebugLog(("[Plugwise] OffTot: ") & Str(fOffTot))
@@ -269,16 +273,16 @@ PUBLIC SUB GetPowerInfo(sAddress AS Stri
sCRC = Hex(CalculateCRC(sString))
sComplete = sHeader & sString & sCRC & Chr(13) & Chr(10)
Send(sComplete)
- sResult = GetResult(POWERINFORESPONSECODE)
+ sResult = GetResult(POWERINFORESPONSECODE, sComplete)
- IF iFirmware = 2009 THEN
- iMinLength = 32
- ELSE
+ IF iFirmware = 2008 THEN
iMinLength = 20
+ ELSE
+ iMinLength = 32
END IF
IF Len(sResult) > iMinLength THEN
- IF iFirmware = 2009 THEN
+ IF iFirmware = 2009 OR IF iFirmware = 2010 THEN
sSeq = Mid(sResult, 8, 4)
sPulses = Mid(sResult, 28, 4)
ELSE
@@ -292,7 +296,7 @@ PUBLIC SUB GetPowerInfo(sAddress AS Stri
IF bPlugwiseDebug THEN
Main.WriteDebugLog(("[Plugwise] GetPowerInfo Result: ") & sResult)
- IF iFirmware = 2009 THEN Main.WriteDebugLog(("[Plugwise] Sequence Number: ") & sSeq)
+ IF iFirmware = 2009 OR IF iFirmware = 2010 THEN Main.WriteDebugLog(("[Plugwise] Sequence Number: ") & sSeq)
Main.WriteDebugLog(("[Plugwise] Pulses: ") & sPulses & " (hex) " & iPulses)
Main.WriteDebugLog(("[Plugwise] Corrected Pulses: ") & fCorrectPulses)
Main.WriteDebugLog(("[Plugwise] kWh: ") & Str(fkWh))
@@ -335,54 +339,76 @@ PRIVATE FUNCTION HexToInt(sHex AS String
END
-PRIVATE FUNCTION GetResult(sType AS String) AS String
+PRIVATE FUNCTION GetResult(sType AS String, sCommand AS String) AS String
DIM iTries AS Integer = 32
- DIM sData, sTemp, sResult AS String
+ DIM iAttempts AS Integer = 0
+ DIM sData, sTemp, sResult, sOldData AS String
DIM iBegin AS Integer
+ DIM bGarbage AS Boolean = TRUE
- WHILE (iTries > 0)
+
+ WHILE (bGarbage)
+ iTries = 32
+ WHILE (iTries > 0)
' wait a bit and read response.
- SLEEP 0.01
+ SLEEP 0.01
' see if we got some data.
- TRY READ #hPlugwise, sTemp, Lof(hPlugwise)
- sData &= sTemp
- DEC iTries
+ TRY READ #hPlugwise, sTemp, Lof(hPlugwise)
+ sData &= sTemp
+ DEC iTries
+ WEND
+ iBegin = InStr(sData, Chr(5) & Chr(5) & Chr(3) & Chr(3) & sType)
+ IF (iBegin == 0) THEN
+ IF (iAttempts < 3) THEN
+ bGarbage = TRUE
+ sOldData = sData
+ Send(sCommand)
+ ELSE
+ bGarbage = FALSE
+ END IF
+ ELSE
+ bGarbage = FALSE
+ END IF
+ INC iAttempts
WEND
-
+
SELECT sType
CASE CALIBRATIONRESPONSECODE
- iBegin = InStr(sData, Chr(5) & Chr(5) & Chr(3) & Chr(3) & CALIBRATIONRESPONSECODE)
IF iBegin THEN
- IF iFirmware = 2009 THEN
+ SELECT iFirmware
+ CASE 2010, 2009
sResult = Mid(sData, iBegin + 1, 150)
- ELSE
+ CASE 2008
sResult = Mid(sData, iBegin + 24, 52)
- END IF
+ END SELECT
END IF
CASE POWERINFORESPONSECODE
- iBegin = InStr(sData, Chr(5) & Chr(5) & Chr(3) & Chr(3) & POWERINFORESPONSECODE)
IF iBegin THEN
- IF iFirmware = 2009 THEN
- sResult = Mid(sData, iBegin + 1, 61)
- ELSE
- sResult = Mid(sData, iBegin + 24, 37)
- END IF
+ SELECT iFirmware
+ CASE 2010, 2009
+ sResult = Mid(sData, iBegin + 1, 61)
+ CASE 2008
+ sResult = Mid(sData, iBegin + 24, 37)
+ END SELECT
END IF
CASE DEVICEINFORESPONSECODE
- iBegin = InStr(sData, Chr(5) & Chr(5) & Chr(3) & Chr(3) & DEVICEINFORESPONSECODE)
IF iBegin THEN
- IF iFirmware = 2009 THEN
- sResult = Mid(sData, iBegin + 8, 60)
- ELSE
- sResult = Mid(sData, iBegin + 8, 34)
- END IF
+ SELECT iFirmware
+ CASE 2010, 2009
+ sResult = Mid(sData, iBegin + 8, 60)
+ CASE
+ sResult = Mid(sData, iBegin + 8, 34)
+ END SELECT
END IF
CASE STICKINITRESPONSECODE
- iBegin = InStr(sData, Chr(5) & Chr(5) & Chr(3) & Chr(3) & STICKINITRESPONSECODE)
IF iBegin THEN sResult = Mid(sData, iBegin + 8, 72)
END SELECT
+ IF (iAttempts > 1) AND IF (Len(sResult) > 0) THEN
+ Main.WriteDebugLog(("sOldData wrong") & sOldData & (" sData correct") & sData)
+ END IF
+
RETURN sResult
END
Basically I do a check and if I do not receive the answer I expect, I resend the command and I read again up to 3 times.
I must still check if this ugly hack actually works all the time (and if it works at all....). I've enabled rrdtools, and I'll keep the thing under observation.