Giter Club home page Giter Club logo

zetta's People

Contributors

adammagaluk avatar anil14sagar avatar bneumann avatar gitter-badger avatar kevinswiber avatar kyork-cl avatar marvinroger avatar mdobson avatar mjavadhpour avatar wooliet avatar wwitman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zetta's Issues

Peering to remote zetta with 2 local zetta servers only shows one peer

I created two versions of the hello-world project by changing the port they listen on, ran both locally and linked them to the same hello-zetta.herokuapp.com peer. According to hello-zetta.herokuapp.com, only one peer is connected. Seems like the server that "wins" is whichever one was the last to come online.

To recreate:

  1. Clone https://github.com/zettajs/zetta-hello-world to your local machine
  2. Modify server.js to listen on a different port, like 2337
  3. Change the folder name from zetta-hello-world to something else, like zetta-hello-world2
  4. Clone https://github.com/zettajs/zetta-hello-world to your machine a second time
  5. Run each server in it's own terminal tab

Both servers peer to that same remote, but the remote only shows one of them. You can see that they're both running and streaming data by looking at how mangled the sinewave stream becomes:

screen shot 2014-10-15 at 3 31 36 pm

change to driver name() in code was ignored

In my LED driver code, I originally had:

    .name('led ' + this.pin)

then I changed it to upper case:

    .name('LED ' + this.pin)

But the names of the LEDs didn't change.

Because I was developing on the BeagleBone, I thought maybe I had opened the wrong file in the Cloud9 IDE or was doing something else wrong. After a while I gained confidence that I had changed the right file and that the new name was being ignored.

Eventually, I did rm -rf .peers .registry because it had worked for me in the past. And it did again. The new names worked after doing the rm.

Peer connection only half openning

When the pi or other local zetta instance restarts it shows connected to the cloud but the cloud does not see it as connected. I was able to reproduce the error a few times ~1/100 using my mac as a local zetta and a different heroku instance.

My heroku instance is using this branch https://github.com/zettajs/zetta/tree/peer-reconnect-issue

When the error happens I see the log on the local instance connected, on the cloud instance I see this websocket message. But none of the following messages for when the initial http request finishes or the peer registry adds it.

I also don't see any error on the http request here.

Any thoughts @kevinswiber @mdobson?

Add weak ETags to device representations.

This will help minimize data over the wire. ETags are an HTTP caching mechanism. Weak ETags become invalid when the underlying representation is not semantically equivalent.

We can use transitions as a trigger for calculating new ETags. ETags should be calculated based on device properties and actions. If, even after a transition, both properties and actions are the same, the ETag value won't change and will still be valid.

Zetta should return 304 Not Modified when receiving a request with an If-None-Match header that has a value of a currently valid ETag. Otherwise, it should continue down the request pipeline.

Extra credit: Peers that proxy to other Zetta instanced could be proxying the transition log. In this case, we know when that ETag has potentially changed based on a transition firing. We can keep a record of the last valid ETag for the backend server's devices and return 304's on behalf of the backend server, limiting bandwidth usage and latency. We can also forward requests on when we know the ETag may have changed (based on a new transition coming in for that device).

Device driver transition callback breaks when an error is passed.

In a device driver you should be able to pass an error to the callback and have http error with 500. It would also be nice if the body of the http response was the error message provided.

However currently the zetta instance throws.

LCD.prototype.change = function(message, cb) {
  cb(new Error('some error message'));
};

Error output

Error: some message
    at LCD.change (/Users/ApigeeCorporation/Software/zetta/zetta/sample/IHeardDat/devices/arduino/lcd_driver.js:23:6)
    at Device.call (/Users/ApigeeCorporation/Software/zetta/zetta-device/device.js:119:39)
    at run (/Users/ApigeeCorporation/Software/zetta/zetta/lib/api_resources/servers.js:137:17)
    at /Users/ApigeeCorporation/Software/zetta/zetta/lib/api_resources/servers.js:92:12
    at IncomingMessage.<anonymous> (/Users/ApigeeCorporation/Software/zetta/zetta/node_modules/argo/argo.js:100:7)
    at IncomingMessage.emit (events.js:92:17)
    at _stream_readable.js:938:16
    at process._tickDomainCallback (node.js:463:13)

