node-red-alexa-home-skill-web icon indicating copy to clipboard operation
node-red-alexa-home-skill-web copied to clipboard

Wont Connect anymore

Open nick9888 opened this issue 6 months ago • 22 comments

Ben,

Thanks for your email reply,

I have Node Red and cant get the Alexa Home skill to connect anymore but was working really well. Continues to say Re-connecting now and also doesn't show any devices in the node red Alexa Home Node setup?

I have checked all my credentials and the linking works perfectly? It must be something simple as was working perfectly?

Any ideas? I can give you my username or any other info if that helps?

Image

Nick Clay - [email protected]

nick9888 avatar May 17 '25 11:05 nick9888

Continuous reconnecting implies either the username/password are wrong or you have 2 instances connected (you can only have one and there should only be a single config node shared between all device nodes)

Please share the node-red logs and the username

hardillb avatar May 17 '25 11:05 hardillb

Thanks user is Clayhome, are you able to help me get the node red logs or is this it?

17 May 08:11:59 - [info] Node-RED version: v4.0.8 17 May 08:11:59 - [info] Node.js version: v20.18.3 17 May 08:11:59 - [info] Linux 6.6.74+rpt-rpi-v8 arm LE 17 May 08:11:59 - [info] Loading palette nodes 17 May 08:12:00 - [info] Dashboard version 3.6.5 started at /ui 17 May 08:12:00 - [info] Settings file : /home/pi/.node-red/settings.js 17 May 08:12:00 - [info] HTTP Static : /home/pi/node-red-static > / 17 May 08:12:00 - [info] Context store : 'default' [module=memory] 17 May 08:12:00 - [info] User directory : /home/pi/.node-red 17 May 08:12:00 - [info] Projects directory: /home/pi/.node-red/projects 17 May 08:12:00 - [warn] No active project : using default flows file 17 May 08:12:00 - [info] Flows file : /home/pi/.node-red/flows.json 17 May 08:12:01 - [error] Unable to listen on http://127.0.0.1:1880/ 17 May 08:12:01 - [error] Error: port in use

nick9888 avatar May 17 '25 12:05 nick9888

Username:ClayHome

nick9888 avatar May 17 '25 12:05 nick9888

I can use the same Username and password entered into the Skill URL website ok?

nick9888 avatar May 17 '25 12:05 nick9888

Image

nick9888 avatar May 17 '25 12:05 nick9888

I do have the "node-red-contrib-alexa-remote2" running ok as well? in node red?

nick9888 avatar May 17 '25 12:05 nick9888

I need more logs than that, what you've given never started the flows because the original version is still running.

The other node should not matter, the logs would have shown if there was an internal node name clash.

From the burger menu in the to right hand corner select configuration nodes and double check that you only have 1 instance of the node with the name matching your username.

Also double check that you do not have any old versions of Node-RED running on other machines configured with the node (even just the configuration node).

I'll check the broker logs for that username later when I get back to confirm it's multiple instances.

Also it would be useful to get a section of logs that covers a time when you press the refresh button next to the list of devices drop down.

hardillb avatar May 17 '25 13:05 hardillb

Image

nick9888 avatar May 17 '25 13:05 nick9888

you are a legend! fixed!

nick9888 avatar May 17 '25 13:05 nick9888

I had another Node red running!!!!

nick9888 avatar May 17 '25 13:05 nick9888

its working!

nick9888 avatar May 17 '25 13:05 nick9888

hang on its stopped again

nick9888 avatar May 17 '25 13:05 nick9888

Since midnight UTC there has only been one instance connected to the broker. It connected at 13:13 UTC and disconncedted at 13:31 UTC.

