The port is one that the HE hub is setup to listen on, that is what dictates the setting we need to use on the EcoWitt setup. From what @bertabcd1234 explained, the HE platform looks at the data coming in on that port, reads the Mac/IP and forwards that on to a device with either of those details as the devices Device Network Identifier (DNI), calling a parse() method in the devices driver.
hard to believe but there doesnt seem to be a function in hubitat to resolve an ip address from a hostname, and it throws an error trying to import java.net.InetAddress
Threw this together a while back:
https://raw.githubusercontent.com/thebearmay/hubitat/main/nslookup.groovy
Command is nslookup(String lookupName, Optional String dnsServer)
There are at least 3 variations of returns and parameters depending on the DNS server you choose so I went with Google’s variation. dnsServer will default to 8.8.8.8 if you don’t override, but if you’re running a local DNS it gives you an option.
thanks integrated and written into the fx ... now testing the changes but think it is done will post later if passes muster.
ok working.. code changes:
1. new attribute
attribute "status", "string"; // Display current driver status
attribute "lastUpdate", "string";
attribute "dynamicIPResult","STRING"
}
2. new include
// Preferences ----------------------------------------------------------------------------------------------------------------
import groovy.json.JsonSlurper;
private String gatewayMacAddress() {
//
3. new parameters
preferences {
input(name: "macAddress", type: "string", title: "MAC / IP Address", description: "Wi-Fi gateway MAC or IP address", defaultValue: "", required: true);
input(name: "DDNSName", type: "text", title: "Dynamic DNS Name to use to resolve a changing ip address. Leave Blank if not used.", description: "Enter DDNS Name", required: false)
input(name: "DDNSRefreshTime", type: "number", title: "How often (in Hours) to check/resolve the DDNS Name to discover an IP address change on a remote weather station? (Range 1 - 720, Default 24)?", range: "1..720", defaultValue: 3, required: false)
input(name: "bundleSensors", type: "bool", title: "Compound Outdoor Sensors", description: "Combine sensors in a virtual PWS array", defaultValue: true);
input(name: "unitSystem", type: "enum", title: "System of Measurement", description: "Unit system all values are converted to", options: [0:"Imperial", 1:"Metric"], multiple: false, defaultValue: 0, required: true);
input(name: "logLevel", type: "enum", title: "Log Verbosity", description: "Default: 'Debug' for 30 min and 'Info' thereafter", options: [0:"Error", 1:"Warning", 2:"Info", 3:"Debug", 4:"Trace"], multiple: false, defaultValue: 3, required: true);
}
4. function changes
def nsCallback(resp, data)
{
logDebug("in callback")
// test change
def jSlurp = new JsonSlurper()
Map ipData = (Map)jSlurp.parseText((String)resp.data)
def String newIP = ipData.Answer.data[0]
sendEvent(name:"dynamicIPResult", value:ipData.Answer.data[0])
// now compare ip to our own and if different reset and log
if ((newIP != null) && (newIP != ""))
{
def String currentIP = settings.macAddress
logInfo("Comparing resolved IP: $newIP to $currentIP")
if (currentIP != newIP)
{
logInfo("IP address has Changed !!! Resetting DNI !")
Map dni = dniIsValid(newIP);
// Update Device Network ID
logDebug("got back dni = $dni")
if (dni)
{
device.updateSetting("macAddress", [type: "string", value: dni.canonical]);
dniUpdate();
resyncSensors();
}
}
}
}
void DNSCheckCallback()
{
logInfo("Dns Update Check Callback Startup")
updated()
}
void updated() {
//
// Called everytime the user saves the driver preferences
//
try {
logDebug("updated()");
// Clear previous states
state.clear();
// Unschedule possible previous runIn() calls
unschedule();
// lgk if ddns name resolve this first and do ip check before dniupdatE.. ALSO schedule the re-check.
def String ddnsname = settings.DDNSName
def Number ddnsupdatetime = settings.DDNSRefreshTime
logDebug("DDNS Name = $ddnsname")
logDebug("DDNS Refresh Time = $ddnsupdatetime")
if ((ddnsname != null) && (ddnsname != ""))
{
logDebug("Got ddns name $ddnsname")
// now resolve
Map params = [
uri: "https://8.8.8.8/resolve?name=$ddnsname&type=A",
contentType: "text/plain",
timeout: 20
]
logDebug("calling dns Update url = $params")
asynchttpGet("nsCallback", params)
}
// now schedule next run of update
if ((ddnsupdatetime != null) && (ddnsupdatetime != 00))
{
def thesecs = ddnsupdatetime * 3600
logInfo("Rescheduling IP Address Check to run again in $thesecs seconds.")
runIn(thesecs, "DNSCheckCallback");
}
// Update Device Network ID
String error = dniUpdate();
if (error == null) {
// The gateway dni hasn't changed: we set OK only if a resync sensors is not pending
if (device.getDataValue("sensorResync")) ztatus("Sensor sync pending", "blue");
else ztatus("OK", "green");
}
else if (error != "") ztatus(error, "red");
else resyncSensors();
// Update driver version now and every Sunday @ 2am
// versionUpdate();
// schedule("0 0 2 ? * 1 *", versionUpdate);
// Turn off debug log in 30 minutes
if (logGetLevel() > 2) runIn(1800, logDebugOff);
// lgk get rid of now unused time attribute
device.deleteCurrentState("time")
}
catch (Exception e) {
logError("Exception in updated(): ${e}");
}
}
my version in its entirety
https://raw.githubusercontent.com/lgkahn/hubitat/master/ecowittgateway.groovy
Am I correct in thinking the port definition of 39501 on the Ecowitt is for the Ecowitt and NOT for the Hubitat, yes? Hubitat is monitoring the IP/MAC and doesn't care what the port is.
If that's not the case where is 39501 being defined in Hubitat?
No, Hubitat is only listening for unsolicited inbound traffic on port 39501 (at least at the "automatic" level; an app can define an OAuth endpoint on the regular HTTP or HTTPS ports to listen for whatever it wants as well, but this is a way to handle traffic on a device/driver directly without an app in between--which I guess is the other way you could handle something like this).
Thanks for the quick response! So it seems like me finding 39501 somewhere in some driver code isn't going to happen, is that correct (or am I just missing it) ?
Right, the port is handled at the Hubitat platform level. You could use an app instead of a driver, but then you're stuck with a similar port isssue (just different ports), so I'm not sure there's much benefit.
lastUpdate change has been made, replacing the time attribute. Thanks again for your help with this @kahn-hubitat. I did choose a slightly different date format of yyyy-MM-dd.
Released another update today incorporating the Dynamic DNS lookup @kahn-hubitat tested, utilising code from @thebearmay.
I can't really test this change myself, but am comfortable with the code and the fact it has been tested successfully in a modified version of the driver.
Should we call that the down-under format?
Thanks for the updates (to you, @sburke781, and to @kahn-hubitat, and @thebearmay).
My station is working/reporting great through Ecowitt. The Google Home integration is lacking, unfortunately. I can't get it to give me a simple current weather report or forecast, Seems I can only get a full report of all sensors when I'd just like a summary ("x temperature, partly cloudy" or similar).
Can someone remind me - I remember there was a limit to the number of certain types of sensors I can add to the gateway.
Can I add multiple WH32 sensors? I have one currently, would like to add a couple more. Would they go in this section?
Additional/optional sensors:
• *One WH32 outdoor temperature and humidity sensor
• One WH40 self-emptying rain gauge sensor
• One WS68 wireless anemometer
• Up to 8 WH31 multi-channel temperature and humidity sensors or 8 WN30 multichannel temp sensors
• Up to 8 WH51 soil moisture sensors
• Up to 4 WH41/WH43 PM2.5 air quality sensors
• One WH45 PM2.5/PM10/CO2/temperature and humidity all-in-1 sensor
• Up to 4 WH55 Water leak sensors
• One WH57 Lightning sensor
• Up to 8 WN34 Temp Sensors
• Up to 8 WN35 leaf wetness sensors
*GW1000 and WH32 combo. Minimum PWS needed for Weather Underground API
Excellent!
ANdt
And thanks for the references.
Thanks, except the answer to your question is No.
Only one WH32 per gateway.
Yup - but I can have a bunch of Wh31's so I'm good. So it was a good "no."
It's nice to have taken over a driver with such a knowledgeable and proactive user-base... Thanks @Ranchitat.
(and thanks again to @kahn-hubitat for his recent efforts in enhancing the networking options for the drivers). @vitaliy_kh - I did start work on per-reading settings for the units (imperial vs metric), I just need to iron out a few more kinks in the code...
Thank you very much.