This repository has been archived by the owner on Feb 16, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
shippingHandling.py
139 lines (120 loc) · 5.15 KB
/
shippingHandling.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# Copyright 2020 Linus S.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Part of the Communications skill to receive messages and messagebus them over to the skill, which announces them"""
import time
from mycroft.messagebus.send import send
from zeroconf import ServiceInfo, Zeroconf, ServiceBrowser
import ipaddress
from ifaddr import get_adapters
import json
def send_communication_to_messagebus(msg_type, msg: dict):
send("skill.communications.{}".format(msg_type), msg)
def get_ip():
ignore_list = ['lo', "lo0"]
res = {}
for iface in get_adapters():
# ignore "lo" (the local loopback)
if iface.ips and iface.name not in ignore_list:
for addr in iface.ips:
if addr.is_IPv4:
res[iface.nice_name] = addr.ip
break
if res.get("wlan"):
return res.get("wlan")
elif res.get("en0"):
return res.get("en0")
elif res.get("eth0"):
return res.get("eth0")
else:
# We don't know which one. Return the first one.
return list(res.values())[0]
def start_receiving_Loop(socket, mycroft_id):
# Start the forever loop
while True:
time.sleep(1)
msg = socket.recv()
if msg is not None:
action = json.loads(str(msg.packets[1]))["action"]
recipient = json.loads(str(msg.packets[1]))["recipients"]
# Only react to message if is to me
if recipient == "all" or recipient == mycroft_id:
data = json.loads(str(msg.packets[1]))["data"]
sender = json.loads(str(msg.packets[1]))["sender"]["mycroft_name"]
sender_id = json.loads(str(msg.packets[1]))["sender"]["mycroft_id"]
if action == "intercom" or "message":
send_communication_to_messagebus("message",
{"data": data, "sender_name": sender, "sender_id": sender_id,
"action": action})
# Do more handling here
else:
pass
def start_advertisement_loop(name, uuid, description):
"""Start advertising to other devices about the ip address"""
# Get the local ip address
ip = get_ip()
info = ServiceInfo(
"_http._tcp.local.",
"Mycroft Communications Skill - {}._http._tcp.local.".format(name),
addresses=[ipaddress.ip_address(ip).packed],
port=4444,
properties={"type": "mycroft_device", "uuid": uuid, "name": name, "description": description},
)
zeroconf = Zeroconf()
# Registering service
zeroconf.register_service(info)
try:
while True:
time.sleep(0.1)
finally:
# Unregister service for whatever reason
zeroconf.unregister_service(info)
zeroconf.close()
class MycroftAdvertisementListener:
def remove_service(self, zeroconf, type, name):
# Remove the device from available devices
pass
def add_service(self, zeroconf, service_type, name):
info = zeroconf.get_service_info(service_type, name)
if bool(info.properties) and b"type" in info.properties and info.properties.get(b'type') == b"mycroft_device":
# Get ip address
name = info.properties.get(b"name").decode()
ip = str(ipaddress.ip_address(info.addresses[0]))
description = info.properties.get(b"description").decode()
uuid = info.properties.get(b"uuid").decode()
send_communication_to_messagebus("device.new",
{"ip": ip, "name": name, "uuid": uuid, "description": description})
def start_new_service_listener_loop(sock):
"""Respond to new services: add them to the database"""
global socket
socket = sock
zeroconf = Zeroconf()
listener = MycroftAdvertisementListener()
browser = ServiceBrowser(zeroconf, "_http._tcp.local.", listener)
try:
while True:
pass
finally:
zeroconf.close()
def send_message(socket, message, message_type, mycroft_id, mycroft_name, recipient="all"):
"""
Args: TYPE and Message and WHO FOR (Needed if not intercom"""
if message_type is not "intercom" and recipient is None:
# Check that when there is a message, it has a specified recipient
raise ValueError("[communicationsSkill/shippingHandling] To send a message, you need to specify a recipient")
message = {"action": message_type, "recipients": recipient, "data": message,
"sender": {"mycroft_id": mycroft_id,
"mycroft_name": mycroft_name}}
time.sleep(1)
socket.send(str(json.dumps(message)))