This seems to be the reason why it throws. https://github.com/zettajs/zetta-device/blob/master/device.js#L85

And this is not passing the errors along. https://github.com/zettajs/zetta-device/blob/master/device.js#L108

Issues with the registry and monitor links

See mailing list email below.

Using the dot notation, I created a property called receivedSignalStrength for the FONA device that I'm modeling in Zetta.

When I called GET on the device's API:

GET /servers/beaglebone/devices/78c6200f-227b-4704-89c1-f54ad34153db

I was able to see the value in the properties object:

"receivedSignalStrength": "23"

Then I decided I'd also like to provide the ability for developers to monitor the value. So, I added:

config
  .monitor('receivedSignalStrength');

However, once I added monitor(), the receivedSignalStrength value stopped appearing in the API GET request properties.

For a moment it looked like a one or the other choice: property or WebSocket.

But just for kicks I removed the peers and registry directories:

rm -rf ./peers ./registry

When I rebooted my server and hit the API, I saw receivedSignalStrength in the properties and as a WebSocket as I had hoped.

So, is this a bug? Which behavior is intended?

HTTP proxy stops working

@mdobson @kevinswiber Starting an issue here to keep track of the findings.

Playing with it I'm noticing after reloading the browser a bunch of times it gets in the broken state. I added a console.log in the agents.socket.write function to inspect what's being sent over the socket. The last three times its got into the state i've noticed an 8 byte packet being constantly sent 20-30 times a second. The packet is formatted: [ 00 00 XX XX 01 00 00 00 ], XX XX being some type id that increments by two every packet.

Normally when a when a proxied http command is sent a packet is sent out I would see the normal http packet around 300 bytes being sent, followed by the same 8 byte packet, however only once per proxied request.

In wireshark it sees the packet a TCP segment.

Create a ServerExtension base class.

We need to be able to extend the Zetta server. For instance, plugging into the HTTP pipeline is currently not doable.

What I'd like is something like this:

var zetta = require('zetta');
var OAuth = require('zetta-oauth');
var DataStore = require('.....');

zetta
  .use(OAuth, DataStore)
  .listen(3000);

Note that DataStore just represents an additional parameter that needs to get sent into the constructor of OAuth.

Perhaps the ServerExtension class can have a list of abstract methods that, when implemented, help to plug into the HTTP pipeline at predefined locations.

include id of the zetta server somewhere in console output

It's great that I can see the id of a device, but without the id of the server I can't get at the device.

Does it make sense for the console log to include the id of the server upon startup? Like it does with the device:
Oct-06-2014 18:21:38 [scout] Device (speech) 0cdcfd8b-c191-44e0-8b06-ad0cd6e9a1a1 was provisioned from registry.

Async weirdness with monitored properties

Just wanted to document this issue. I have a feeling it will arise again. It appears that there is an async state weirdness with streams. Here is the sequence of events:

  1. Poll the sonos for it's current status
  2. Retrieve the currently playing track.
  3. Set the track title first. This fires off the title stream "data" event
  4. In the app on the title stream "data" event access the "artist" property. It's out of sync.
  5. Madness ensues.

Can clarify tomorrow if this doesn't make sense. Just need it here so I don't forget.

var Device = require('zetta').Device;
var util = require('util');
var setTrack = function(self, calledFromTransition) {
  self._sonos.currentTrack(function(err, track) {
    if(err) {
      return;
    } else {
      if((track && track.position > 0) || calledFromTransition) {
        self.state = 'playing';
        if(self.track !== track.title) {
          //The track data event fires before the artist is set.
          self.track = track.title;
          self.artist = track.artist;
        }
     } else {
        self.state = 'stopped';
        self.track = '';
        self.artist = '';
      }
    }
  });
};

var setVolume = function(self) {
  self._sonos.getVolume(function(e, volume) {
    if(e) {
      return;
    } else {
      if(volume) {
        self.volume = volume;
      }
    }
  });
};

