In a rule under OH 2.3.0, I receive this log error:
'toUnit' is not a member of 'org.eclipse.smarthome.core.library.types.QuantityType'
in reaction to the expression MyItemName.state.toUnit('mph') for a Number:Speed item. Also, an attempt to import tec.uom.se.AbstractUnit at the top of the rule does not result in resolving AbstractUnit when the rule tries to use the parse static method.
@kaikreuzer:
I have seen the same error and wondered why it happened. We might need some implicit imports in Xbase for it - @watou I would say that this is worth a separate issue (as I consider it a bug).
See https://github.com/eclipse/smarthome/issues/5243#issuecomment-397846492
Example rule that produces the log message:
import java.net.URLEncoder
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Map
import java.util.TimeZone
import tec.uom.se.AbstractUnit
/* Uploads weather station data using this format:
http://wiki.wunderground.com/index.php/PWS_-_Upload_Protocol
*/
rule PWS
when
Item DavisVantageVueWindDirectionAverage received update
then
val sdf = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss')
sdf.setTimeZone(TimeZone.getTimeZone('UTC'))
val Map<String, Object> params = newLinkedHashMap(
'action' -> 'updateraw',
'ID' -> 'XXXX',
'PASSWORD' -> 'xxxx',
'dateutc' -> sdf.format(new Date()),
'winddir' -> DavisVantageVueWindDirection.state,
'windspeedmph' -> DavisVantageVueWindSpeed.state.toUnit('mph'),
'windgustmph' -> DavisVantageVueWindSpeedMaximum.state.toUnit('mph'),
'windgustdir' -> DavisVantageVueWindDirectionAverage.state,
'windspdmph_avg2m' -> DavisVantageVueWindSpeedAverage.state.toUnit('mph'),
'winddir_avg2m' -> DavisVantageVueWindDirectionAverage.state,
'humidity' -> DavisVantageVueHumidity.state,
'tempf' -> DavisVantageVueOutdoorTemperature.state.toUnit('掳F'),
'rainin' -> DavisVantageVueRainCurrentHour.state.toUnit('in'),
'baromin' -> MeteoStickPressure.state.toUnit('inHg'),
'softwaretype' -> 'openHAB 2.3')
var url = 'https://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?'
var first = true
for (key : params.keySet()) {
if (!first) {
url += '&'
}
url += key + '=' + URLEncoder::encode(params.get(key).toString, 'UTF-8')
first = false
}
logDebug('PWS', 'url is {}', url)
sendHttpGetRequest(url)
end
I did some analysis, it seems we have multiple problems:
DavisVantageVueWindDirection.state provides you a State and toUnit is indeed not defined on State. If you instead do a DavisVantageVueWindDirection.getStateAs(QuantityType).toUnit('mph'), all should work as expected.
I do not know, why it fails to log this message upon loading of the file as well.'toUnit' is not a member of State, but it prints the type of the actual instance, which is by chance a QuantityType, in which case (only) the statement is actually incorrect. It should either correctly state that it is not defined on State or it should succeed in finding the method and execute it.With your explanation, the rule below now works! All of the unit conversions look correct. Of course, your points 2 and 3 would be best addressed.
import java.net.URLEncoder
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Map
import java.util.TimeZone
/* Uploads weather station data using this format:
http://wiki.wunderground.com/index.php/PWS_-_Upload_Protocol
*/
rule PWS
when
Item DavisVantageVueWindDirectionAverage received update
then
val id = 'XXXX'
val pw = 'xxxx'
val sdf = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss')
sdf.setTimeZone(TimeZone.getTimeZone('UTC'))
val Map<String, Object> params = newLinkedHashMap(
'action' -> 'updateraw',
'ID' -> id,
'PASSWORD' -> pw,
'dateutc' -> sdf.format(new Date()),
'winddir' -> DavisVantageVueWindDirection.getStateAs(QuantityType).toUnit('掳').intValue,
'windspeedmph' -> DavisVantageVueWindSpeed.getStateAs(QuantityType).toUnit('mph').doubleValue,
'windgustmph' -> DavisVantageVueWindSpeedMaximum.getStateAs(QuantityType).toUnit('mph').doubleValue,
'windgustdir' -> DavisVantageVueWindDirectionAverage.getStateAs(QuantityType).toUnit('掳').intValue,
'windspdmph_avg2m' -> DavisVantageVueWindSpeedAverage.getStateAs(QuantityType).toUnit('mph').doubleValue,
'winddir_avg2m' -> DavisVantageVueWindDirectionAverage.getStateAs(QuantityType).toUnit('掳').intValue,
'humidity' -> DavisVantageVueHumidity.state,
'tempf' -> DavisVantageVueOutdoorTemperature.getStateAs(QuantityType).toUnit('掳F').doubleValue,
'rainin' -> DavisVantageVueRainCurrentHour.getStateAs(QuantityType).toUnit('in').doubleValue,
'baromin' -> MeteoStickPressure.getStateAs(QuantityType).toUnit('inHg').doubleValue,
'softwaretype' -> 'openHAB 2.3')
var url = 'https://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?'
var first = true
for (key : params.keySet()) {
if (!first) {
url += '&'
}
url += key + '=' + URLEncoder::encode(params.get(key).toString, 'UTF-8')
first = false
}
logDebug('PWS', 'url is {}', url)
sendHttpGetRequest(url)
end
Most helpful comment
I did some analysis, it seems we have multiple problems:
DavisVantageVueWindDirection.stateprovides you aStateandtoUnitis indeed not defined onState. If you instead do aDavisVantageVueWindDirection.getStateAs(QuantityType).toUnit('mph'), all should work as expected.'toUnit' is not a member of State, but it prints the type of the actual instance, which is by chance aQuantityType, in which case (only) the statement is actually incorrect. It should either correctly state that it is not defined onStateor it should succeed in finding the method and execute it.