Own skill not working

Hi,

I’m really desperated.

I am practicing Python and wanna create an own skill.
This skill should access to a Nextcloud Calender. I should do prompts and new entries etc.

I create a new skill with the template mycroft-msk create and initially it works. I can make promts etc. but whenever I modify my __init__.py and try to extend it, the prompts are not working anymore.

For now I have just this snippet here

``` `` `

from mycroft import MycroftSkill, intent_file_handler
import caldav
from caldav.elements import dav

caldav_url = 'url'

class SiCalender(MycroftSkill):
    def __init__(self):
        MycroftSkill.__init__(self)
     
    def initialize(self):
        self._username = str(self.settings.get("username"))
        self._password = str(self.settings.get("password"))
        # open connection to calendar
        client = caldav.DAVClient(url=caldav_url, username=self._username, password=self._password)
        principal = client.principal()
        # get all available calendars (for this user)
        calendars = principal.calendars()
        for c in calendars:
                self.log.info('got calendar {}'.format(c.name))  

    @intent_file_handler('calender.si.intent')
    def handle_calender_si(self, message):
        self.speak_dialog('calender.si')


def create_skill():
    return SiCalender()

```````` `` `
Whenever I add the initialize the skill does not work anymore…
What am I doing wrong?

Here is my github repo
Repo

i think you have to add additional steps between the Principal object creation and calling calendars() on em, because it would return self.calendar_home_set.calendars() and self.calendar_home_set is None after initialisation - and is from what i can gather not set subsequently. This should causing the problem.

Hey,

I think whenever I try to modify the __init__.py the skill is not working anymore and I have to delete it and create a new one…

Now I try to get the username and password which can be set in the settings.

class SiCalender(MycroftSkill):
    def __init__(self):
        MycroftSkill.__init__(self)
        
    def initialize(self):
        self.register_entity_file('when.entity')
                
        self.setting_change_callback = self.on_websettings_changed
        self.on_websettings_changed()
        
    def on_websettings_changed(self):
        self.log.info('Collecting login information')

        self.user = self.settings.get('username')
        if not self.user:
            self.log.info('Failed to retrieve username')

        self.password = self.settings.get('password')
        if not self.password:
            self.log.info('failed to retrieve password')

        self.log.info('Completed login information retrieval attempt')

    @intent_file_handler('calender.si.intent')
    def handle_calender_si(self, message):
        self.speak_dialog('calender.si')


def create_skill():
    return SiCalender()

But this snippet seems also not working.
I don’t get it :frowning:

With not working I mean, I cannot even do a prompt like “What is my next appointment” MyCroft is supposed to answer “No appointments today” for now but always reply “I don’t understand” etc.

there is no entity file (at least on github) - and therefor the skill wont load

Ah okay…

Alright then I modified again and put it simple:

class SiCalender(MycroftSkill):
    def __init__(self):
        MycroftSkill.__init__(self)
        
        self.log.info('Collecting login information')

        self.user = self.settings.get('username')
        if not self.user:
            self.log.info('Failed to retrieve username')

        self.password = self.settings.get('password')
        if not self.password:
            self.log.info('failed to retrieve password')
            

    @intent_file_handler('calender.si.intent')
    def handle_calender_si(self, message):
        self.speak_dialog('calender.si')


def create_skill():
    return SiCalender()

Also did not work. Always answer that he cannot understand me.
But when I create a skill from template it worked…
I uninstalled that skill and reinstalled again and it is my skill folder on the pi but not on the skill settings on mycroft home for some reason…
But when I create a new skill from template the skill appears in the home but uninstalling and installing again with mycroft-msm install skill it doesn’t appear…

this wouldn’t work since MycroftSkill isn’t fully constructed at this point (at least a would imagine that) → initialize

Still after put it into initialize

class SiCalender(MycroftSkill):
    def __init__(self):
        MycroftSkill.__init__(self)
        
        
    def initialize(self):
        self.log.info('Collecting login information')

        self.user = self.settings.get('username')
        if not self.user:
            self.log.info('Failed to retrieve username')

        self.password = self.settings.get('password')
        if not self.password:
            self.log.info('failed to retrieve password')
            

    @intent_file_handler('calender.si.intent')
    def handle_calender_si(self, message):
        self.speak_dialog('calender.si')


def create_skill():
    return SiCalender()

not working.
Uninstall and install skill again and it doesn’t appear on my skill settings @ home… Dunno why

but when create a new skill with template mycroft-msk createit does appear. This is ridiculous.

Okay I found out that the error might be of the import caldav but I already installed with mycroft-pip install caldav and also with pip install caldav

I will fork the skill, get it running and PR the result. Good time to juice the reminder skill with some dav functionality

The skeleton skill is working, if you toss everything caldav related.

i’m struggling with ssl. requests is excepting because my ssl cert is expired (allthough it’s not) - most likely the expiration of the CAcertificate (LetsEncrypt resp. IdenTrust). certifi is the package handling that in given context. (Docker/npm issue)

Furthermore config.php (nextcloud) would need an trusted_domain addition (if the IP calling from is not allready listed)

edit: i’m unclear if the url you want to call is wrong. It might be that you have to call ../remote.php/dav/calendars/< user >/

Hi thanks for your help!

Did the skill works for you? I mean when you just do the import caldav it is still working?

What do you mean need an trusted_domain addition?

I found out that this might be the url:

url = "https://" + username + ":" + password + "@https://cloud.mi.hdm-stuttgart.de/remote.php/dav"

yeah, just want to update that the skill is working with the code on github as is.

With the slight difference that i don’t use the webend to store and retrieve the settings - but that is not the issue (you don’t need to str() the settings btw). And i tossed the caldav.elements import.

Due to the fact that i use (homebrew) SSL i pass the param ssl_verify_cert="/path/to/ca.pem"

so calendars would be [Calendar(https://.../remote.php/dav/calendars/<redacted>/personal/)] in my case (only have the default calendar)

This could mean, that one of the above mentioned problems occur.

  • SSL (verify resp. verify_ssl_cert is True by default),
  • Nextcloud not trusting the IP/host → trusted_domains

You might want to check /var/log/mycroft/skills.log. I would expect exceptions during startup.

DAVClient is handling this, so you can stay with the former expression (without knowing if DAVClient is able to obectify the url as quoted above)

On a general note, i wouldn’t use the web backend settings for sensitive information. (saw the credentials.py btw) You might want to look into using OAuth described here. This skill is worth a peek for oauth implementation. (concerning access token/user agent mycroft wise)
But i’m unclear about the “redirect uri” from nextcloud tbh.

depending on your webserver setup there should be a config file at /var/www/html/nextcloud/config/config.php. A host/ip declaration in trusted_domains is needed to be able to connect.

And not be able to connect would equate to an exception, ie skill wont load (you might want to use try: except: here; and self.speak_dialog("not_connected") if that happens - just to get some audio feedback)

if you want the error to be spoken

except Exception as e:
    error = str(e)
    self.speak_dialog('not_connected',
                       data={"error": error})

with not_connected.dialog (in locale)
“Nicht verbunden. Grund {error}”

Yet, the error can be darn long :wink:

You need the package icalendar and/or vobject to access the subcomponents of the ics

so manifest.yml would be

dependencies:
   # Pip dependencies on PyPI
   python:
     - caldav
     - icalendar
#     - vobject # one can choose between icalendar and vobject - instance

Hi thanks for your help!

You might want to check /var/log/mycroft/skills.log. I would expect exceptions during startup.

How can I check the skills.log?
I am not so familar with Linux and opened the file with vim but I think this is not a good way to check log files…

depending on your webserver setup there should be a config file at /var/www/html/nextcloud/config/config.php. A host/ip declaration in trusted_domains is needed to be able to connect.

I see! The webserver is hosted from my univ, so I can’t change anything there :frowning:

So when an import is not correctly loaded or when there is an exception the whole skill is not working, right?

Do you know the admin? Better person to ask than some guy who is bruteforcing his way through everything network related :wink:

hdm-stuttgart. realized that. That is why i mentioned Oauth. I would guess an authorisation method like this is more appreciated(?) by the admins than ping-ponging the credentials back and forth. Again, the admin would be the right guy to ask.

You can go all in with one of those but i didn’t felt the need (until now - damn you). Talking Mycroft-native stuff, there are a few commands using mycroft-cli-client like :find 'Exception' but this is mostly real-time (i wouldn’t know how long you can stretch the period pre startup with :history #lines ; maybe @gez-mycroft can jump in)

If you are looking at the gcalendar skill, Ake has set an event in init. If this event (that calls the relevant method) throws an exception, the skill (in general) wouldn’t care much - besides not doing what it’s told. But i wouldn’t miss try/except those exceptions because it gives an opportunity to get some audio feedback.

I cobble together an implementation for my reminder skill as we speak and send you the git link if you like.
With the reminder skill i’m going a similar route with handling the dav calendars (pulling the events and saveing the new ones locally) when the skill regularly checks the reminders.

Yeah I could ask the admin.
But I thought it is a valid method to save the credentials in the backend (home mycroft) and fetch it with settings.get .

If this event (that calls the relevant method) throws an exception, the skill (in general) wouldn’t care much - besides not doing what it’s told

Hmm I see. But then I still don’t understand why my skill wasn’t working when I did the import caldav


> I cobble together an implementation for my reminder skill as we speak and send you the git link if you like.

Ah yes please, that would be nice!
I want to implement basic actions like asking mycroft “what are my appointments for today, what is my next appointment”,
Creating new appointments for day X, deleting appoinments.
I think it is not difficult but I am having trouble already with the connection of the calendar…

its not the local storage that is problematic, more requesting the server with username:password. (and not being a intranet/local network call)

That wasn’t the cause, but using the import in initialize (by creating an calendar object - that was somehow bugging out) - but we still not know if/where/why the exception happend


Creating ical data from a mycroft reminder or some other input for that matter isn’t that straight forward - at least not with caldav 0.8.2(latest). You need to work with Event /Calendar class from icalendar. Otherwise you would have to string it together (which is impractical).

Got it to push the new reminder to the server. I even see the PUT request with a 201 response (Created) but nothing appears on the personal calendar. The other way around is no problem. I’ll look tomorrow what’s up with that. Maybe some crucial subcomponent is missing

edit: got it. Nextcloud has no clue what to do with VALARM (the prenotify component). I guess the timedelta data threw em off. Yet, i could retrieve the event that wasn’t shown :stuck_out_tongue:

That wasn’t the cause, but using the import in initialize (by creating an calendar object - that was somehow bugging out) - but we still not know if/where/why the exception happend

I see.
Could you help me with what you did so that the skill is running?

I guess you have to help me first and look in skills.log what is going on. (And i would think the solution is not skill related but Nextcloud config related, or if it is SSL then it’s Linux related)