Creating my first skill with essentially no experience - Mycroft MagicMirror skill

the response object json member is a method returning the json as a dict (and not a json object).

so you should definitely use

data = r.json()

with this change it should work, though I’m not sure why you’re dumping to file here?

2 Likes

@forslund Thanks! I did make the change to data = r.json() last night after doing a little more research on google. And you are right, there is really no need to dump to a file at that point. All that is really needed is to pass that information to AvailableModulesWithIdentifier.json which works with no issue.

I did dump the AvailableModulesWithIdentifier.json in the def initialize(self): into the skill/Magic-Mirror-Voice-Control-skill/ folder and it caused something that I didn’t expect. The skill was continually being loaded by mycroft. I assume that when a change is made to the skill, mycroft reloads it. Because I dump the file in the def initialize(self): it would save the file every time the skill is loaded. I think this created a loop.

When I don’t specify a path to write the file:

with open ('AvailableModulesWithIdentifier.json', 'w') as f: json.dump(AvailableData, f, indent = 2)

It puts the file in the Mycroft-core folder, which is not what I want to do.

So my next thought is “do I really need to write the file?” And again, this may just be my inexperience, but I ran into an issue with creating a variable in the def initialize(self):

url = 'http://localhost:8080/remote'

that the intents said was not defined. So I added the variable to each intent. My thinking with the AvailableModulesWithIdentifier.json was that if I write the file, it can be called by any intent at any time.

The good news is that the skill works mostly. There are a couple of intents I need to work on. Specifically the intents that use the word form of numbers like the PagesIntent and the AdjustBrightnessIntent.

With the PagesIntent for example when I type “go to page three” in the cli, it doesn’t recognize the keywords and activate the intent, instead it goes to the fallback.

With the AdjustBrightnessIntent the same thing happens when I type “set brightness to one hundred”, but when I type “set brightness to 100” the intent is recognized and works perfectly. The reason I have included the word form of the numbers in the appropriate .voc file is that occasionally mycroft recognizes the utterance “set brightness to 100” as “set brightness to one hundred” and I wanted to be thorough.

I know I have probably worn you out with all my questions. I do appreciate all your help.

I will continue to research these answers on my own, but if you have any advice, I would gladly take it.

Thanks a million for all of your advice!

1 Like

You can make it available everywhere by tying it to the object

self.url = 'http://localhost:8080/remote'

when you access it you use self.url.

If you want to store in a neutral location there’s a self.filesystem.path member that point to a sandbox for the skill. I’ve used it for savegames in my zork-skill

The thing you mention is the skill reloader function, as soon as there is a write in the skill folder mycroft reloads the skill.

@forslund would that work for a variable with the AvailableModulesWithIdentifier.Json data?

For example self.moduledata = availablemoduleswithidentifier

Also any thoughts on the Intents using words as numbers like “one hundred”?

@forslund I just wanted to thank you again. Your advice has been invaluable. The Magic-Mirror-Voice-Control-skill is now fully functioning thanks to your advice.

I switched to the self.url = “http://localhost:8080/remote” and removed the now un-needed url variable in every intent. I also followed your advice and saved the AvailableModulesWithIdentifier.json by using the code:

 with open (join(self.file_system.path, 'AvailableModulesWithIdentifier.json'), 'w') as f:
        json.dump(AvailableData, f, indent = 2)

and call it when needed from the intents like:

with open (join(self.file_system.path, 'AvailableModulesWithIdentifier.json')) as f:
        data = json.load(f)

Also the issue with the words as numbers (example: one hundred) was not the real issue with the PagesIntent. It turns out that changing the PageActionKeywords.voc file to read:
go to page
show page
display page
reveal page

as opposed to
go to
show
display
reaveal

and then changing the PageKeywords,voc from:
page one
page 1
page two
page 2
etc.

to:
one
1
two
2
etc.

Made all the difference in the skill being recognized by mycroft. I’m guessing that it may have been causing a conflict having the moduleKeywords.voc and the PageKeywords.voc being too similar.

There are additional things I’d like to add to this skill in the future:
Having a sort of debug feature that displays what mycroft is doing on the mirror.
Kind of like a cli, but less detailed. maybe a motion graphic with the utterances and mycroft’s replies to them in text below the motion graphic

Anyway, I think this skill is nearly ready for submission. I’ll clean up the readme and go through the skill looking for excess files, updating the commenting, etc.

Then I’ll submit.

Thank you again!

2 Likes

I don’t suppose you’d like to do a video demo? I’m sure our community would absolutely love to see Magic Mirror for Mycroft (Magic Myrror?) in action!

1 Like

@KathyReid I planned to do a video. The hardware for the Mirror is not complete. I have been focusing on developing the skill first. I can do a video showing Mycroft controlling the various modules via vnc at this point.

The skill requires that the MagicMirror developed by Michael Teeuw be installed on the same Raspberry Pi as Mycroft. It also requires the MMM-Remote-Control module for MagicMirror be installed and working properly.