var currentState = function(self) {
  self._sonos.getCurrentState(function(err, state) {
    self.state = state;
  });
};

var SonosDriver = module.exports = function(sonos) {
  Device.call(this);
  this._sonos = sonos;
  this._refreshInterval = null;
  this.track = '';
  this.artist = '';
  this.volume = 0;
};
util.inherits(SonosDriver, Device);

SonosDriver.prototype.init = function(config) {
  var self = this;
  config
    .state('stopped')
    .type('sonos')
    .name(this._sonos.host)
    .when('playing', { allow: ['stop', 'skip', 'play-uri', 'play', 'volume-up', 'volume-down'] })
    .when('stopped', { allow: 'play' })
    .when('paused', { allow: 'play'})
    .map('skip', this.skip)
    .map('play', this.play)
    .map('stop', this.stop)
    .map('volume-up', this.volumeUp)
    .map('volume-down', this.volumeDown)
    .map('play-uri', this.playUri, [{ name:'endpoint', type:'url' }])
    .monitor('artist')
    .monitor('volume')
    .monitor('track');

  //poll the track every 3 seconds
  self._refreshInterval = setInterval(setTrack, 1000, self, false);
  //setTimeout(setTrack, 1000, self, false);
  setTimeout(setVolume, 1000, self);
//  setInterval(currentState, 1000, self);
};

SonosDriver.prototype.play = function(cb) {
  var self = this;
  this._sonos.play(function(e, playing) {
    if(e) {
      console.log(e);
      if(cb) {
        cb(e);
      }
    } else {
      setTrack(self, true);
      if(cb) {
        cb();
      }
    }
  });
};

SonosDriver.prototype.skip = function(cb) {
  var self = this;
  this._sonos.next(function(e, playing) {
    if(e) {
      console.log(e);
      if(cb) {
        cb(e);
      }
    } else {
      setTrack(self, true);
      if(cb) {
        cb();
      }
    }
  });
};

SonosDriver.prototype.stop = function(cb) {
  var self = this;
  this._sonos.stop(function(e, stopped) {
    if(e) {
      console.log(e);
      if(cb) {
        cb(e);
      }
    } else {
      self.state = 'stopped';
      self.track = '';
      self.artist = '';
      if(self._refreshInterval) {
        clearInterval(self._refreshInterval);
      }
      if(cb) {
        cb();
      }
    }
  });
};

SonosDriver.prototype.playUri = function(url, cb) {
  var self = this;
  this._sonos.play(url, function(err, playing) {
    if(err) {
      console.log(err);
      if(cb) {
        cb(err);
      }
    } else {
      setTrack(self, true);
      if(cb) {
        cb();
      }
    }
  });
};

SonosDriver.prototype.volumeUp = function(cb) {
  var self = this;
  var newVolume = this.volume + 1;
  if(newVolume > 100) {
    newVolume = 100;
  } else if(newVolume < 0) {
    newVolume = 0;
  }
  this._sonos.setVolume(newVolume.toString(), function(e, data) {
    if(e) {
      if(cb) {
        cb(e);
      }
    } else {
      setVolume(self);
      if(cb) {
        cb();
      }
    }
  });
};

SonosDriver.prototype.volumeDown = function(cb) {
  var self = this;
  var newVolume = this.volume - 1;
  if(newVolume > 100) {
    newVolume = 100;
  } else if(newVolume < 0) {
    newVolume = 0;
  }
  this._sonos.setVolume(newVolume.toString(), function(e, data) {
    if(e) {
      if(cb) {
        cb(e);
      }
    } else {
      setVolume(self);
      if(cb) {
        cb();
      }
    }
  });
};

In app

module.exports = function(server) {
  var sonosQuery = server.where({ type: 'sonos' });

  server.observe(sonosQuery, function(sonos) {
    sonos.streams.track.on('data', function(message) {
      if(message.data !== '') {
        console.log('Current track:', message.data);
        //This statement will come back blank
        console.log('Current artist:', sonos.artist);
      }
    });
  });
};

