Node-red-contrib-tesla anti-vampire drain function

I'm using the tesla contrib to monitor vehicle charge.

This function checks if the vehicle is offline or online and calls the relevant node to get online or offline data. It will never try to wake the vehicle- I do that elsewhere (for instance when my charger sees the vehicle connected, or when I expect charge to be nearly complete).

This is the first development I've done for a very long time, so sure there's better ways to optimise. It seems to work and has helped me start to understand JS!

I've shared test inject nodes rather than the Tesla nodes which need api, here is how to wire the function in:-

[{"id":"2f4b71c.592088e","type":"inject","z":"70721692.7614c8","name":"Error Test (O/P1)","topic":"","payload":"Error response: 408","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":560,"y":400,"wires":[["cdca6086.5a784"]]},{"id":"a681f5a8.6858c8","type":"inject","z":"70721692.7614c8","name":"vehicle Offline Query- \"asleep\" (O/P1)","topic":"","payload":"{\"id\":\"1234567890987654\",\"vehicle_id\":123456789,\"vin\":\"abcdefgefhijklmno\",\"display_name\":\"Tesla\",\"option_codes\":\"AD15,MDL3,PBSB,RENA,BT37,ID3W,RF3G,S3PB,DRLH,DV2W,W39B,APF0,COUS,BC3B,CH07,PC30,FC3P,FG31,GLFR,HL31,HM31,IL31,LTPB,MR31,FM3B,RS3H,SA3P,STCP,SC04,SU3C,T3CA,TW00,TM00,UT3P,WR00,AU3P,APH3,AF00,ZCST,MI00,CDM0\",\"color\":null,\"tokens\":[\"aabbccddeeff0011\",\"2233445566778899\"],\"state\":\"asleep\",\"in_service\":false,\"id_s\":\"1111111111111111\",\"calendar_enabled\":true,\"api_version\":7,\"backseat_token\":null,\"backseat_token_updated_at\":null}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":492,"y":230,"wires":[["cdca6086.5a784"]]},{"id":"40efa1c9.f4733","type":"inject","z":"70721692.7614c8","name":"vehData Online Query- Outside Temp \"null\", (ready to sleep) (O/P1)","topic":"","payload":"{\"id\":1234567890987654,\"user_id\":654321,\"vehicle_id\":123456789,\"vin\":\"abcdefgefhijklmno\",\"display_name\":\"Tesla\",\"option_codes\":\"AD15,MDL3,PBSB,RENA,BT37,ID3W,RF3G,S3PB,DRLH,DV2W,W39B,APF0,COUS,BC3B,CH07,PC30,FC3P,FG31,GLFR,HL31,HM31,IL31,LTPB,MR31,FM3B,RS3H,SA3P,STCP,SC04,SU3C,T3CA,TW00,TM00,UT3P,WR00,AU3P,APH3,AF00,ZCST,MI00,CDM0\",\"color\":null,\"tokens\":[\"3aabbbb333\",\"1111222289bbbbb3\"],\"state\":\"online\",\"in_service\":false,\"id_s\":\"1111111111111111\",\"calendar_enabled\":true,\"api_version\":7,\"backseat_token\":null,\"backseat_token_updated_at\":null,\"charge_state\":{\"battery_heater_on\":false,\"battery_level\":62,\"battery_range\":184.72,\"charge_current_request\":6,\"charge_current_request_max\":6,\"charge_enable_request\":false,\"charge_energy_added\":0,\"charge_limit_soc\":90,\"charge_limit_soc_max\":100,\"charge_limit_soc_min\":50,\"charge_limit_soc_std\":90,\"charge_miles_added_ideal\":0,\"charge_miles_added_rated\":0,\"charge_port_cold_weather_mode\":null,\"charge_port_door_open\":true,\"charge_port_latch\":\"Engaged\",\"charge_rate\":0,\"charge_to_max_range\":false,\"charger_actual_current\":0,\"charger_phases\":null,\"charger_pilot_current\":6,\"charger_power\":0,\"charger_voltage\":0,\"charging_state\":\"Stopped\",\"conn_charge_cable\":\"IEC\",\"est_battery_range\":142.6,\"fast_charger_brand\":\"<invalid>\",\"fast_charger_present\":false,\"fast_charger_type\":\"<invalid>\",\"ideal_battery_range\":147.77,\"managed_charging_active\":false,\"managed_charging_start_time\":null,\"managed_charging_user_canceled\":false,\"max_range_charge_counter\":0,\"minutes_to_full_charge\":1230,\"not_enough_power_to_heat\":false,\"scheduled_charging_pending\":false,\"scheduled_charging_start_time\":null,\"time_to_full_charge\":20.5,\"timestamp\":1588265747583,\"trip_charging\":false,\"usable_battery_level\":61,\"user_charge_enable_request\":false},\"climate_state\":{\"battery_heater\":false,\"battery_heater_no_power\":false,\"climate_keeper_mode\":\"off\",\"defrost_mode\":0,\"driver_temp_setting\":21,\"fan_status\":0,\"inside_temp\":null,\"is_auto_conditioning_on\":null,\"is_climate_on\":false,\"is_front_defroster_on\":false,\"is_preconditioning\":false,\"is_rear_defroster_on\":false,\"left_temp_direction\":null,\"max_avail_temp\":28,\"min_avail_temp\":15,\"outside_temp\":null,\"passenger_temp_setting\":21,\"remote_heater_control_enabled\":false,\"right_temp_direction\":null,\"seat_heater_left\":0,\"seat_heater_rear_center\":0,\"seat_heater_rear_left\":0,\"seat_heater_rear_right\":0,\"seat_heater_right\":0,\"side_mirror_heaters\":false,\"steering_wheel_heater\":false,\"timestamp\":1588265747583,\"wiper_blade_heater\":false},\"drive_state\":{\"gps_as_of\":1588265746,\"heading\":315,\"latitude\":35.172169,\"longitude\":-7.123456,\"native_latitude\":59.417909,\"native_location_supported\":1,\"native_longitude\":-3.123564,\"native_type\":\"wgs\",\"power\":0,\"shift_state\":null,\"speed\":null,\"timestamp\":1588265747583},\"gui_settings\":{\"gui_24_hour_time\":true,\"gui_charge_rate_units\":\"mi/hr\",\"gui_distance_units\":\"mi/hr\",\"gui_range_display\":\"Ideal\",\"gui_temperature_units\":\"C\",\"show_range_units\":true,\"timestamp\":1588265747583},\"vehicle_config\":{\"can_accept_navigation_requests\":true,\"can_actuate_trunks\":true,\"car_special_type\":\"base\",\"car_type\":\"models2\",\"charge_port_type\":\"EU\",\"ece_restrictions\":true,\"eu_vehicle\":true,\"exterior_color\":\"Red\",\"has_air_suspension\":true,\"has_ludicrous_mode\":true,\"motorized_charge_port\":true,\"plg\":true,\"rear_seat_heaters\":1,\"rear_seat_type\":1,\"rhd\":true,\"roof_color\":\"None\",\"seat_type\":1,\"spoiler_type\":\"Passive\",\"sun_roof_installed\":2,\"third_row_seats\":\"None\",\"timestamp\":1588265747584,\"trim_badging\":\"p90d\",\"use_range_badging\":false,\"wheel_type\":\"Base19\"},\"vehicle_state\":{\"api_version\":7,\"autopark_state_v2\":\"standby\",\"autopark_style\":\"dead_man\",\"calendar_supported\":true,\"car_version\":\"2020.12.5 e1144a6600ff\",\"center_display_state\":0,\"df\":0,\"dr\":0,\"ft\":0,\"homelink_device_count\":1,\"homelink_nearby\":true,\"is_user_present\":false,\"last_autopark_error\":\"no_error\",\"locked\":true,\"media_state\":{\"remote_control_enabled\":true},\"notifications_supported\":true,\"odometer\":18660.410966,\"parsed_calendar_supported\":true,\"pf\":0,\"pr\":0,\"remote_start\":false,\"remote_start_enabled\":true,\"remote_start_supported\":true,\"rt\":0,\"smart_summon_available\":false,\"software_update\":{\"download_perc\":0,\"expected_duration_sec\":2700,\"install_perc\":1,\"status\":\"\",\"version\":\"\"},\"speed_limit_mode\":{\"active\":false,\"current_limit_mph\":50,\"max_limit_mph\":90,\"min_limit_mph\":50,\"pin_code_set\":false},\"summon_standby_mode_enabled\":false,\"sun_roof_percent_open\":0,\"sun_roof_state\":\"unknown\",\"timestamp\":1588265747583,\"valet_mode\":false,\"valet_pin_needed\":true,\"vehicle_name\":\"Bob\"}}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":401,"y":280,"wires":[["cdca6086.5a784"]]},{"id":"8cf85779.10a9d8","type":"debug","z":"70721692.7614c8","name":"O/P2 Online","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1130,"y":340,"wires":[]},{"id":"a4a1db0f.1c98c8","type":"debug","z":"70721692.7614c8","name":"O/P1 Offline","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1131,"y":260,"wires":[]},{"id":"1ea3c8cb.3cd437","type":"inject","z":"70721692.7614c8","name":"vehData Online Query- Outside Temp 20, full online (O/P2)","topic":"","payload":"{\"id\":1234567890987654,\"user_id\":654321,\"vehicle_id\":123456789,\"vin\":\"abcdefgefhijklmno\",\"display_name\":\"Tesla\",\"option_codes\":\"AD15,MDL3,PBSB,RENA,BT37,ID3W,RF3G,S3PB,DRLH,DV2W,W39B,APF0,COUS,BC3B,CH07,PC30,FC3P,FG31,GLFR,HL31,HM31,IL31,LTPB,MR31,FM3B,RS3H,SA3P,STCP,SC04,SU3C,T3CA,TW00,TM00,UT3P,WR00,AU3P,APH3,AF00,ZCST,MI00,CDM0\",\"color\":null,\"tokens\":[\"33b1234567890\",\"1234567890b3\"],\"state\":\"online\",\"in_service\":false,\"id_s\":\"1111111111111111\",\"calendar_enabled\":true,\"api_version\":7,\"backseat_token\":null,\"backseat_token_updated_at\":null,\"charge_state\":{\"battery_heater_on\":false,\"battery_level\":62,\"battery_range\":184.72,\"charge_current_request\":6,\"charge_current_request_max\":6,\"charge_enable_request\":false,\"charge_energy_added\":0,\"charge_limit_soc\":90,\"charge_limit_soc_max\":100,\"charge_limit_soc_min\":50,\"charge_limit_soc_std\":90,\"charge_miles_added_ideal\":0,\"charge_miles_added_rated\":0,\"charge_port_cold_weather_mode\":null,\"charge_port_door_open\":true,\"charge_port_latch\":\"Engaged\",\"charge_rate\":0,\"charge_to_max_range\":false,\"charger_actual_current\":0,\"charger_phases\":null,\"charger_pilot_current\":6,\"charger_power\":0,\"charger_voltage\":0,\"charging_state\":\"Stopped\",\"conn_charge_cable\":\"IEC\",\"est_battery_range\":142.6,\"fast_charger_brand\":\"<invalid>\",\"fast_charger_present\":false,\"fast_charger_type\":\"<invalid>\",\"ideal_battery_range\":147.77,\"managed_charging_active\":false,\"managed_charging_start_time\":null,\"managed_charging_user_canceled\":false,\"max_range_charge_counter\":0,\"minutes_to_full_charge\":1230,\"not_enough_power_to_heat\":false,\"scheduled_charging_pending\":false,\"scheduled_charging_start_time\":null,\"time_to_full_charge\":20.5,\"timestamp\":1588265747583,\"trip_charging\":false,\"usable_battery_level\":61,\"user_charge_enable_request\":false},\"climate_state\":{\"battery_heater\":false,\"battery_heater_no_power\":false,\"climate_keeper_mode\":\"off\",\"defrost_mode\":0,\"driver_temp_setting\":21,\"fan_status\":0,\"inside_temp\":null,\"is_auto_conditioning_on\":null,\"is_climate_on\":false,\"is_front_defroster_on\":false,\"is_preconditioning\":false,\"is_rear_defroster_on\":false,\"left_temp_direction\":null,\"max_avail_temp\":28,\"min_avail_temp\":15,\"outside_temp\":20,\"passenger_temp_setting\":21,\"remote_heater_control_enabled\":false,\"right_temp_direction\":null,\"seat_heater_left\":0,\"seat_heater_rear_center\":0,\"seat_heater_rear_left\":0,\"seat_heater_rear_right\":0,\"seat_heater_right\":0,\"side_mirror_heaters\":false,\"steering_wheel_heater\":false,\"timestamp\":1588265747583,\"wiper_blade_heater\":false},\"drive_state\":{\"gps_as_of\":1588265746,\"heading\":315,\"latitude\":35.127169,\"longitude\":-7.123456,\"native_latitude\":57.581949,\"native_location_supported\":1,\"native_longitude\":-3.123564,\"native_type\":\"wgs\",\"power\":0,\"shift_state\":null,\"speed\":null,\"timestamp\":1588265747583},\"gui_settings\":{\"gui_24_hour_time\":true,\"gui_charge_rate_units\":\"mi/hr\",\"gui_distance_units\":\"mi/hr\",\"gui_range_display\":\"Ideal\",\"gui_temperature_units\":\"C\",\"show_range_units\":true,\"timestamp\":1588265747583},\"vehicle_config\":{\"can_accept_navigation_requests\":true,\"can_actuate_trunks\":true,\"car_special_type\":\"base\",\"car_type\":\"models2\",\"charge_port_type\":\"EU\",\"ece_restrictions\":true,\"eu_vehicle\":true,\"exterior_color\":\"Red\",\"has_air_suspension\":true,\"has_ludicrous_mode\":true,\"motorized_charge_port\":true,\"plg\":true,\"rear_seat_heaters\":1,\"rear_seat_type\":1,\"rhd\":true,\"roof_color\":\"None\",\"seat_type\":1,\"spoiler_type\":\"Passive\",\"sun_roof_installed\":2,\"third_row_seats\":\"None\",\"timestamp\":1588265747584,\"trim_badging\":\"p90d\",\"use_range_badging\":false,\"wheel_type\":\"Base19\"},\"vehicle_state\":{\"api_version\":7,\"autopark_state_v2\":\"standby\",\"autopark_style\":\"dead_man\",\"calendar_supported\":true,\"car_version\":\"2020.12.5 e1144a6600ff\",\"center_display_state\":0,\"df\":0,\"dr\":0,\"ft\":0,\"homelink_device_count\":1,\"homelink_nearby\":true,\"is_user_present\":false,\"last_autopark_error\":\"no_error\",\"locked\":true,\"media_state\":{\"remote_control_enabled\":true},\"notifications_supported\":true,\"odometer\":18660.410966,\"parsed_calendar_supported\":true,\"pf\":0,\"pr\":0,\"remote_start\":false,\"remote_start_enabled\":true,\"remote_start_supported\":true,\"rt\":0,\"smart_summon_available\":false,\"software_update\":{\"download_perc\":0,\"expected_duration_sec\":2700,\"install_perc\":1,\"status\":\"\",\"version\":\"\"},\"speed_limit_mode\":{\"active\":false,\"current_limit_mph\":50,\"max_limit_mph\":90,\"min_limit_mph\":50,\"pin_code_set\":false},\"summon_standby_mode_enabled\":false,\"sun_roof_percent_open\":0,\"sun_roof_state\":\"unknown\",\"timestamp\":1588265747583,\"valet_mode\":false,\"valet_pin_needed\":true,\"vehicle_name\":\"Bob\"}}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":431,"y":340,"wires":[["cdca6086.5a784"]]},{"id":"cdca6086.5a784","type":"function","z":"70721692.7614c8","name":"Anti-Vampire","func":"//node-red-contrib-tesla Anti-Vampire drain function block- avoids waking vehicle\n//Connect input to both Tesla Vehicle Query Output (Offline Query) and Tesla AllData Output (Online Query)\n//Connect O/P 1 to Offline Query, and O/P2 to online query\n//Ensure you add delay node of minimum 60 second on each output before input to API query nodes!\n\n//Set PrevVehState from context or \"unknown\" if not stored\nvar PrevVehState = context.get ('VehState') || 'unknown'\n\n//Set VehTemp to msg Value or 99 if missing\nif (msg.payload.hasOwnProperty(\"climate_state\")){\n    var VehTemp = msg.payload.climate_state.outside_temp || 99\n}\nelse VehTemp = 99;\n\n//Set CurVehState from msg.state or set to \"unknown\" if missing\nvar CurVehState = msg.payload.state || 'unknown'\n\n//Check if anywhere in msg contains \"error\", send msg to o/p1\nif (msg.payload == \"error\") {\n    node.status({fill:\"grey\", shape:\"ring\", text:msg})\n    return [msg,null]\n}\n\n//If Vehicle is not online, send msg to o/p1\nelse if (CurVehState !== 'online') {\n    context.set(\"VehState\", CurVehState)\n    node.status({fill:\"red\", shape:\"ring\", text:CurVehState})\n    return [msg,null]\n}\n\n//Check if VehState has changed to \"online\" since previous stored state, send msg to o/p2\nelse if ((CurVehState == \"online\") && (PrevVehState !== \"online\")) {\n    node.status({fill:\"yellow\", shape:\"ring\", text:CurVehState})\n    context.set(\"VehState\", CurVehState)\n    return [null,msg]\n}\n\n//Check if VehState was and still is \"online\" and VehTemp is 99, send msg to o/p1\nelse if ((CurVehState == \"online\") && (PrevVehState == \"online\") && (VehTemp == 99)) {\n    node.status({fill:\"blue\", shape:\"ring\", text:CurVehState})\n    context.set(\"VehState\", CurVehState)\n    return [msg,null]\n} \n\n//Check if VehState was and still is \"online\" and VehTemp is not 99, send msg to o/p2\nelse if ((CurVehState == \"online\") && (PrevVehState == \"online\") && (VehTemp != 99)) {\n    node.status({fill:\"green\", shape:\"ring\", text:CurVehState})\n    context.set(\"VehState\", CurVehState)\n    return [null,msg];\n}\n\n//If VehicleState was unknown try offine query again\nelse if (CurVehState == \"unknown\") {\n    node.status({fill:\"yellow\", shape:\"ring\", text:CurVehState})\n    context.set(\"VehState\", CurVehState)\n    return [null,msg]\n}","outputs":2,"noerr":0,"x":870,"y":300,"wires":[["a4a1db0f.1c98c8"],["8cf85779.10a9d8"]]}]
2 Likes

This topic was automatically closed after 60 days. New replies are no longer allowed.