I need to see the NR logs from the running instance that is trying to connect (may be run the node-red-logs command

hardillb avatar May 17 '25 13:05 hardillb

pi@raspberrypi:~ $ node-red-log

 
17 May 09:55:05 - [info] Loading palette nodes
17 May 09:55:06 - [info] Dashboard version 3.6.5 started at /ui
17 May 09:55:07 - [info] Settings file  : /home/pi/.node-red/settings.js
17 May 09:55:07 - [info] HTTP Static    : /home/pi/node-red-static > /
17 May 09:55:07 - [info] Context store  : 'default' [module=memory]
17 May 09:55:07 - [info] User directory : /home/pi/.node-red
17 May 09:55:07 - [info] Projects directory: /home/pi/.node-red/projects
17 May 09:55:07 - [warn] No active project : using default flows file
17 May 09:55:07 - [info] Flows file     : /home/pi/.node-red/flows.json
17 May 09:55:07 - [info] Server now running at http://127.0.0.1:1880/
17 May 09:55:07 - [warn]
---------------------------------------------------------------------
Your flow credentials file is encrypted using a system-generated key.
If the system-generated key is lost for any reason, your credentials
file will not be recoverable, you will have to delete it and re-enter
your credentials.
You should set your own key using the 'credentialSecret' option in
your settings file. Node-RED will then re-encrypt your credentials
file using your chosen key the next time you deploy a change.
---------------------------------------------------------------------
17 May 09:55:07 - [info] Starting flows
17 May 09:55:07 - [info] Started flows
17 May 09:55:07 - [info] [mqtt-broker:c4f358c5.17ac08] Connected to broker: mqtt://10.0.0.210:1883

nick9888 avatar May 17 '25 13:05 nick9888

Will need at least another 5mins worth of logs, including when hitting the refresh button

hardillb avatar May 17 '25 14:05 hardillb

Image

nick9888 avatar May 17 '25 14:05 nick9888

i have stopped my other node red at home just encase, but still not working - but it did connect for short time?

nick9888 avatar May 17 '25 14:05 nick9888

All I can suggest is find the alexa.js file under node_modules/node-red-alexa-home-skill and take the // off the start of line 102

So it reads as follows

            node.client.on('error', function (err){
                console.log(err);
                node.setStatus({text: 'disconnected', shape: 'dot', fill:'red'});
                node.error(err);
            });
        }

This should print some more error messages to the logs (but they should already be showing up in the debug sidebar)

I've seen it connect once more today

tail -f mosquitto.log | grep ClayHome
1747489742: New client connected from 124.190.xx.xx:34826 as ClayHome (p2, c1, k60, u'ClayHome').
1747489977: Client ClayHome disconnected.

hardillb avatar May 17 '25 14:05 hardillb

/**

  • Copyright 2016 IBM Corp.
  • 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. **/

