# Math help needed!

I'm trying to get a temperature humidity sensor to compare to another to determine if the amount of humidity is high and if so start an exhaust fan. Program runs fine but I want to change from a humidity comparison to a dewpoint comparison to make it more reliable. In that calculation I need to take the log() of a number. I know that I need to import java.lang.Math for the function but I cannot get it working.

I know it is the log() function causing issues because I've removed that part of the equation and it runs through the sub-routine fine. This is in a driver not and app, could that be the issue?

``````
// *?*?*?*?*?*?*?*?*?*?*?*?*?
def DewPoint = dewpt(ftemp,humid)
if(logEnable) log.info "Current Humidity: \${DewPoint}"
sendEvent(name: "calcDewPt", value: DewPoint)
// *?*?*?*?*?*?*?*?*?*?*?*?*?

...
def dewpt(temp,humd) {
if(logEnable) log.info "DewPoint: \${temp}f -> \${humd}%"
C1=-10214.165
C2=-4.8932428
C3=-0.005376579
C4=1.92024e-7
C5=3.55758e-10
C6= -903447e-15
C7=4.1635019
C8=-10440.397
C9=-11.29465
C10=-0.027022355
C11=1.28904e-5
C12=-2.47807e-9
C13=6.5459673
ln=0.4342944819
Tr=459.67+temp
if (temp < 32) {
def double lnPws=C1/Tr+C2+C3*Tr+C4*Tr**2+C5*Tr**3+C6*Tr**4+C7*log(Tr)/ln
} else {
//        lnPws=C8/Tr+C9+C10*Tr+C11*Tr**2+C12*Tr**3+C13*log(Tr)/ln  *** Commented out for trouble shooting
def double lnPws= Math.log(11.638)
}
if(logEnable) log.info "DewPoint lnPws: \${lnPws} -> \${ln}**"  // Never gets here!
Pws= exp(lnPws)
Pw=humd*Pws
lnPw=log(Pw)/ln
if (temp < 32) {
Td=90.12+26.412*lnPw+0.8927*lnPw*lnPw
} else {
Td=100.45+33.193*lnPw+2.319*lnPw*lnPw+0.17074*lnPw**3+1.2063*Pw**0.1984
}
if(logEnable) log.info "DewPoint: \${Td}f -> \${Pws}--"

return Td
}
``````

Thanks for any suggestions

Are you showing any errors? I barely know what I'm talking about, but could it be that your integer is not a double type?

So the error is (possibly not declaiming double correctly .. I'll chase that now) in ...

``````...
def double lnPws= Math.log(11.638)
...
``````

Which is about 2/3 the way through the sub-routine.

You never said what the exact problem was, but here's a guess: is this getting shown as `null` when you print the value on your `log.info` line? If so, that's because you're declaring this variable inside your `if`/`else` (actually two different ones, each with their own scope, only inside the `if` or `else` and no longer accessible once you're outside that block).

To fix, declare this variable somewhere before that so it is still in scope by the time you need it. Right before (and outside of) your `if` is one place that would work. What you wrote should work, though in Groovy you'll normally see something like this:

``````Double lnPws
if (temp < 32) {
lnPws = // ...
// ...
``````

Solved with your assistance: Declaration of double was the trick ....

``````def dewpt(temp,humd) {
def double lnPws
def double Pws
def double Pw
def double lnPw

if(logEnable) log.info "DewPoint: \${temp}f -> \${humd}%"
C1=-10214.165
C2=-4.8932428
C3=-0.005376579
C4= 0.000000192024
C5= 0.000000000355758
C6= -0.0000000000000903447
C7=4.1635019
C8=-10440.397
C9=-11.29465
C10=-0.027022355
C11=1.28904e-5
C12=-2.47807e-9
C13=6.5459673
ln=0.4342944819
Tr=459.67+temp
if (temp < 32) {
lnPws=C1/Tr + C2 + C3*Tr + C4*Tr**2 + C5*Tr**3 + C6*Tr**4 + C7*Math.log(Tr)
} else {
lnPws= C8/Tr + C9 + C10*Tr + C11*Tr**2 + C12*Tr**3 + Math.log(Tr)*C13
}
Pws= Math.exp(lnPws)
Pw=humd*Pws/100
lnPw=Math.log(Pw)
if(logEnable) log.info "DewPoint: Tr = \${Tr}R -> lnPws = \${lnPws} -> Pws = \${Pws} -> Pw = \${Pw} -> lnPw = \${lnPw}"
if (temp < 32) {
Td=90.12+26.412*lnPw+0.8927*lnPw**2
} else {
Td=100.45+33.193*lnPw+2.319*lnPw*lnPw+0.17074*lnPw**3+1.2063*Pw**0.1984
}
if(logEnable) log.info "DewPoint: \${Td}f"

return Td
}
``````

Thanks ALL.

2 Likes

Typically you would use either "def" or "Double" but not both. def is used to define an untyped variable. Also be careful with doing math on doubles, you can get odd decimals, its a java thing. For the best precision decimals use type BigDecimal.

`BigDecimal` is imported by default in Groovy, including the Hubitat app and driver environment, and it should not be necessary to do so yourself. If you find the need to do so, something else is probably going on...