ewelink-api icon indicating copy to clipboard operation
ewelink-api copied to clipboard

multichannel devices, set/get powerstate inconsitent behavior

Open mduchain opened this issue 1 year ago • 0 comments

Hello All, Over the last few months I've been battling with inconsistent get/set states from one of my CH4. I use this to control irigation pumps and with the summer heat I had to figure out what was going on.

I figured out that the current ewelink-api code assumes that the "switches" array is order by channel. This is a wrong assumption! The channel = outlet number + 1. For one of my CH4 devices, the order in which the outlets are listed is mixed (2,3,1,0), while all others are (0,1,2,3).

So I modified the following pieces of code to make sure the mapping channel-outlet is respected.

  1. added a new function in ewelink-api/src/helpers/device-control.js, getMultiChannelSwitchIndex
...
const getMultiChannelSwitchIndex = (params, channel) => {

  let i=0;
  while (i < params.length) {
    const ch = params[i];
    if (ch.outlet == (channel-1)) {
      console.info("mc: channel" + channel + " in switches[" + i + "]");
      return i;
    }
    i++;
  }
};

module.exports = {
  STATE_ON,
  STATE_OFF,
  STATE_TOGGLE,
  VALID_POWER_STATES,
  getNewPowerState,
  getPowerStateParams,
  getAllChannelsState,
  getSpecificChannelState,
  getMultiChannelState,
  getMultiChannelSwitchIndex,
};

  1. modified ewelink-api/src/mixns/getDevicePowerState.js as follows:
    ...
    if (switchesAmount > 0 && switchesAmount < channel) {
      return { error: 404, msg: errors.ch404 };
    }
    console.info("getDevicePowerState");
    console.info(JSON.stringify(switches));

    if (switches) {
      //multichannel switches are not ordered by channel!!
      state = switches[getMultiChannelSwitchIndex(switches, channel)].switch;
    }

    return { status: 'ok', state, channel };
  },
};

  1. modified ewelink-api/src/mixns/setDevicePowerState.js as follows:
...
  let stateToSwitch = state;
  const params = {};

  if (switches) {
    //multichannel switch: channels == outlet, switches is not ordered!!
    const switchIndex = getMultiChannelSwitchIndex(switches, channel);
    status = switches[switchIndex].switch;
  }

  if (state === 'toggle') {
    stateToSwitch = status === 'on' ? 'off' : 'on';
  }

  if (switches) {
    const switchIndex = getMultiChannelSwitchIndex(switches, channel);
    switches[switchIndex].switch = stateToSwitch;
    params.switches = switches;
  } else {
    params.switch = stateToSwitch;
  }
...

Hope this helps for those of you that have multichannel devices acting weird.

mduchain avatar Jul 13 '24 09:07 mduchain