Communications Skill - Intercom using Mycroft!

Link to GitHub: GitHub - LinusSkucas/communications-skill: An intercom, messaging, and (video) calling skill for Mycroft!

Hi all, I’ve started with a communications skill, one that will (soon) be able to let Mycrofts on the same network call, message and (video) chat with each other. Today, I’ve released a first version of that skill that auto connects to other Mycrofts on the network and then can be used for an intercom.

When you install the skill on your devices on the network, the Mycrofts then start advertising themselves, and find each other (using zeroconf). After they find each other they all connect forming a peer to peer/mesh network. This is all done without you needing to type in addresses/ip of other Mycrofts.

After they are connected (which takes 1-2 seconds, on my network), you can then say,

Announce dinner’s ready

After that, all the Mycrofts that the skill is installed on will make a blinging noise and announce what you said.

To install the skill run:
msm install https://github.com/LinusS1/communications-skill.git

After you’ve run that on all your devices, you can try the skill out!

Testing

Wait a few minutes for the devices to find each other, after you install the skill, then say “announce Good Morning!”

Then, all your devices should say good morning (except the one that you asked).

What needs to be tested is if this skill works well on the Mark 1, and whether it works reliably with 3 Mycroft devices.

If you have any trouble, feedback, or success, please post it here!

This is just a beginning: I’m going to be adding chatting and calling over the coming weeks, and once the Mark 2 is released: Video calling. After that, I hope to connect it to different services, such a Skype. Stay Tuned :smile:

7 Likes

AMAZING !!!

Job well done.

Probably way to soon, but… Here is an idea. As you are using “zeroconf” for device discovery and Home Assistant also using “zeroconf” for device discovery, maybe somewhere in the future we (as in someone in the community) can have a look into hooking this into Home Assistant, making HASS also auto discover your Mycroft instances and configuring them auto-magically within Home Assistant.

Anyway: I have something to play around with this weekend.

Thanks!

3 Likes

I was able to install the skill but got the following error on one of my raspberry.

Exception in thread Thread-58:
Traceback (most recent call last):
File “/usr/lib/python3.5/threading.py”, line 914, in _bootstrap_inner
self.run()
File “/usr/lib/python3.5/threading.py”, line 862, in run
self._target(*self._args, **self._kwargs)
File “/opt/mycroft/skills/communications-skill/shippingHandling.py”, line 54, in start_advertisement_loop
ip = netifaces.ifaddresses(“wlan0”).get(netifaces.AF_INET)[0].get(“addr”)
TypeError: ‘NoneType’ object is not subscriptable

Thanks!

Installed it on a Mark-I (Debian Jessie) and a Picroft (Debian Stretch) both Mycroft 19.2.13.

  1. Skill initialization fails with following error:
08:36:45.826 - mycroft.skills.core:load_skill:151 - INFO - Loaded mycroft-wiki.mycroftai
~~~~FO - ATTEMPTING TO LOAD SKILL: communications-skill.linuss1 with ID communications-skill.linuss1
~~~~ mycroft.skills.core:load_skill:169 - ERROR - Failed to load skill: communications-skill.linuss1
Traceback (most recent call last):
  File "/home/pi/mycroft-core/mycroft/skills/core.py", line 131, in load_skill
    imp.PY_SOURCE))
  File "/usr/lib/python3.5/imp.py", line 234, in load_module
    return load_source(name, filename, file)
  File "/usr/lib/python3.5/imp.py", line 172, in load_source
    module = _load(spec)
  File "<frozen importlib._bootstrap>", line 693, in _load
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 673, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "/opt/mycroft/skills/communications-skill.linuss1/__init__.py", line 16, in <module>
    import py2p
ImportError: No module named 'py2p'

EDIT: You are missing “py2p” in your manifest.yml. There is a requirement for package “pyp2p” (which is also available on pypi.org) instead - probably a typo?

  1. Manual install of py2p by mycroft-pip install py2p succeeds on the PiCroft, but fails on the Mark-I with error:
Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: 
'/opt/venvs/mycroft-core/lib/python3.4/site-packages/base58.py'
  1. Skill loads successfully on the Picroft but shows message in mycroft-cli:
Exception in thread Thread-51:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.5/threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
~~~~t/skills/communications-skill.linuss1/shippingHandling.py", line 63, in start_advertisement_loop
    properties={"type": "mycroft_device"},
TypeError: __init__() got an unexpected keyword argument 'addresses'
  1. installed py2p on the Mark-I using a bad hack: sudo /opt/venvs/mycroft-core/bin/python3.4 -m pip install py2p. Now skill initialization fails with:
