mqttjs / mqtt-elements

Polymer elements for MQTT
http://mqttjs.github.io/mqtt-elements/
MIT License
27 stars 6 forks source link

Lets get started on some custom HTML mqtt-elements #1

Closed sandro-k closed 9 years ago

sandro-k commented 9 years ago

Hi,

I like to get started on custom HTML MQTT-Elements aka Web Components. I already developed MQTTlens last summer, which is currently based on polymer 0.5.5 . Getting to the point Web Components are declarative which means that an application can mostly be created with only HTML and only the minimum JavaScript required. E.g.:

<google-map latitude="37.779" longitude="-122.3892" min-zoom="9" max-zoom="11" language="en">
  <google-map-marker latitude="37.779" longitude="-122.3892"
                     title="Go Giants!" draggable="true">
    <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/49/San_Francisco_Giants_Cap_Insignia.svg/200px-San_Francisco_Giants_Cap_Insignia.svg.png" />
  </google-map-marker>
</google-map>

would add Google-Maps onto a website without having to write any JavaScript. All the initialization of the Google-Maps API is done within the google-map element using the supplied arguments on the HTML tag. Custom HTML-Elements don't have to have any UI, see <iron-ajax> or <platinum-push-messaging>. These components provide an elegant way to wrap and interact with the underlying JavaScript libraries.

Without going into to many details I would like to collect some use cases how mqtt-elements could be used, so that these use cases can be considered while designing the elements.

sandro-k commented 9 years ago

Creating an mqtt-connection could be done like this

<mqtt-connection
  host="ws://localhost"
  port="8080"
  topic='["foo/bar", "device/1", {"topic":"location/home", "qos":"1"}]'
  on-connection="connectionCallback"
  on-connection-error="connectionErrorCallback"
  lastwill='{"topic":"user/1", "message":"offline", "qos":"2"}'>
</mqtt-connection>

or with an options object

<mqtt-connection
  options='{"host": "ws://localhost", "port": 8080, "lastWill": {"topic":"user/1", "message":"offline", "qos":"2"}}'
  on-connection="connectionCallback"
  on-connection-error="connectionErrorCallback">
sandro-k commented 9 years ago

@mqttjs/owners comments are welcome

sandro-k commented 9 years ago

Subscribing to a topic with

<mqtt-subscription topic="device/2" qos="1"></mqtt-subscription>

or

<mqtt-subscription options='{"topic": "foo/bar", "qos"="1"}'></mqtt-subscription>

Subscribing to multiple topics at once

<mqtt-subscription topic='["foo/bar", "device/1"]'></mqtt-subscription>
mcollina commented 9 years ago

I don't like that the protocol 'ws://' is in the 'host' property. Can you please match the new connect(url, opts) thing?

sandro-k commented 9 years ago

I agree, but iron-ajax is putting the protocol http or https into the url too. I think what would be nice to have is a property for the protocol and a read only property that is an array of all currently available protocols.

mcollina commented 9 years ago

I'm ok if the property is 'url'. Not if it is 'host'. I think you should just have an url property and pass it straight to mqtt.connect(url)

RangerMauve commented 9 years ago

I agree with having just one URL property that you pass everything to.

sandro-k commented 9 years ago

@mcollina I get why you want to map the <mqtt-connection> properties directly to mqtt.connect(). It will help to keep all API's identical and help users of the mqtt.js library to get used to the <mqtt-connection> element, but It might makes the usage of the element a bit more complicated or inconvenient. I think having a consistent API for the project will outweigh the negative aspects.

mcollina commented 9 years ago

I am ok in having two different APIs, it's just that including the protocol in the host is wrong: host="ws://localhost". It should be something like host="localhost" protocol="ws", or just url:"ws://localhost:12345".

RangerMauve commented 9 years ago

Does polymer support multiple variables when binding to an attribute? Something like host="{foo}/{bar}"?

sandro-k commented 9 years ago

Yes and no. The direkt binding of host="{{foo}}/{{bar}}" was possible in Polymer 0.5, but was removed with 1.0. Now there are Computed Properties and Computed Bindings. The later has the following syntax {{function(foo, bar)}}.

mcollina commented 9 years ago

@sandro-k why is it problematic having the protocol and host on two separate properties, and why can't we just have an URL property?

sandro-k commented 9 years ago

It is not problematic we can have protocol, host as Declared Properties and url as Computed Property or protocol, host as Computed Properties and url as Declared Property. Otherwise If we have all three properties as Declared Properties we would have to sync them manually.

Having just the url property would make it not possible to bind to inputs to the property like this:

<input value="{{protocol}}" />
<input value="{{host}}" />
<mqtt-connection url="{{protocol}}://{{host}}"></mqtt-connection>

This would work if we define the toUrl function within the mqtt-connection element

<input value="{{protocol}}" />
<input value="{{host}}" />
<mqtt-connection url="{{toUrl(protocol,host)}}"></mqtt-connection>

I gave a talk two weeks ago at a local Java User Group which include examples for Computed Properties and Computed Bindings

mcollina commented 9 years ago

I think you might not need to compute anything, as all the logic is in MQTT.js already.

I propose the following argument: if there is a url, call mqtt.connect(url), if there isn't, call it with mqtt.connect(properties), and properties would need to contain both a 'host' and a 'protocol'.

Does it make sense?

sandro-k commented 9 years ago

Makes sense..

I just wanted to have a discussion about the how the mqtt-elements should feel like to use. I think going with the minimum of extra logic around MQTT.js would make the development easier and missing features can always be added later on.

sandro-k commented 9 years ago

Closing this one. New feature discussions should be started on the base of 0.0.1-beta.