• 10 dec 2017: forum version update. In case of issues use this topic.
  • 30 nov 2017: pilight moved servers. In case of issues use this topic.
Hello There, Guest! Login Register


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Implement 433gpio send buffer to prevent interference
#1
I was reading the doc for the pilight-send command and it says issues can be reported on the github repo, but I don't see an issues page in that repo...  Is there a way to report bugs?  If so, where? And can the doc be updated?

Regarding the "bug".  I'm not even sure it's a bug with pilight.  I've been using pilight (pilight-send) for the better part of a year now to control 8 Etekcity outlets and I have been messing around with homebridge and node red to automate things.  I've discovered that if I try to turn more than one outlet on or off at a time, the result is erratic. Something always doesn't work.  Either I get an error or one of multiple outlets turns on and the others don't.

At first, I'd even forgotten I was running the pilight server and thought I needed a lock file or something so that the separate command instances don't mix together, but then I was looking at my install notes and the pilight-send command doc and realized that everything should theoretically be copacetic... but it's not.

So does the pilight server not manage the transmitter resource properly when the protocol is "raw"?  That's the hunch I had.
 
Reply
#2
OK, I'm more convinced this is a pilight bug now.

I edited my commands file that homebridge-commander uses to get the pilight-send commands.  I added a different amount of sleep time before each different command.  I used my 3 fans as a test.  The first one, I didn't call sleep.  The second one, I did `sleep 0.5 && pilight-send...`.  The third one, I did `sleep 1 && pilight-send...`.  Once I added those sleeps, my "fans scene" I created in the Home app started working whereas without the sleep, maybe one fan would turn on/off about 10% of the time.

I thought the whole point of using a server was to manage the transmitter as a resource so that multiple commands competing for the resource would not step on each other's toes.  It doesn't seem to work correctly in managing multiple pilight-send commands executed at roughly the same time.  Am I doing something wrong?  If not, how do I report this as a bug?
 
Reply
#3
The info bugs can be reported on github is indeed wrong. Will change that soon. I use the forum for bug tracking.

The bug you are reporting has been discussed earlier as well as the intended fix. If someone is willing to implement the fix i'm happy to integrate it. I didn't have time to do so myself.
 
Reply
#4
(07-10-2019, 06:17 PM)curlymo Wrote: The info bugs can be reported on github is indeed wrong. Will change that soon. I use the forum for bug tracking.

The bug you are reporting has been discussed earlier as well as the intended fix. If someone is willing to implement the fix i'm happy to integrate it. I didn't have time to do so myself.

Ok, great!  Sorry I failed to find the previous bug thread on this issue.  I'll just keep my sleep work-around until the fix is pushed out.  Is there a branch I can follow to get notified when the fix is merged?
 
Reply
#5
All work is done in the staging branch.
 
Reply
#6
Can you try if it works when you replace the contents of /usr/local/lib/pilight/hardware/433gpio.lua with this. A pilight restart is needed afterwards.



I was too simplistic Smile
 