The way the skill works is it sends a requests.get to the MMM-Remote-Control module. I am still having issues with the MMM-Remote-Control module being accessed from my network. That’s why it requires they both be installed on the same Raspberry Pi at this point. It is a work in progress, but once I resolve the issue with accessing the MMM-Remote-Control on my network, I can foresee being able to create a config entry for Mycroft pointing to the MagicMirror’s ip address to allow users to have them on seperate Pi’s if they prefer. That way any Mycroft (Mark 1, Mark 2 when it comes out, Picroft, etc.) would be able to control the Mirror. That’s on my TODO list. For me though, my intention is to build a stand alone mirror with Mycroft so having them on the same Pi is not an issue for me.

This thread can serve as a blueprint for anyone else wanting to build the same project. In fact, I thought about writing a blog about this whole experience. It’s been frustrating at times, but a really fun hobby for me. I would not have been able to do it without your help, and the help of @forslund . You’ve both been so helpful and I really appreciate it.

I need to finish the skill submission process. I think I left a step or two out because it didn’t work like it is supposed to. I’ll try it again tonight.

Cheers!

1 Like

Thanks so much @dmwilsonkc - we think - no pun intended - your Skill is magical :joy:

1 Like

@KathyReid @forslund Here’s a short video of the magic-mirror-voice-control-skill in action. I submitted the skill, correctly this time I think. The auto-tester failed it however I’m not sure why.

4 Likes

HUGE thanks, @dmwilsonkc ! @forslund and I can take a look at the submission.
Again, many thanks.

1 Like

This is absolutely awesome. Let me know if you put together that blog post, we’d love to share it around, along with the demo video and any updates.

2 Likes

@KathyReid Have either you or @forslund had a chance to look at my PR for the magic-mirror-voice-control-skill? I don’t understand why it failed the automatic skill tester. Everything works perfectly on my end. And I thought I set up the sample#.intent.json files properly. Let me know what you think when you have a chance to look at it.

Thanks!

Will do, we’re a bit backlogged on the Skill testing at the moment.

@KathyReid I understand. No worries, just let me know if there is something else I need to do when you catch-up and have a chance to look at it.

Thanks!

I did a quick check of it right now and it seems like the skill can’t start without the magic mirror available.

It tries to connect but fails and errors out. It might require manual testing in it’s present form.

1 Like

@forslund That does make sense. In the def initialize(self) the first step it takes is to get the module_data from the MagicMirror. Without that step, Mycroft would not “know” how to send the proper commands to the mirror. As you can see from the video the skill works perfectly when all the requirements have been met.

So what’s my next step?

Should I add some error handling to the skill to tell the user there is a problem connecting to their Mirror?

That’s probably a good idea. @KathyReid might know more of how the skills that can’t run without external components will be tested and what you’d need to do.

1 Like

Thanks for flagging @forslund.

The Skills Team have been working through these sorts of cases this week actually.

If the Magic Mirror has to be manually installed and cannot be installed using requirements.txt or requirements.sh then we have the ability to flag the need for passing Skills Tests to be overridden to merge the PR. We as that you upload the Skills Tester output as a comment in the PR so we can review.

The second piece is - “has anyone else been able to validate this work” - where a Skill cannot be tested automatically because it requires some external dependencies that are not met easily - like installing Magic Mirror - we usually require that at least one other person has validated the Skill before we merge it.

I think the next step here is to request community assistance in getting this tested - sound reasonable?

@KathyReid That sounds perfectly reasonable to me. There’s no way to automatically install everything. The first thing I installed on the RPi 3b was the Rasbpian Jesse (not lite) image with the pixel desktop listed in my first post. Then the MagicMirror, then a couple of modules including the MMM-Remote-Control module. Each module requires an entry in the MagicMirror’s config.js file that is typically done manually (there may be another way, but if there is, I haven’t found it). Then install mycroft-core. I installed from the Master branch, but I believe the dev branch would work as well.

The biggest issue now is that everything must be installed on the same RPi, the skill will not work otherwise. I realize that configuration is not ideal.

Maybe the best course of action would be to figure out how to access the MMM-Remote-Control module via my network and add some configuration or better yet allow a user to tell Mycroft by voice what the ip of their mirror is. Then store the ip and use that. Of course, I would also need to write in some error handling for occasions when the mirror is not accessible or its ip has changed. Then any Mycroft, a Mark 1, a Mark 2 (when they come out), a Picroft, or some other version could use the skill. I hate to say it, but maybe not adding it to the skills repo, or adding it with very clear instructions for now, would be best.

It works perfectly well on my setup as it is. I would hate to not share it for someone willing to put in the time to match what I have done at this point. But if someone really needs it now, they can always get it at my repo.

What are your thoughts?

Good points, @dmwilsonkc.

Although the installation is not straightforward, and can’t be achieved using just requirements.sh or requirements.txt, it’s likely that if you’re at the point of building a Magic Mirror type project, then you’re likely to be OK with the building process and its manual nature.

The other alternative I see here is to make an image of the RPi with Magic Mirror and mycroft-core installed, but that’s a lot of work.