Allow users to suppress logging

It would be great to be able to suppress logs, or possibly hook into logs to allow users to pipe it to their desired log collector.

help me find more quickly mismatches between devices and queries

in my device driver, I had this:

config.type('text-to-speech');

in my app, I had this:

var speechToTextQuery = server.where({type: 'speech-to-text'});

when I fired up my server, Zetta just sat there. doing nothing.

it took me longer than I care to admit to track down the embarrassing mistake that I had made.

is there a creative way that Zetta could help me track down this kind of mistake more easily?

even a simple log of known queries and known devices back-to-back in the console might have helped?

Error peering to Zetta on Azure

I tried running Zetta on Windows Azure. It can run its own API just fine with connected devices. However, when trying to peer a local Zetta with Zetta on Azure, I got this error:

Sep-21-2014 16:06:41 [http_server] Websocket connection for peer c2a5eb39-1c51-43ad-a340-139891123f96 established
Sep-21-2014 16:06:46 [http_server] Websocket http request timed out for peer c2a5eb39-1c51-43ad-a340-139891123f96
Sep-21-2014 16:06:52 [http_server] Websocket http request timed out for peer c2a5eb39-1c51-43ad-a340-139891123f96
Sep-21-2014 16:06:57 [http_server] Websocket http request timed out for peer c2a5eb39-1c51-43ad-a340-139891123f96
2014-09-21T16:08:29  No new trace in the past 1 min(s).
Sep-21-2014 16:08:42 [http_server] Websocket connection for peer c2a5eb39-1c51-43ad-a340-139891123f96 established
Sep-21-2014 16:08:42 [http_server] Websocket connection for peer c2a5eb39-1c51-43ad-a340-139891123f96 established
Sep-21-2014 16:08:42 [http_server] Websocket connection for peer c2a5eb39-1c51-43ad-a340-139891123f96 established
Sep-21-2014 16:08:42 [http_server] Websocket connection for peer c2a5eb39-1c51-43ad-a340-139891123f96 established
Sep-21-2014 16:08:47 [http_server] Websocket http request timed out for peer c2a5eb39-1c51-43ad-a340-139891123f96
Sep-21-2014 16:08:47 [http_server] Websocket http request timed out for peer c2a5eb39-1c51-43ad-a340-139891123f96
Sep-21-2014 16:08:47 [http_server] Websocket http request timed out for peer c2a5eb39-1c51-43ad-a340-139891123f96
Sun Sep 21 2014 16:08:47 GMT+0000 (Coordinated Universal Time): Unaught exception: Error: write EPIPE
    at errnoException (net.js:904:11)
    at Socket._write (net.js:645:26)
    at doWrite (_stream_writable.js:225:10)
    at writeOrBuffer (_stream_writable.js:215:5)
    at Socket.Writable.write (_stream_writable.js:182:11)
    at Socket.write (net.js:615:40)
    at Connection.write (D:\home\site\wwwroot\node_modules\zetta\node_modules\spdy\lib\spdy\connection.js:492:24)
    at Scheduler.tickListener (D:\home\site\wwwroot\node_modules\zetta\node_modules\spdy\lib\spdy\scheduler.js:67:23)
    at processImmediate [as _immediateCallback] (timers.js:345:15)
Application has thrown an uncaught exception and is terminated:
Error: write EPIPE
    at errnoException (net.js:904:11)
    at Socket._write (net.js:645:26)
    at doWrite (_stream_writable.js:225:10)
    at writeOrBuffer (_stream_writable.js:215:5)
    at Socket.Writable.write (_stream_writable.js:182:11)
    at Socket.write (net.js:615:40)
    at Connection.write (D:\home\site\wwwroot\node_modules\zetta\node_modules\spdy\lib\spdy\connection.js:492:24)
    at Scheduler.tickListener (D:\home\site\wwwroot\node_modules\zetta\node_modules\spdy\lib\spdy\scheduler.js:67:23)
    at processImmediate [as _immediateCallback] (timers.js:345:15)

/cc @klevak

Create a ProtocolScout