~~~ mycroft.skills.core:load_skill:169 - ERROR - Failed to load skill: communications-skill.linuss1
Traceback (most recent call last):
~~~~/venvs/mycroft-core/lib/python3.4/site-packages/mycroft/skills/core.py", line 131, in load_skill
    imp.PY_SOURCE))
  File "/opt/venvs/mycroft-core/lib/python3.4/imp.py", line 235, in load_module
    return load_source(name, filename, file)
  File "/opt/venvs/mycroft-core/lib/python3.4/imp.py", line 171, in load_source
    module = methods.load()
  File "<frozen importlib._bootstrap>", line 1220, in load
  File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1129, in _exec
  File "<frozen importlib._bootstrap>", line 1471, in exec_module
  File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
  File "/opt/mycroft/skills/communications-skill.linuss1/__init__.py", line 22, in <module>
    from . import shippingHandling
  File "/opt/mycroft/skills/communications-skill.linuss1/shippingHandling.py", line 21, in <module>
    import netifaces
ImportError: No module named 'netifaces'

Thanks for testing my skill!
@gras64 could you please run in the python interpreter:

>>> import netifaces
>>> netifaces.interfaces()

And paste the output here?

I’m looking at the other errors, and will be fixing them soon.

1 Like

i get on my Ubuntu Desktop:
[‘lo’, ‘enp1s0’, ‘wlp2s0’, ‘enp0s20u4c4i2’, ‘virbr0’, ‘virbr0-nic’, ‘docker0’] use wlp2s0
on my osmc and pycroft:
[‘lo’, ‘eth0’, ‘wlan0’] use eth0
I have then:
try:
ip = netifaces.ifaddresses(“wlp2s0”).get(netifaces.AF_INET)[0].get(“addr”)

I then adjusted the interface and now get the same problem as Dominik:

got an unexpected keyword argument ‘addresses’

PS:Reaload of the skill generates address are in use
have fun with the fix:)

I too had the same problems. I adjusted the name of the network interface, and then also changed “addresses” to just “address” and it seems to load correctly. I am still testing to make sure.

I am currently working on trying to figure out how to get the name of the active network interface to use as a variable instead of hard coding it. Linux is easier than Windows in that respect.

Hello, all

The problem with address vs. addresses is a problem with how dependencies are managed. If you install them in a certain order, the correct version of zero conf will be installed, which allows you to use addresses.

Reloading the skill does cause an error because the web server doesn’t shut down until after. This is a known bug, but it is low priority because end users will not have to deal with it.

Regarding the dependencies installations: This is odd, because manifest.yml should work. However, it’s not installing everything, so I’ll revert to using plain requirements.txt which hopefully should work.

As for the interfaces, it’s really hard to get the correct interface, let alone the correct IP address. I have included support for the normal, most common interface for wifi: wlan0, and if that fails, ethernet, en0 (Ethernet is also hard because there’s like 3 interfaces that refer to different things). It would be hard (I think) to find what interface is currently working because at one time multiple interfaces can be active. Also, an interface can have multiple ip addresses (now I’m selecting the first one, which, from what I’ve heard, seems to be the correct one.)

To solve this issue of interfaces, I suggest that I just create a yaml config file, which allows people to pick the interface they use like wlan0, en0, wlp2s0, or any other crazy, indecipherable interface code/name. The config file would also let users specify ip addresses, in case the incorrect one is being picked up. I feel like this way normal users, who use common devices, won’t have the burden of picking an interface name, or being slowed down, while developers can still use the skill, by just specifying the interface, and maybe ip, and I don’t need to program around tons of edge cases :grinning:

Here’s an example of my envisioned config file - nice and simple:

interface: "en0"
ip: "10.0.1.7"

I’d like to hear what y’all think.
-Linus

Maybe you have a look at the source-code of skill-ip

There are some code fragments that read the current ip from all active interfaces of the Mycroft-Device.

I am not a python guy – but would not
device=os.popen("route -n | sed -n 3p | awk ‘{print $NF}’ ")

work for you to get correct routing device

your ip you could use this

import ipgetter
IP=ipgetter.myip()

the iP skill I find kind of limited for my taste I wish they add public IP to it

