Add time last changed to Python script

It’s because they are executing the python files with the exec() function. This is a limitation of that call. It’s possible to add the import built in but it can only be done on the interpreters end. I’m guessing there is a reason they avoid it.

As for your errors, did you change this line

dt.replace(tzinfo=timezone.utc).astimezone(tz=None)

to this?

dt.replace(tzinfo=datetime.timezone.utc).astimezone(tz=None)

yes…

for entity_id in hass.states.get(lights_group).attributes['entity_id']:
    dt = hass.states.get('automation.sense_lights_change').attributes.get('last_triggered')
#    dt.replace(tzinfo=timezone.utc).astimezone(tz=None)
    dt.replace(tzinfo=datetime.timezone.utc).astimezone(tz=None)
#    dt = dt + datetime.timedelta(hours=+1)
    time = '%02d:%02d' % (dt.hour, dt.minute)

gives:

08

welp, you are dead in the water then, just add your +1 and be done with it!

consider it done, and many thanks for your efforts, much appreciated!

btw, all this crap you are doing could be solved with appdaemon. You wouldn’t run into any of these issues.

1 Like

really? have no experience with that yet, next on the list it is then!

since all other methods proved impossible, i would like to try this.
How do i do the check? do i just drop it in the script, or should it be accompanied with several if, then else scenarios?
if has_key: continue
if ! has_key: do this
just asking…

Is this what you mean by that? the import is done successfully in an Custom Component sensor:

import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import (CONF_NAME)
from homeassistant.util import Throttle

from urllib.request import urlopen
from datetime import timedelta
import json
import argparse
import datetime
import logging

import voluptuous as vol

Yes, I have no clue how you are running your other file. Something is running it as an exec() string. What you have listed above is normal. When running through the exec() function, you need to pass the __import__ __builtin__ because it doesn’t perform imports. That cannot be done by you in the script, it has to be done by whatever is calling the exec().

well that sounds ominous… the only thing I can tell you the summary.py is in my /config/python_scripts, as defined in the configuration.yaml through:

python_script:

might not be related but still, in the same folder another python script is being used to extract the last_command and show that in the frontend. This script uses:

state = hass.states.get(entity_id)
dt = datetime.datetime.now() #state.attributes.get('last_triggered') #
time = "%02d:%02d" % (dt.hour, dt.minute)

and doesn’t need the +1 for the timezone correction.

Is that something i could use in cooperation with the last_triggered or last_changed, so i wont need to add +1?

Then the python_script component is what’s using exec().

You don’t have access to what you need in order to not use the +1, hence this error you posted earlier:

im not alone…:

https://github.com/home-assistant/home-assistant/issues/13396 @anon43302295

I’ve just noticed this:
correct time:

filtering the attributes changes that:

amazing…still, glad to see the correct time is in there somewhere…

Yes, thats the datetime object you are accessing when you call last_triggered

ofcourse, but see the time attributes. why is it correct in the fist shot, and when accessing the attributes, suddenly take s the utc time…

The first shot is a custom string formatted for the user, the second two images are showing you exactly what they are as objects.

I think you just need to add a feature request and call it a day. I think you are beating a dead horse at this point. In a custom_script, you cannot get your current time zone time. You either need to move to a component, or appdaemon so you can properly get all the calls you need.

The reason they use UTC under the hood is because they have users all over the world. They will never change this. In yaml, they convert it to your time zone. In the custom_script they don’t because you are accessing their object.

Why am i telling you this? Because when you make a feature request, you need to ask for a custom_script enhancement that allows you to convert to your timezone, because they will never change their object because it would break for other users.

1 Like

fear you’re complete right…

i have one little bit of hope:

ive changed my script to read like this now:

for entity_id in hass.states.get(lights_group).attributes['entity_id']:
#    dt = hass.states.get('automation.sense_lights_change').attributes.get('last_triggered')
#    dt = dt + datetime.timedelta(hours=+1)
#    time = '%02d:%02d' % (dt.hour, dt.minute)

    if hass.states.get(entity_id).state is 'on': #and entity_id not in excluded
        lights_on.append(hass.states.get(entity_id).attributes["friendly_name"])
        state = hass.states.get(entity_id)

        dt = state.last_changed
        dt = dt + datetime.timedelta(hours=+1)
        time = "%02d:%02d" % (dt.hour, dt.minute)

thus reading the last changed of the individual entities, rather than the triggered status of the automation. Error is gone…

only thing is, it doesn’t read the state for no lights on.
Trying this algorithm in an else : statement below this section doesn’t work. Would you be willing to help me one final time…

how to make the script take the time when the state.lights_group.state goes from on to off (any light on to no lights on) and read that last_changed and set it to the time…

my effort:

else:
    state = hass.states.get(lights_group)
    dt = state.last_changed
    dt = dt + datetime.timedelta(hours=+1)
    time = "%02d:%02d" % (dt.hour, dt.minute)

will have to see if this catches all scenarios.

just thought you might be interested in something I overlooked, thanks to @arsaboo ive managed to finally get rid of a lot of errors in the logging :

no errors seen since…(yet, #fingerscrossed)

I’m confused, his solution is exactly the same as what you’ve had…

you had:

dt = dt + datetime.timedelta(hours=+1)

and now you are using:

dt = dt + datetime.timedelta(hours = 1)

those are identical aside from the + sign, which does nothing in the top line.

so am I…

still, havent seen the errors since.
Only thing bugging now is the fact some of the entities aren’t populated at startup, leading to several Nonetype’s.
And the still existing issue of the daytime and daylight savings (have hours=2) at the moment…

Hello since the hassio 0.95 update one of my python script (from maattdiy(https://github.com/maattdiy) is not working with this error in the log:

Error executing script: %d format: a number is required, not NoneType
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/python_script/__init__.py", line 159, in execute
    exec(compiled.code, restricted_globals, local)
  File "summary.py", line 174, in <module>
TypeError: %d format: a number is required, not NoneType

The line it refers on my .py file is this one:

    time = "%02d:%02d" % (dt.hour, dt.minute)

Do you guys have an idea ?

Thanks.