Tesla Wall Connector Status (Gen 3 with Wi-Fi) (Amps, Voltage, health, and contact sensor - "is my car plugged in")

Thanks, that would do the trick. I've made note of this and will give it try.

1 Like

I'm putting this together and ran into a problem I can't figure out the answer to...

Step 1 was easy, my dashboard has a virtual keypad, so I figured out I needed a unique number value. Then the step 2 connected to the trigger.
Step 2 was going well, but adding the device, in my case "Tesla Gen 3 Wall Connector" became a problem. It does not show up in the list of devices with a "refresh" command.
However, the device does have a "refresh" command.
'command "refresh"' from the driver code.
For the device, in "Devices" under "Commands", there is a "Refresh" button and it refreshes the values.

So, I'm stuck at step 2 until I figure out how to make the RM rule see the device's refresh command. Maybe this is root of the original problem as well. Interesting...

Any clues?
Appreciate your help. I think I'm very close to getting this done.

No worries! Step 2 is a bit daunting the first time.

In RM, try adding « Run Custom Action » and select « Actuator »:

Your Powerwall should be an item from the list, and Refresh should come up in the « Select capability of action device* » list.

Once « Refresh » is selected, click on the « Done with Action » button. (No need to set a parameter type.)

Does that help?

I sure wish it did (Help).
Same exact problem as before.
My device does NOT appear in the "Actuator" list either.

Something seems really broken with the whole refresh thing. None of the code seems to behave as coded.
Refresh works only from the device page when manually actuated.
Driver code is ignored (or is wrong):


The driver as written has code (may be completely wrong):

I have another driver issue with the "Hubitat Ping" driver. I've used this for two years or so and it has worked to detect when my Konnected Pro is disconnected.
Cloning and repurposing the virtual device for a different network device has proved futile, inconsistent, or confused about the IP address.
The display of device attributes is also confusing. "Device Name" vs "Device Label" and how their use varies from device to device and where the generic/source device name should be.
Quite confusing and a possible source of problems.

I decided to start figuring this out with the "Tesla Plug" driver.
It has been an adventure.

1 Like

If it’s not coming up in the list, it is probably because the dev didn’t set it up with the capability « Actuator ». You can try another capability - see what is available for the Powerwall, like « Sensor » or « Contact Sensor » that is available with the Tesla Plug driver.

Well, I'll post the code I am using, it is derived from the below community thread:

https://community.hubitat.com/t/tesla-wall-connector-status-gen-3-with-wi-fi-amps-voltage-health-and-contact-sensor-is-my-car-plugged-in/100839

The as it stands code only supports 'command "refresh"' which I've established doesn't get found to be added as an action "refresh" option. No actuator at all.

I didn't write it, the posting is old, and I have iPhone apps for this sort of thing.
I thought having the values for state, voltage, and power on my main status dashboard would be nice.
As it is I get stale values without a manual refresh from the driver.

I'll let it be for now and maybe learn more about Hubitat drivers as my will to do so permits.

Thanks for your help. So close. It was educational for me. New Hubitat stuff I've not used before.

Back to your day job. :slight_smile:

/**
 *  Tesla Plug
 *
 *  Copyright 2022 Paul Nielsen
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 *  Change History:
 *
 *    Date        Who             Info            Version        Notes:
 *    ----        ---             ----            -------        ------
 *    2022-09-13  Paul Nielsen    Created         0.0            
 *    2022-09-16  Paul Nielsen    Update          1.0            Added new Fields (Thanks @wounded) and debug toggle
 *    2025-02-04  S Kutoroff      Update          1.0a           Added case 9 : chargeStatus2, suggested by nielsen411
 *
 */
import groovy.json.JsonSlurper

metadata {
    definition (name: "Tesla Plug", namespace: "PMFN", author: "Paul Nielsen") {
        capability "Sensor"
        capability "Contact Sensor"

        command "refresh"

        attribute 'voltage', 'number'
        attribute 'current', 'number'
        attribute 'status', 'string'
        attribute 'last_charge', 'string'
        attribute 'charge_status', 'string'
    }

    preferences {
        input(name: "deviceIP", type: "string", title:"Device IP Address", description: "Enter IP Address of your Tesla Home Charger", required: true, displayDuringSetup: true)
        input name: 'loggingEnabled', type: 'bool', title: '<b>Enable Logging?</b>', description: '<div><i>Automatically disables after 30 minutes.</i></div><br>', defaultValue: false
    }
}

def initialize() {
    runEvery5Minutes("refresh")
    if (settings.loggingEnabled) runIn(1800, disableLogging)

}

def parse(String description) {
    logDebug "Debug: JSON Message: '${description}'"
    def msg = parseLanMessage(description)   
    def bodyString = new groovy.json.JsonSlurper().parseText(msg.body)
    //log.debug(bodyString)
    def volts = bodyString.'grid_v'
    def amps = bodyString.'vehicle_current_a'
    def last = bodyString.'session_energy_wh'/1000
    def chargeStatus = bodyString.'evse_state'
    def chargeStatus2
    switch(chargeStatus){
    case 1 : chargeStatus2 = "Not Connected";
        break;
    case 4 : chargeStatus2 = "Finished";
        break;
    case 9 : chargeStatus2 = "Charging Stopped";
        break;
    case 11 : chargeStatus2 = "Charging";
        break;
    default: chargeStatus2 = "Unknown"
    }
    sendEvent(name: "charge_status", value: chargeStatus2)
    sendEvent(name: "last_charge", value: last + ' KWh')
    sendEvent(name: "voltage", value: volts)
    sendEvent(name: "current", value: amps)
    logDebug "Debug: charge status: '${chargeStatus2}'"
    if (bodyString.'vehicle_connected') {
        close() 
    } else {
        open()
    }
}

def refresh() {
    getCmd()
}

def open(){
	sendEvent(name: "contact", value: "open")
}

def close(){
	sendEvent(name: "contact", value: "closed")
}

def getCmd() {
    def localDevicePort = "80"
    def path = "/api/1/vitals" 
    def body = ""
    def method = "GET"
    def deviceContent = "application/json"
    def headers = [:] 
    headers.put("HOST", "${deviceIP}:${localDevicePort}")
    headers.put("Content-Type", deviceContent)

    try {
        def hubAction = new hubitat.device.HubAction(
            method: method,
            path: path,
            body: body,
            headers: headers
            )
        logDebug "Debug: hubAction '${hubAction}'"
        sendEvent(name: "status", value: "healthy")
        return hubAction
    }
    catch (Exception e) {
        logDebug "Debug: getCmd exception '${e}' on '${hubAction}'"
        sendEvent(name: "status", value: "unhealthy")
    }  
}

void disableLogging() {
	log.info 'Logging disabled'
	device.updateSetting('loggingEnabled',[value:'false',type:'bool'])
}

void logDebug(str) {
    if (loggingEnabled) {
        log.debug str
    }
}
1 Like