[V4] Dev service RFlink

Hello,

I have started developing the backend of the RFlink service (no PR yet because I have a low level in JS and I didn’t think I would be able to do it) and I am looking for someone who would like to do the frontend.

I can’t take care of it myself, I can’t learn React and I don’t even really know how to develop in JS.

The front end would be simple, a setup tab that lists the USB ports and a tab for the devices.

If no one can help, I will try to copy and paste the pages I am interested in from the other modules.

And I take this opportunity to ask questions:

  • For the API, is it enough to return an object controllers that associates a function with each request?

  • RFlink manages milight and 433, so we will have 2 services to manage Milight and 2 for 433, is that not annoying?

  • Should I make a PR even if the module is not sure to be released and does not depend only on me (for the front end)?

Thank you for your answers

Hello!

I struggle to see how you can develop the backend if you don’t know how to develop in JS ^^

Preact is quite simple, duplicate the code of another service and go at it by trial and error, it’s worth learning :slight_smile:

In fact, I’m learning JS by doing the service (and it’s working really well :grinning:).

For Preact, I’ll try.

I have another question:

  • Why do I get an error saying that I didn’t put an external_id when I create a device, even though when I log the device, I see the external_id property?

The error:
2020-02-02T13:04:33+0100 device.create.js:68 () {
device: {
service_id: undefined,
name: ‹ TriState switch ›,
selector: ‹ rflink:808a90 ›,
external_id: ‹ rflink:808a90 ›,
model: ‹ TriState ›,
features: [ [Object] ]
}
}
2020-02-02T13:04:33+0100 functionsWrapper.js:15 (EventEmitter.) Error while executing function () { [native code] }
2020-02-02T13:04:33+0100 functionsWrapper.js:16 (EventEmitter.) BadParameters [Error]: A device must have an external_id.
at E:\admin\Documents\MOI\Projets\Gladys\gladys\server\lib\device\device.create.js:70:13

  • I also wonder how to know if a device already exists in the database?

Are you sure you’re sending it? Check in the « Network » tab of your browser, I think you’re not sending the external_id.

I think you’re right, I’ll take a look. I put the code on GitHub: Gladys/server/services/rflink at rflink · mTondenier/Gladys · GitHub

Could someone tell me if it’s good for the object controllers because I feel like my routes are returning errors

Hello, I would like to know if a developer can help me understand why my API is not working

I think the problem is in the index because the controllers object is correct. Is this due to the fact that I return controllers in the start function?

index.js:

const logger = require('../../utils/logger');

const RfLinkManager = require('./lib');

const RflinkController = require('./api/rflink.controller');

const { ServiceNotConfiguredError } = require('../../utils/coreErrors');

let rfLinkManager;

module.exports = function RfLink(gladys, serviceId) {

    const Serialport = require('serialport');

    const Readline = require('@serialport/parser-readline');

/**
 * @description start rflink module
 * @example
 * gladys.services.rflink.start();
 */

    async function start() {

      logger.log('Starting Rflink service');

      const RflinkPath = await gladys.variable.getValue('RFLINK_PATH', serviceId);

      if (!RflinkPath) {

        throw new ServiceNotConfiguredError('RFLINK_PATH_NOT_FOUND');

      }
      const port = new Serialport(RflinkPath, {baudRate : 57600});

      const readline = new Readline();

      port.pipe(readline);

      rfLinkManager = new RfLinkManager(readline, gladys, serviceId);

      if (rfLinkManager === undefined)  {

        throw new ServiceNotConfiguredError('RFLINK_GATEWAY_ERROR');

      } else {

        rfLinkManager.connect(RflinkPath);

        return Object.freeze({

          device : rfLinkManager,

          controllers : RflinkController(gladys, rfLinkManager, serviceId),

        });

      }

    }

/**
 * @description stop rfllink module
 * @example
 * gladys.services.rflink.stop();
 */

    async function stop() {

      logger.log('Stopping Rflink service');

      rfLinkManager.disconnect();

    }
    return Object.freeze({

      start,

      stop,

    })

    ;

};

The GitHub link: Gladys/server/services/rflink at master · mTondenier/Gladys · GitHub

Thanks in advance for the help and I hope to be able to release the module quickly.

Indeed, that can’t work!

The controller must be returned by the service constructor, not by the start function.

If I prevent the service from starting when the user hasn’t defined rflinkpath, won’t I be unable to change the value of rflinkpath if I stop my service?

I think you should review how your classes are organized. Your controller should be able to start without all that, same for your RfLinkManager object!

Do all that outside of the start function.

The start function should only call the « .connect » with the value of the RFLINK_PATH