i did using ( but there are python ways too)

 /usr/bin/dig  +short [myip.opendns.com](http://myip.opendns.com) @[resolver1.opendns.com](http://resolver1.opendns.com)

You mentioned that your plans include Skype. This is not really in keeping with the open source theme of Mycroft. May I suggest SIP support. There are a huge number of service providers. There are open source libraries for building clients and servers ( user agents in SIP speak ). SIP is what businesses use for their internal phone systems. There are even SIP based “door bells”.

Sorry, I accidentally deleted my last post here it is:

Hello, all

The problem with address vs. addresses is a problem with how dependencies are managed. If you install them in a certain order, the correct version of zero conf will be installed, which allows you to use addresses .

Reloading the skill does cause an error because the web server doesn’t shut down until after. This is a known bug, but it is low priority because end users will not have to deal with it.

Regarding the dependencies installations: This is odd, because manifest.yml should work. However, it’s not installing everything, so I’ll revert to using plain requirements.txt which hopefully should work.

As for the interfaces, it’s really hard to get the correct interface, let alone the correct IP address. I have included support for the normal, most common interface for wifi: wlan0 , and if that fails, ethernet, en0 (Ethernet is also hard because there’s like 3 interfaces that refer to different things). It would be hard (I think) to find what interface is currently working because at one time multiple interfaces can be active. Also, an interface can have multiple ip addresses (now I’m selecting the first one, which, from what I’ve heard, seems to be the correct one.)

To solve this issue of interfaces, I suggest that I just create a yaml config file, which allows people to pick the interface they use like wlan0 , en0 , wlp2s0 , or any other crazy, indecipherable interface code/name. The config file would also let users specify ip addresses, in case the incorrect one is being picked up. I feel like this way normal users, who use common devices, won’t have the burden of picking an interface name, or being slowed down, while developers can still use the skill, by just specifying the interface, and maybe ip, and I don’t need to program around tons of edge cases :grinning:

Here’s an example of my envisioned config file - nice and simple:

interface: "en0"
ip: "10.0.1.7"

@Dominik Thanks, I should have thought of this, I’ll probably barrow some code from there, as it looks promising. If @gras64 could verify that it works (gives him the correct IP address) on his computer using the wlp2s0 interface, I’ll fix that right away!

@krywenko Thanks for the suggestions! I’ll probably just use code from the IP address skill, which also just gets the interface, and allows me to try to keep most the code in python (calling bash scripts from python isn’t exactly what I’d call python :wink:) The ipgetter library seems only to get the public IP address, which isn’t what the skill needs

@Robert_Dyck I used Skype only for an example. I’m purposefully designing the skill so that it can be extended, and once I’m done with calling, I’ll look more into extensions for other ways of communicating, like SIP, Signal or Skype. I’m thinking of making an API and allowing other developers to integrate these platforms directly into the skill. But this is still very much being though out.

no worries as i said I am not python guy- but then again alot of python code is mostly wrapper to the background C executable anyways just doing what I did in in a neater package… with the same result. so is it not programing in python that debatable :wink:

1 Like

Hi @gras64, @krywenko, @Dominik, @builderjer,

I think that I’ve fixed the problems. It turned out that I was installing a totally wrong library (I was installing pyp2p instead of py2p). Also, I’ve upgraded the IP address getting, so hopefully more devices can work immediately with the skill.

To test it again, first remove the old skill:

msm remove communications

Also, uninstall any of the old libraries (if they are needed, the should be installed, when you reinstall the skill):

pip3 uninstall netifaces pyp2p py2p ifaddr zeroconf

Then reinstall it:

msm install https://github.com/linuss1/communications-skill.git

I’m going to go on a trip but, please do post any comments, successes, errors or failures and I’ll get to them when I come back.

Thanks,
Linus

2 Likes

Great, I was able to test successfully. The skill should send to all devices but I could only send to one device although all devices were displayed in the log.

have a beautiful trip

Re-installed on Picroft: works.
Re-installed on Mark-1: fails during initialization with

 - mycroft.skills.core:load_skill:169 - ERROR - Failed to load skill: communications-skill.linuss1
  File "/opt/mycroft/skills/communications-skill.linuss1/__init__.py", line 22, in <module>
  File "/opt/mycroft/skills/communications-skill.linuss1/shippingHandling.py", line 19, in <module>

In that line package ifaddr gets imported. mycroft-pip install ifaddr says that package is already installed. Eventually i did sudo mycroft-pip uninstall ifaddr followed by sudo mycroft-pip install ifaddr

With this i am able to send announce between my Picroft and Mark-1.

HA!!! This skill installed correctly on both an ubuntu machine and picroft. I am also able to communicate between the two. I will continue testing and leave you any feedback.

Thank you for the great skill

Ok, so I connected one more device. Everything installed correctly and was able to see, hear and talk to the other devices as expected. The issue that I see now is it sends multiple times. Does it send to all ip addresses for every ip address that is connected?

With just two devices, everything worked correct. I would announce “here i am” and the client would receive…just one reply “there is a new announcement: here i am”…perfect.

Add another device. I announce “here i am”, and both clients receive the message, but both receive it twice.

Good to hear that its starting to work!
@gras64 could you elaborate when you say you only able to send to one device?
@Dominik Good to hear that installation (kind of) works. ifaddr is installed by default, so I except that won’t be a problem. Just one question can the mark 1 send and receive intercoms? I know that the mark 1 has a firewall, and want to know if that is a problem.
@builderjer I know that this may sound simple, but are you sure your devices can’t hear each other, meaning that when you activate one, it activates the rest, and therefore sends to the rest of the devices?

Thanks for testing this skill!