Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Zeroconf] WebThings are discoverable using mDNS|SD #183

Closed
DazWilkin opened this issue Dec 25, 2020 · 7 comments
Closed

[Zeroconf] WebThings are discoverable using mDNS|SD #183

DazWilkin opened this issue Dec 25, 2020 · 7 comments
Labels
enhancement New feature or request stale

Comments

@DazWilkin
Copy link
Contributor

Is your feature request related to a problem? Please describe.

A side-benefit of the Zeroconf Protocol Implementation is that Zeroconf enables discovery of any device (services) published using mDNS|DNS-SD.

Revisiting the new (!) WebThings (formerly Mozilla's WebThings), I was heartened to discover that WebThings' devices are published using mDNS|DNS-SD described in the Draft spec here

Unfortunately, there's an issue with the Rust SDK but devices written using other SDKs work as expected. Here using avahi-browse to observe a device published using the WebThings Python sample:

avahi-browse --all
+ enp5s0 IPv6 LightAndTempDevice                            _webthing._tcp       local
- enp5s0 IPv6 LightAndTempDevice                            _webthing._tcp       local

Is your feature request related to a way you would like Akri extended? Please describe.

Zeroconf Protocol implementation provides the foundation for discovery of WebThings devices.

Describe the solution you'd like

Zeroconf Protocol implementation provides the foundation for discovery of WebThings devices.

Describe alternatives you've considered

N/A

@DazWilkin
Copy link
Contributor Author

This should now be working for devices developed using any of WebThings SDKs; there was an issue with the Rust SDK that is now resolved.

For example, using the non-TLS example described in the Rust SDK:

cargo run
setting new humidity level: 12.535304069519043
setting new humidity level: 2.093383550643921
setting new humidity level: 14.57203483581543
setting new humidity level: 2.1968395709991455
setting new humidity level: 2.9822685718536377

Then:

avahi-browse --all | grep _webthing._tcp
IPv4 LightAndTempDevice         _webthing._tcp       local

NOTE The WebThings examples creates ThingsType::Multiple(things, "LightAndTempDevice".to_owned())

Add it to your Gateway per the instructions.

The Gateway uses mDNS|SD browsing and should find 2 devices on LightAndTempDevice: My Lamp, My Humidity Sensor

Here's the Lamp:

image

Then, apply the following Akri Zeroconf Configuration to a cluster:

apiVersion: akri.sh/v0
kind: Configuration
metadata:
  name: webthings
spec:
  protocol:
    zeroconf:
      kind: "_webthing._tcp"
      port: 8888
  capacity: 1
  brokerPodSpec:
    containers:
      - name: broker
        image: ghcr.io/deislabs/akri/zeroconf-broker:v1 # This repository does not yet exist
        resources:
          limits:
            "{{PLACEHOLDER}}": "1"

And:

kubectl get configuration
NAME        CAPACITY   AGE
webthings   1          2s

kubectl get instances
NAME               CONFIG      SHARED   NODES    AGE
webthings-d6097c   webthings   true     [akri]   4s

Wait for Akri to create the Broker Pod:

kubectl get instances \
--output=jsonpath="{.items[*].spec.metadata.AKRI_ZEROCONF_DEVICE_NAME}"
LightAndTempDevice

And, lastly:

for INSTANCE in $(kubectl get instances --output=jsonpath="{.items[*].metadata.name}")
do
  POD="pod/akri-${INSTANCE}-pod"
  kubectl logs ${POD}
done
[zeroconf:main] Entered
[zeroconf:new] Entered
[zeroconf:main] Service: kind: _webthing._tcp
name: LightAndTempDevice
host: akri.local
addr: 10.1.1.1
port: 8888
TXTs:
  AKRI_ZEROCONF_DEVICE_PATH: /

[zeroconf:main:loop] Sleep
[zeroconf:main:loop] check_device(Service { kind: "_webthing._tcp", name: "LightAndTempDevice", host: "akri.local", addr: "10.1.1.1", port: 8888, txts: Some({"AKRI_ZEROCONF_DEVICE_PATH": "/"}) })
[zeroconf:read_device] Entered: Service { kind: "_webthing._tcp", name: "LightAndTempDevice", host: "akri.local", addr: "10.1.1.1", port: 8888, txts: Some({"AKRI_ZEROCONF_DEVICE_PATH": "/"}) }
[zeroconf:main:loop] Sleep
[zeroconf:main:loop] check_device(Service { kind: "_webthing._tcp", name: "LightAndTempDevice", host: "akri.local", addr: "10.1.1.1", port: 8888, txts: Some({"AKRI_ZEROCONF_DEVICE_PATH": "/"}) })
[zeroconf:read_device] Entered: Service { kind: "_webthing._tcp", name: "LightAndTempDevice", host: "akri.local", addr: "10.1.1.1", port: 8888, txts: Some({"AKRI_ZEROCONF_DEVICE_PATH": "/"}) }
[zeroconf:main:loop] Sleep

And:

kubectl exec --stdin --tty ${POD} -- env | grep ^AKRI
AKRI_ZEROCONF_DEVICE_NAME=LightAndTempDevice
AKRI_ZEROCONF_DEVICE_KIND=_webthing._tcp
AKRI_ZEROCONF_DEVICE_ADDR=10.1.1.1
AKRI_ZEROCONF_DEVICE_PATH=/
AKRI_ZEROCONF=zeroconf
AKRI_ZEROCONF_DEVICE_HOST=akri.local
AKRI_ZEROCONF_DEVICE_PORT=8888

NOTE WebThings adds a TXT record path="/" to the service name referencing the device's path. The Akri Zeroconf protocol handler transfers this to an environment variable AKRI_ZEROCONF_DEVICE_PATH which we'll use below to construct the correct URL to access the device.

And, you can:

kubectl exec --stdin --tty ${POD} -- sh
apt update && apt install -y curl
curl ${AKRI_ZEROCONF_DEVICE_ADDR}:${AKRI_ZEROCONF_DEVICE_PORT}${AKRI_ZEROCONF_DEVICE_PATH} \
| jq -r .[].title
My Lamp
My Humidity Sensor

NOTE DNS-SD aren't exposed directly as host names so we use AKRI_ZEROCONF_DEVICE_ADDR rather than AKRI_ZEROCONF_DEVICE_NAME with curl. If you use a DNS-SD client, you can use the name.

@bfjelds bfjelds added the enhancement New feature or request label Dec 30, 2020
@bfjelds
Copy link
Collaborator

bfjelds commented Dec 30, 2020

Do I read this correctly that the zeroconf implementation also serves as a WebThings implementation? That is awesome!! I can't wait to get the extensibility model fixed up to merge zeroconf!!

@DazWilkin
Copy link
Contributor Author

Yes :-)

I'm contemplating (!) implementing the Akri "Distribution of Vaccines" scenario by writing WebThings for e.g. vaccine refrigerators and trucks. It may be overkill but it'd be a double whammy of an industrial application using WebThings and a neat scenario for Akri.

@DazWilkin
Copy link
Contributor Author

We fixed the WebThings Rust SDK so devices built with it, publish mDNS|SD correctly.

@bfjelds
Copy link
Collaborator

bfjelds commented Jan 2, 2021

Awesome!!

@kate-goldenring kate-goldenring linked a pull request Jan 11, 2021 that will close this issue
8 tasks
@github-actions
Copy link
Contributor

github-actions bot commented Sep 5, 2021

Issue has been automatically marked as stale due to inactivity for 45 days. Update the issue to remove label, otherwise it will be automatically closed.

@github-actions github-actions bot added the stale label Sep 5, 2021
@bfjelds
Copy link
Collaborator

bfjelds commented Nov 2, 2021

Per thread above, this has been fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request stale
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

2 participants