-
Notifications
You must be signed in to change notification settings - Fork 58
-
Hello :)
I am just starting and encountering issue when working on jupyter with the hass pyscript kernel.
I am wondering if this is a limit off hass python, pyscript, or me being a newbe.
With this simplifed exemple:
class BaseMessage:
@classmethod
def print_value(cls, value):
print(value)
toto=BaseMessage()
toto.print_value("titi")
On my python, i get at the output
titi
but using hass pyscript kernel i get the following error
Exception in <jupyter_3> line 8:
toto.print_value("titi")
^
TypeError: 'EvalFunc' object is not callable
Did i miss a limitation ? I am running the latest stable HASS from there docker repo in a development environment.
Thank you !
EDIT:
Just to be sure i tried the same command in the hass docker python, it does work.
So it's something else and i have no idea how that kernel thing work
Beta Was this translation helpful? Give feedback.
All reactions
In this particular case, I believe it's subclassing that isn't working.
As a whole, I'm really not sure. Subclassing, passing methods or classes created in pyscript to native python modules, and the use of non-pyscript decorators are issues I've run in to myself. But I don't know if a full list has been made.
In short, the solution is, keep your pyscript code to very simple classes and methods. For everything else, use native python modules of @pyscript_compile
. It just means you have to separate the logic between what talks to HASS and what doesn't, since anything in @pyscript_compile
won't be able to use pyscript functionality.
Replies: 2 comments 2 replies
-
pyscript is Python, but there are some language limitations; features that are not available. In short, almost everything in pyscript (classes, functions, class methods, etc) are turned into classes internally. This makes, for one, using non-pyscript decorators difficult.
The easiest way around this is to use the @pyscript_compile
decorator.
I have not tested this, but I believe this will work in your case:
@pyscript_compile def makeBaseMessage(): class BaseMessage: @classmethod def print_value(cls, value): print(value) return BaseMessage BaseMessage = makeBaseMessage() toto=BaseMessage() toto.print_value("titi")
Beta Was this translation helpful? Give feedback.
All reactions
-
Thank you for the feedback :)
Sadly it look like your solution is breaking other thing, for example pyscript function don't seam to work in the class (a log.debug return that log is undef). So no way to run hass task or trigger latter.
I am also having other issue, like subclass not registering themself (i tried to remove all decorators)
Here is what I've started to work on. Could you clarify what will not work (as a hole and not just in this example) for me ? That way i can restart from 0, but with a good idea of what to avoid.
app_config = pyscript.config['apps']['my_app1'] class Device: device_classes = {} def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) cls.device_classes[cls._DEVICE_TYPE] = cls def __get_device_config(self, device_name): try: device_config = app_config["device"][device_name] log.debug(f"retrived config for device {device_name}: {device_config}") return(device_config) except(KeyError): log.error(f"{device_name} is not present in the config file") return(False) def set_type(self): if self.config["type"] not in self.device_classes: raise ValueError('Bad device type {}'.format(self.config["type"])) return self.device_classes[self.config["type"]](self.device_name) def __init__(self, device_name): self.device_name=device_name print(f"creating {device_name}") self.config = self.__get_device_config(self.device_name) def is_available(self): raise NotImplementedError def turn_on(self): raise NotImplementedError def notify(self): raise NotImplementedError class Android_app_device(Device): _DEVICE_TYPE = 'android_app' def turn_on(self): log.debug("android device can't be turned on") return(True) def is_available(self): log.debug("android device availability can't be checked") return(True) def notify(self, message, title=None, data={}, tag=None, color=None, sticky=None, channel=None, importance=None, persistent=None, timeout=None): if tag: data["tag"] = tag if color: data["color"] = color data["ledColor"] = color if sticky: data["sticky"] = bool(sticky) if persistent: data["persistent"] = bool(persistent) if timeout: data["timeout"] = timeout if channel: data["channel"] = channel if importance: data["importance"] = importance log.debug({"title": title, "message": message, "data": data}) def clear_notify(self, tag): log.debug(f"clearing notification taged {tag}") self.notify(message="clear_notification", tag=tag) def remove_channel(self, channel): log.debug(f"removing channel named {channel}") self.notify(message="remove_channel", channel=channel) def tts_notify(self, message): log.debug(f"sending \"{message}\" in TTS") self.notify(message="TTS", title=message, channel="alarm_stream_max") x=Device('galaxys4') print(x.device_classes) > creating galaxys4 > retrived config for device galaxys4: {'notify_service': 'notify.mobile_app_gt_i9505', 'type': 'android_app', 'status_check': None, 'turn_on': None} > {} x=x.set_type() > ValueError: Bad device type android_app
But with raw python
x=Device('galaxys4') print(x.device_classes) x=x.set_type() x.turn_on() > creating galaxys4 > debug: retrived config for device galaxys4: {'notify_service': 'notify.mobile_app_gt_i9505', 'type': 'android_app', 'status_check': None, 'turn_on': None} > {'android_app': <class '__main__.Android_app_device'>} > creating galaxys4 > debug: retrived config for device galaxys4: {'notify_service': 'notify.mobile_app_gt_i9505', 'type': 'android_app', > 'status_check': None, 'turn_on': None} > debug: android device can't be turned on > True
Beta Was this translation helpful? Give feedback.
All reactions
-
In this particular case, I believe it's subclassing that isn't working.
As a whole, I'm really not sure. Subclassing, passing methods or classes created in pyscript to native python modules, and the use of non-pyscript decorators are issues I've run in to myself. But I don't know if a full list has been made.
In short, the solution is, keep your pyscript code to very simple classes and methods. For everything else, use native python modules of @pyscript_compile
. It just means you have to separate the logic between what talks to HASS and what doesn't, since anything in @pyscript_compile
won't be able to use pyscript functionality.
Beta Was this translation helpful? Give feedback.
All reactions
-
i tend to overcomplicate thing i don't master, so that will keep me in check :D
Thank you for sharing some of your knowledge on this, i will work around those limit and make my centralized notification another way ;D
Cheers !
Beta Was this translation helpful? Give feedback.