module.exports = function(RED) {

"use strict";
var request = require('request');
var mqtt = require('mqtt');
var bodyParser = require('body-parser');

var devicesURL = 'https://alexa-node-red.bm.hardill.me.uk/api/v1/devices';


var devices = {};

function alexaConf(n) {
	RED.nodes.createNode(this,n);
	this.username = n.username;
	this.password = this.credentials.password;

    this.users = {};

	var node = this;

    var options = {
        username: node.username,
        password: node.password,
        clientId: node.username,
        reconnectPeriod: 5000,
        servers:[
            // {
            //     protocol: 'mqtts',
            //     host: 'alexa-node-red.hardill.me.uk',
            //     port: 8883
            // },
            {
                protocol: 'mqtt',
                host: 'alexa-node-red.hardill.me.uk',
                port: 1883
            }
        ]
    };

    // if (process.env.DEBUG) {
    //     console.log("debug");
    //     process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
    //     var test = {
    //         protocol: 'mqtt',
    //         host: '172.17.0.2',
    //         port: 1883
    //     };
    //     options.servers = [test];

    //     devicesURL = 'https://localhost:3000/api/v1/devices'
    // }

    getDevices(node.username, node.password, node.id);

    this.connect = function() {
        node.client = mqtt.connect(options);
        node.client.setMaxListeners(0);

        node.client.on('connect', function() {
            node.setStatus({text:'connected', shape:'dot', fill:'green'});
            node.client.removeAllListeners('message');
            node.client.subscribe("command/" + node.username + "/#");
            node.client.on('message', function(topic, message){
                var msg = JSON.parse(message.toString());
                var applianceId = msg.payload.appliance.applianceId;
                for (var id in node.users) {
                    if (node.users.hasOwnProperty(id)){
                        if (node.users[id].device === applianceId) {
                            node.users[id].command(msg);
                        }
                    }
                }
            });
        });

        node.client.on('offline',function(){
            node.setStatus({text: 'disconnected', shape: 'dot', fill:'red'});
        });

        node.client.on('reconnect', function(){
            node.setStatus({text: 'reconnecting', shape: 'ring', fill:'red'});
        });

        node.client.on('error', function (err){
            console.log(err);
            node.setStatus({text: 'disconnected', shape: 'dot', fill:'red'});
            node.error(err);
        });
    }

    this.setStatus = function(status) {
        for( var id in node.users) {
            if (node.users.hasOwnProperty(id)) {
                node.users[id].status(status);
            }
        }
    }

    this.register = function(deviceNode) {
        node.users[deviceNode.id] = deviceNode;
        if (Object.keys(node.users).length === 1) {
            //connect
            node.connect();
        }
    };

    this.deregister = function(deviceNode, done) {
        delete node.users[deviceNode.id];

        if (Object.keys(node.users).length === 0) {
            //disconnect
            if (node.client && node.client.connected) {
                node.client.end(done);
            } else {
                node.client.end();
                done();
            }
        }

        done();
    };

    this.acknoledge = function(messageId, device, success, extra) {
        var response = {
            messageId: messageId,
            success: success
        };

        if (extra) {
            response.extra = extra;
        }

        // console.log("response: " + response);

        var topic = 'response/' + node.username + '/' + device;
        if (node.client && node.client.connected) {
            node.client.publish(topic, JSON.stringify(response));
        }
    };

	this.on('close',function(){
        if (node.client && node.client.connected) {
            node.client.end();
        }
        //node.removeAllListeners();
		//delete devices[node.id];
	});
};

RED.nodes.registerType("alexa-home-conf",alexaConf,{
    credentials: {
        password: {type:"password"}
    }
});

function alexaHome(n) {
	RED.nodes.createNode(this,n);
	this.conf = RED.nodes.getNode(n.conf);
    this.confId = n.conf;
	this.device = n.device;
    this.topic = n.topic;
    this.acknoledge = n.acknoledge;
    this.name = n.name;

	var node = this;

    node.command = function (message){
        var msg ={
            topic: node.topic || "",
            name: node.name,
            _messageId: message.header.messageId,
            _applianceId: message.payload.appliance.applianceId,
            _confId: node.confId,
            command: message.header.name,
            extraInfo: message.payload.appliance.additionalApplianceDetails
        }

        var responseExtra;
        var respond = true;

        switch(message.header.name){
            case "TurnOnRequest":
                msg.payload = true;
                break;
            case "TurnOffRequest":
                msg.payload = false;
                break;
            case "SetPercentageRequest":
                msg.payload = message.payload.percentageState.value;
                break;
            case "IncrementPercentageRequest":
                msg.payload = message.payload.deltaPercentage.value;
                break;
            case "DecrementPercentageRequest":
                msg.payload = -1 * message.payload.deltaPercentage.value;
                break;
            case "SetTargetTemperatureRequest":
                msg.payload = message.payload.targetTemperature.value;
                responseExtra = {
                    targetTemperature: {
                        value: message.payload.targetTemperature.value
                    }
                };
                break;
            case "IncrementTargetTemperatureRequest":
                msg.payload = message.payload.deltaTemperature.value;
                responseExtra = {
                    targetTemperature: {
                        value: message.payload.targetTemperature.value
                    }
                };
                break;
            case "DecrementTargetTemperatureRequest":
                msg.payload = -1 * message.payload.deltaTemperature.value;
                responseExtra = {
                    targetTemperature: {
                        value: message.payload.targetTemperature.value
                    }
                };
                break;
            case "SetLockStateRequest":
                msg.payload = message.payload.lockState;
                responseExtra = {
                    lockState: message.payload.lockState
                }
                break;
            case "SetColorRequest":
                msg.payload = message.payload.color;
                responseExtra = {
                    achievedState: {
                        color: message.payload.color
                    }
                };
                break;
            case "SetColorTemperatureRequest":
                msg.payload = message.payload.colorTemperature.value;
                responseExtra = {
                    achievedState: message.payload
                }
                //respond = false;
                break;
            case "IncrementColorTemperatureRequest":
                msg.payload = message.payload
                respond = false;
                break;
            case "decrementColorTemperatureRequest":
                msg.payload = message.payload;
                respond = false;
                break;
            case "GetLockStateRequest":
            case "GetTemperatureReadingRequest":
            case "GetTargetTemperatureRequest":
                respond = false;
                break;
        }

        node.send(msg);
        if (node.acknoledge && respond) {
            node.conf.acknoledge(message.header.messageId, node.device, true, responseExtra);
        }
    }

    node.conf.register(node);

    node.on('close', function(done){
        node.conf.deregister(node, done);
    });

}


RED.nodes.registerType("alexa-home", alexaHome);

function alexaHomeResponse(n) {
    RED.nodes.createNode(this,n);

    var node = this;

    node.on('input',function(msg){
        if (msg._messageId && msg._applianceId && msg._confId) {
            var conf = RED.nodes.getNode(msg._confId);
            if (typeof msg.payload == 'boolean' && msg.payload) {
                conf.acknoledge(msg._messageId, msg._applianceId, true, msg.extra);
            } else {
                conf.acknoledge(msg._messageId, msg._applianceId, false, msg.extra);
            }
        }

    });
}

RED.nodes.registerType("alexa-home-resp", alexaHomeResponse);

RED.httpAdmin.use('/alexa-home/new-account',bodyParser.json());

function getDevices(username, password, id){
    if (username && password) {
        request.get({
            url: devicesURL,
            auth: {
                username: username,
                password: password
            }
        }, function(err, res, body){
            if (!err && res.statusCode == 200) {
                var devs = JSON.parse(body);
                //console.log(devs);
                devices[id] = devs;
            } else {
                //console.("err: " + err);
                RED.log.log("Problem looking up " + username + "'s devices");
            }
        });
    }
};

RED.httpAdmin.post('/alexa-home/new-account',function(req,res){
	//console.log(req.body);
	var username = req.body.user;
	var password = req.body.pass;
	var id = req.body.id;
	getDevices(username,password,id);
});

RED.httpAdmin.post('/alexa-home/refresh/:id',function(req,res){
    var id = req.params.id;
    var conf = RED.nodes.getNode(id);
    if (conf) {
        var username = conf.username;
        var password = conf.credentials.password;
        getDevices(username,password,id);
        res.status(200).send();
    } else {
        //not deployed yet
        console.log("Can't refresh until deployed");
        res.status(404).send();
    }
});

RED.httpAdmin.get('/alexa-home/devices/:id',function(req,res){
	if (devices[req.params.id]) {
		res.send(devices[req.params.id]);
	} else {
		res.status(404).send();
	}
});

};

nick9888 avatar May 17 '25 14:05 nick9888

updated

nick9888 avatar May 17 '25 14:05 nick9888

pi@raspberrypi:~ $ node-red-start

Start Node-RED

Once Node-RED has started, point a browser at http://10.0.0.208:1880 On Pi Node-RED works better with the Firefox or Chrome browser

Use node-red-stop to stop Node-RED Use node-red-start to start Node-RED again Use node-red-log to view the recent log output Use sudo systemctl enable nodered.service to autostart Node-RED at every boot Use sudo systemctl disable nodered.service to disable autostart on boot

To find more nodes and example flows - go to http://flows.nodered.org

Starting as a systemd service. TCP Timeout TCP Timeout TCP Timeout TCP Timeout

nick9888 avatar May 17 '25 14:05 nick9888

I'll need to see some log output after the change (and it's been running for a while) to be able to suggest anything useful

hardillb avatar May 18 '25 11:05 hardillb

Closing as no updates since May

hardillb avatar Nov 09 '25 18:11 hardillb