Currently, we have the ability to register devices over HTTP. What would an MQTT Scout look like? A TCP Scout? Should we make this extensible?

Monitored property returning null

Ran into a strange issue building out demo code today. A monitored property is always returning null when trying to access it from it's getter.

module.exports = function(server) {
  var sonosQuery = server.where({type: 'sonos'});
  var twilioQuery = server.where({type: 'phone'});

  server.observe([sonosQuery, twilioQuery], function(sonos, twilio) {
    sonos.streams.state.on('data', function(message) {
      if(message.data !== '') {
        //sonos.artist always returns null
        var sms = 'Sonos playing - ' + message.data + ' by ' + sonos.artist;
        console.log(sms);
        twilio.call('send-sms', '+17346345472', sms, function(err) {
          if(err) {
            server.log(err);
          } else {
            server.log('Sent your phone an update!');
          }
        });
      }
    });
  });
};

HTTP POST to Zetta without content-type specified causes crash

I issued a POST without specifying content-type:

curl -X POST  http://0.0.0.0:1337/servers/ba41550f-68f9-424d-b78e-123ee811014c/devices/0cdcfd8b-c191-44e0-8b06-ad0cd6e9a1a1

Zetta coughed up this error:

./node_modules/zetta/node_modules/argo-multiparty/index.js:5
nv.request.method === 'POST' && env.request.headers['content-type'].indexOf('m
                                                                    ^
TypeError: Cannot call method 'indexOf' of undefined
    at null.<anonymous> (./node_modules/zetta/node_modules/argo-multiparty/index.js:5:77)
    at b (domain.js:183:18)
    at null.<anonymous> (./node_modules/zetta/node_modules/argo/node_modules/pipeworks/pipeworks.js:72:17)
    at null.<anonymous> (./node_modules/zetta/node_modules/titan/node_modules/argo-formatter/formatter.js:48:7)
    at b (domain.js:183:18)
    at null.<anonymous> (./node_modules/zetta/node_modules/argo/node_modules/pipeworks/pipeworks.js:72:17)
    at null.<anonymous> (./node_modules/zetta/node_modules/titan/node_modules/argo-url-helper/url.js:31:5)
    at b (domain.js:183:18)
    at null.<anonymous> (./node_modules/zetta/node_modules/argo/node_modules/pipeworks/pipeworks.js:72:17)
    at null.<anonymous> (./node_modules/zetta/node_modules/titan/node_modules/argo-url-helper/url.js:31:5)

Ambiguous zetta.use() failing with version miss match

@mdobson @kevinswiber Starting a thread here for the issue we found yesterday. zetta.use() cannot determine if the first argument is a Device/Scout/App based on the base class's prototype if different versions of zetta-device or zetta-scout are installed for the device vs the base server.

Few options:

a: Don't use a ambiguous use call.

b: Change zetta-scout and zetta-device constructor to use a named function like:

var Device = module.exports = function Device(){};

Then compare on the constructors name Device or Scout. However this has issues with zetta versions not matching.

c: Add some other property to Device/Scout that could distinguish it, possibly with a version associated with it. Seems more hackish.

d: Use npm peerDependencies. Biggest downside to this options is that it may be unnatural for module developers that are not familiar with Dependencies.

Logging in the server file

Any thoughts on opening up logging in the server file as well? We have it every where else basically.

var zetta = require('zetta');
var LED = require('./');
var server = zetta()
  .use(LED)
  .listen(1337, function(err) {
    server.log('Error:', err);
  });

or

var zetta = require('zetta');
var LED = require('./');
zetta()
  .use(LED)
  .listen(1337, function(err) {
    this.log('Error:', err);
  });

Request for Feedback: Root Link Relation Update

Hey I'm going through and building a small API consumer app before the conference, and just making notes of things that I observe when building. I'd like to add a server relation to all the peer links in addition to the peer relation. I think it would make it easier for a client to access all the relevant servers quickly with this relation in place. Thoughts?

{
  "class": [
    "root"
  ],
  "links": [
    {
      "rel": [
        "self"
      ],
      "href": "http://zetta-cloud-2.herokuapp.com/"
    },
    {
      "title": "cloud",
      "rel": [
        "http://rels.zettajs.io/server"
      ],
      "href": "http://zetta-cloud-2.herokuapp.com/servers/2d72035a-fff5-4183-a4da-ca6001706b76"
    },
    {
      "title": "matt.dobson",
      "rel": [
        "http://rels.zettajs.io/peer",
        "http://rels.zettajs.io/server"
      ],
      "href": "http://zetta-cloud-2.herokuapp.com/servers/5961a387-44ee-4e8a-8d88-9791fcb6b0fc"
    },
    {
      "title": "Detroit",
      "rel": [
        "http://rels.zettajs.io/peer",
        "http://rels.zettajs.io/server"
      ],
      "href": "http://zetta-cloud-2.herokuapp.com/servers/d23094cf-aba5-4c7b-b3ee-b43807ce4e95"
    },
    {
      "rel": [
        "http://rels.zettajs.io/peer-management"
      ],
      "href": "http://zetta-cloud-2.herokuapp.com/peer-management"
    }
  ]
}

HTTP POST to Zetta with empty data specified causes crash

I issued a POST with empty data:

curl --data "" http://0.0.0.0:1337/servers/4c16ef80-c4a3-4990-9f6b-7a05f17ed37a/devices/0cdcfd8b-c191-44e0-8b06-ad0cd6e9a1a1

Zetta coughed up this error:

./examples/node_modules/zetta/lib/api_resources/servers.js:103
      body = querystring.parse(body.toString());
                                    ^
TypeError: Cannot call method 'toString' of undefined
    at ./examples/node_modules/zetta/lib/api_resources/servers.js:103:37
    at IncomingMessage.<anonymous> (./examples/node_modules/zetta/node_modules/argo/argo.js:100:7)
    at IncomingMessage.EventEmitter.emit (events.js:92:17)
    at _stream_readable.js:920:16
    at process._tickDomainCallback (node.js:459:13)

Double device .use has unpredictable behavior

Hey All,

Did a deep dive into a bug @alanguir was running into earlier today. We thought it was medea hint files, but that was really a red herring. It was an issue with a double use() call of a driver. Check out the server code here: https://github.com/alanguir/zetta-button-app/blob/master/server.js

Here is the scenario that I believe is happening:

  • We create two instances of button
    • One has a name of "Camera"
    • One has a name of "Lights"
    • Each of these is saved to the registry
  • We exit zetta
  • Zetta is restarted
    • We search in the registry for devices of type "button"
    • We receive two results
    • We iterate through each sending arguments off to provision as intended
      • Each time we mutate and array called applyArgs by putting the registry data object as the first item using unshift()
        • First iteration provisions a new "button" device properly
        • Second iteration doesn't, and causes a meltdown
          • In the concrete implementation of provision we typically chop off the first data object argument and send off the other arguments (A constructor function, and additional arguments) to the scientist for creation
          • The second iteration doesn't have that happen properly because the array appends a second data object to the front.

The offending piece of code can be found here:

https://github.com/zettajs/zetta-auto-scout/blob/master/auto_scout.js#L41-L44

A small hack to fix this is below. If we shift off the data object after we call provision everything will be provisioned properly.

      results.forEach(function(result) {
        applyArgs.unshift(result);
        self.provision.apply(self, applyArgs);
        applyArgs.shift();
      });

However, there is a second issue as well. Since we filter on the type of device in the registry we actually call each provision of button with a single auto scout instance and it's corresponding argument. Which means the arguments in the second device use() call is ignored. Basically this means that we provision a "Camera" "button" and a "Lights" "button" with the following statement .use(Button, "Lights")

This is a weird issue and properly an incoherent writeup. I can repro monday morning and talk through it more as well.

Linking API outside of initial server startup

Here is an interesting issue. The following code won't do what we think it would do. It will just sit there doing nothing. Should we investigate doing a patch on this part of the API to handle this scenario?

var zetta = require('zetta');

var inst = zetta()
  .name('mdobs')
  .listen(1337, function(err) {
    if(!err) {
      inst.link('http://hello-zetta.herokuapp.com/');
    }
  });

This work around will remedy the issue, but doesn't account for the peer cleanup process which is another internal function.

var inst = zetta()
  .name('mdobs')
  .listen(1337, function(err) {
      inst.link('http://hello-zetta.herokuapp.com/');
      inst._initPeers(function(err) {
        if(err) {
          console.log(err);  
         } 
       });  
  });

can zetta help me find simple state machine mistakes

I created a new state machine via copy and paste from another driver's state machine. But when I went to run it I wasn't seeing the states that I had created. after much staring at code, I realized that I had never deleted the original off and on states at the very end of the state machine. code below.

would Zetta help me by flagging duplicate state entries?

    .when('off', { allow: ['turn-on', 'turn-on-pulse', 'turn-on-alternating', 'flash']})
    .when('on', { allow: ['turn-off', 'turn-on-pulse', 'turn-on-alternating', 'flash'] })
    .when('pulse', { allow: ['turn-off', 'turn-on', 'turn-on-alternating', 'flash'] })
    .when('alternating', { allow: ['turn-off', 'turn-on', 'turn-on-pulse', 'flash'] })
    .when('flash', { allow: [] })
    .when('off', { allow: ['turn-on'] })
    .when('on', { allow: ['turn-off'] })

Be more explicit about creating device streams in apps.

Currently, to create a new read stream on a device, we do something like:

heartbeat.streams.pulse.on('data', function(pulse) {
  // do something with pulse
});

We have a custom getter on streams that creates a new readable stream with each property access.

This gets confusing.

heartbeat.streams.pulse.on('data', function(pulse) {
  // do something with pulse
});

heartbeat.streams.pulse.on('error', function(err) {
  // this is an error handler on a different stream!
});

See the issue?

I'd like to be more explicit about stream creation.

Something like...

var pulseStream = heartbeat.createReadStream('pulse');

pulseStream.on('data', function(pulse) {
  // do something with pulse
});

pulseStream.on('error', function(err) {
  // this is an error handler on a different stream!
});

Thoughts?

/cc @AdamMagaluk @mdobson

Async Device.prototype.init

Hey Dudes,

Been working on my sonos driver. Adding a callback to the init function like within the Scout init may be advantageous for some pre configuration. Using the Sonos lib everything is async, and so retrieving any relevant info is a PITA.

//this._sonos => JS interface to sonos. 

SonosDriver.prototype.init = function(config, cb) {
  config
    .state('online')
    .type('sonos')
    .name(this._sonos.host);

    this._sonos.currentTrack(function(err, track) {
      if(!err && track) {
        config
          .state('playing')
          self.track = track.title;
          cb(); //Hey we're done configuring. Wire up device.
      }
   });

};

documentation

Please provide link to documentation. I have visited http://www.zettajs.org/ however couldn't find proper documentation there.

I want to do POC to connect Andruino robot through zetta platform.

Thanks,
Purvish

error: Failed to find devicetree fragment

I was following the Home Security project. When I ran node server.js the first time I got the error below.

The fix was to rm -rf .peers/ .registry/

# node server.js
error: Failed to find devicetree fragment: bspwm_P9_14_6
info:  0: 54:PF--- 
 1: 55:PF--- 
 2: 56:PF--- 
 3: 57:PF--- 
 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
 5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
 7: ff:P-O-L Override Board Name,00A0,Override Manuf,am33xx_pwm

info: Error loading devicetree overlay for P9_14 using template bspwm
error: error updating PWM freq and value: undefined, Error: ENOENT, no such file or directory 'undefined/duty'

Yet, the device and server sent messages to the console as if all was good.

Apr-23-2014 20:30:35 [scout] Device (buzzer) 8c01a134-43b3-4c44-a2d0-8226df5f7901 was discovered
Zetta is running at http://beaglebone.local:1337

Fix Windows support

We broke Windows support when we created hidden directories (prefixed with a ".").

Let's use underscores instead of periods on Windows (common convention).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.