Reply
#7
Please install the latest nightly tomorrow and replace /usr/local/lib/pilight/hardware/433gpio.lua with this code:
PHP Code:
--
-- 
Copyright (CCurlyMo
--
-- 
This Source Code Form is subject to the terms of the Mozilla Public
-- 
Licensev2.0. If a copy of the MPL was not distributed with this
-- fileYou can obtain one at http://mozilla.org/MPL/2.0/.
--

local dump = require "dump";
local lookup = require "lookup";

local M = {}

function 
M.send(timer)
    if timer == nil then
        return
;
    end

    local data2 
timer.getUserdata();
    local len_ data2.__len();

    local config pilight.config();
    local data1 config.getData();
    local platform config.getSetting("gpio-platform");
    local sender lookup(data1'hardware''433gpio''sender') or nil;

    local wx wiringX.setup(platform);

    if sender == nil then
        error
("sender parameter missing");
    end

    if len_ 
0 then
        local data 
data2[1];

        if sender >= 0 then
            local count 
0;

            for _ in pairs(data['pulses']) do
                count count 1
            end

            for i 
1data['txrpt'], do
                wx.digitalWrite(sender1data['pulses']());
            end
            
--
            -- Make sure we do not leave the GPIO dangling
            
-- in HIGH position.
            --
            if (count 2) == 0 then
                wx
.digitalWrite(sender0);
            end
        end

        for i 
1len_ 1do
            data2[i] = data2[i+1];
        end
        data2
[len_] = nil;

        timer.start();
    end
end

function M.pre_send(objreasondata)
    if reason ~= pilight.reason.SEND_CODE then
        return
;
    end

    if data
['hwtype'] ~= pilight.hardware.RF433 then
        return
;
    end

    if data
['pulses'] ~= nil and type(data['pulses']) == 'table' then
        local data2 
obj.getUserdata();
        local len_ data2.__len();

        if len_ == 0 then
            local timer 
pilight.async.timer();
            timer.setCallback("send");
            timer.setUserdata(obj.getUserdata()());
            timer.setTimeout(100);
            timer.setRepeat(0);
            timer.start();
        end

        data2
[len_+1] = data;
    end
end

function M.callback(objnrpulses)
    if obj == nil then
        return
;
    end
    local config 
pilight.config();
    local data config.getData();

    local pulse 0;
    local length 0;

    local minrawlen lookup(data'registry''hardware''RF433''minrawlen') or 0;
    local maxrawlen lookup(data'registry''hardware''RF433''maxrawlen') or 0;
    local mingaplen lookup(data'registry''hardware''RF433''mingaplen') or 0;
    local maxgaplen lookup(data'registry''hardware''RF433''maxgaplen') or 0;

    data obj.getUserdata();
    data['hardware'] = '433gpio';

    if data['pulses'] == nil then
        data
['pulses'] = {};
    end

    length 
#data['pulses'];

    for i 1nr 1do
        pulse pulses[i];
        length length 1;

        data['pulses'][length] = pulse;

        if length maxrawlen then
            data
['pulses'] = {};
            length 0;
        end
        if pulse 
mingaplen then
            if length 
>= minrawlen and
                length <= maxrawlen and
                ((length+>= nr and minrawlen == 0) or (minrawlen 0)) then

                data
['length'] = length;
                local event pilight.async.event();
                event.register(pilight.reason.RECEIVED_OOK);
                event.trigger(getmetatable(data)());

                data['pulses'] = {};
                length 0;
            end
            if length
+>= nr then
                data
['pulses'] = {};
                length 0;
            end
        end
    end
end

function M.validate()
    local config pilight.config();
    local platform config.getSetting("gpio-platform");
    local data config.getData();
    local obj nil;

    local settings lookup(data'hardware''433gpio') or nil;

    if settings == nil then
        return
;
    end

    for x in pairs
(settings) do
        if x ~= 'sender' and ~= 'receiver' then
            error
(.. "is an unknown parameter")
        end
    end

    local receiver 
data['hardware']['433gpio']['receiver'];
    local sender data['hardware']['433gpio']['sender'];

    if receiver == nil then
        error
("receiver parameter missing");
    end

    if receiver 
== nil then
        error
("sender parameter missing");
    end

    if platform 
== nil or platform == 'none' then
        error
("no gpio-platform configured");
    end

    obj 
wiringX.setup(platform);

    if obj == nil then
        error
(platform .. " is an invalid gpio-platform");
    end
    if receiver 
== nil then
        error
("no receiver parameter set");
    end
    if sender 
== nil then
        error
("no sender parameter set");
    end
    if type
(sender) ~= 'number' then
        error
("the sender parameter must be a number, but a " .. type(sender) .. " was given");
    end
    if type
(receiver) ~= 'number' then
        error
("the receiver parameter must be a number, but a " .. type(receiver) .. " was given");
    end
    if sender 
< -1 then
        error
("the sender parameter cannot be " .. tostring(sender));
    end
    if receiver 
< -1 then
        error
("the receiver parameter cannot be " .. tostring(receiver));
    end
    if receiver 
== sender then
        error
("sender and receiver cannot be the same GPIO");
    end
    if sender 
> -1 then
        if obj
.hasGPIO(sender) == false then
            error
(sender .. " is an invalid sender GPIO");
        end
        if obj
.pinMode(senderwiringX.PINMODE_OUTPUT) == false then
            error
("GPIO #" .. sender .. " cannot be set to output mode");
        end
    end
    if receiver 
> -1 then
        if obj
.hasGPIO(receiver) == false then
            error
(receiver .. " is an invalid receiver GPIO");
        end
        if obj
.pinMode(receiverwiringX.PINMODE_INPUT) == false then
            error
("GPIO #" .. receiver .. " cannot be set to input mode");
        end
        if obj
.ISR(receiverwiringX.ISR_MODE_BOTH"callback"250) == false then
            error
("GPIO #" .. receiver .. " cannot be configured as interrupt");
        end
    end
end

function M.run()
    local config pilight.config();
    local platform config.getSetting("gpio-platform");
    local data config.getData();
    local obj nil;

    local receiver lookup(data'hardware''433gpio''receiver') or nil;
    local sender lookup(data'hardware''433gpio''sender') or nil;

    if platform == nil or sender == nil or receiver == nil then
        return
;
    end

    obj 
wiringX.setup(platform);
    obj.pinMode(senderwiringX.PINMODE_OUTPUT);
    obj.pinMode(receiverwiringX.PINMODE_INPUT);
    obj.ISR(receiverwiringX.ISR_MODE_BOTH"callback"250);

    local event pilight.async.event();
    event.register(pilight.reason.SEND_CODE);
    event.setCallback("pre_send");

    return 1;
end

function M.implements()
    return pilight.hardware.RF433
end

function M.info()
    return {
        name "433gpio",
        version "4.1",
        reqversion "7.0",
        reqcommit "94"
    }
end

return M
Let me know if that delay is still necessary afterwards.
 
Reply
  


Possibly Related Threads...
Thread Author Replies Views Last Post
  Verify pilight send/receive function Rschnauzer 10 3,998 10-22-2019, 01:36 PM
Last Post: curlymo
  Send via wiringPI receive via LIRC? daenny 2 3,238 08-26-2013, 08:23 PM
Last Post: daenny

Forum Jump:


Browsing: 1 Guest(s)