I advise you to draw inspiration from the other services :slight_smile:

Thanks for your quickness, I will review everything to make it work

Got it, I’ve already found a solution :grinning:.

I just wanted to know if you can explain why I’m getting 404 errors when I call the routes of my controllers.

Here is the server error (it looks like an authentication problem):

2020-02-08T15:25:37+0100 <debug> index.js:95 (WebSocketServer.<anonymous>) New user connected in websocket, [object Object]
2020-02-08T15:25:37+0100 <debug> index.js:117 (WebSocket.<anonymous>) JsonWebTokenError: invalid signature
    at E:\admin\Documents\MOI\Projets\Gladys\gladys\server\node_modules\jsonwebtoken\verify.js:133:19
    at getSecret (E:\admin\Documents\MOI\Projets\Gladys\gladys\server\node_modules\jsonwebtoken\verify.js:90:14)
    at Object.module.exports [as verify] (E:\admin\Documents\MOI\Projets\Gladys\gladys\server\node_modules\jsonwebtoken\verify.js:94:10)
    at Session.validateAccessToken (E:\admin\Documents\MOI\Projets\Gladys\gladys\server\lib\session\session.validateAccessToken.js:15:23)
    at WebSocket.<anonymous> (E:\admin\Documents\MOI\Projets\Gladys\gladys\server\api\websockets\index.js:109:49)
    at WebSocket.emit (events.js:304:20)
    at Receiver.receiverOnMessage (E:\admin\Documents\MOI\Projets\Gladys\gladys\server\node_modules\ws\lib\websocket.js:789:20)
    at Receiver.emit (events.js:304:20)
    at Receiver.dataMessage (E:\admin\Documents\MOI\Projets\Gladys\gladys\server\node_modules\ws\lib\receiver.js:422:14)
    at Receiver.getData (E:\admin\Documents\MOI\Projets\Gladys\gladys\server\node_modules\ws\lib\receiver.js:352:17)
    at Receiver.startLoop (E:\admin\Documents\MOI\Projets\Gladys\gladys\server\node_modules\ws\lib\receiver.js:138:22)
    at Receiver._write (E:\admin\Documents\MOI\Projets\Gladys\gladys\server\node_modules\ws\lib\receiver.js:74:10)
    at doWrite (_stream_writable.js:463:12)
    at writeOrBuffer (_stream_writable.js:445:5)
    at Receiver.Writable.write (_stream_writable.js:325:11)
    at Socket.socketOnData (E:\admin\Documents\MOI\Projets\Gladys\gladys\server\node_modules\ws\lib\websocket.js:864:35)
    at Socket.emit (events.js:304:20)
    at addChunk (_stream_readable.js:341:12)
    at readableAddChunk (_stream_readable.js:316:11)
    at Socket.Readable.push (_stream_readable.js:250:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:186:23) {
  name: 'JsonWebTokenError',
  message: 'invalid signature'
}

This is the last question for today, after that I’ll stop :innocent:

In my opinion, these logs are something else… These logs only appear when you restart your dev server, the access tokens are invalidated, it’s debug, not errors

Are your routes really 404? Are you sure your controller is properly exposed?

These logs appear every time I press my button on the UI, I’m still looking into it.

While I’m at it, I’ll give a bit of an update on the module’s progress:

What’s done:

  • Backend:

    • create devices
    • receive a new value from a device
    • change the value of a device
    • pair and unpair milights
  • Frontend:

    • configuration page

What’s left to do:

  • manage to display all devices on a page (I copied the Philips Hue page but it doesn’t work)

  • receive status requests without getting a 404

  • manage color, intensity, … changes for milights

That’s it, the module is not far from being finished

The github: GitHub - mTondenier/Gladys at rflink · GitHub

Maybe I don’t understand, but what’s the connection with milight? :slight_smile:

RFlink manages Milight bulbs, so if someone wants to use these bulbs without a bridge, they need to be able to pair them.

For my 404 issue, it only concerns one route, which is:

/api/v1/service/rflink/status

And I checked, it’s the same for the Z-Wave service, which also gets a 404 on its route:

/api/v1/service/zwave/status

Without this route, the frontend doesn’t know if the RFlink gateway is connected.

Is this normal in the zwave module?

Could you add WIP in the title of your PR @joeypic?

It’s just to indicate that development is ongoing.
Thanks :+1:

So no one understands why the « status » routes aren’t working?

@pierre-gilles I would like to know if it’s possible in my service to have a condition to check if a device exists in the database or not?

I think no one has had time to look at your code yet.

A little patience :wink:

You must be right :upside_down_face:
It’s just that since the RC is coming out on the 21st, I wanted to see if I was able to release the service before