HomeyScript for Wallbox Pulsar plus charger lock/unlock pause/resume

Hello

I added the script in Homeyscript but when i click on ‘test i’, i have this error message

:x: Script Error
:warning: TypeError: Cannot read properties of undefined (reading ‘split’)
at myWallbox.js:142:26
at processTicksAndRejections (node:internal/process/task_queues:96:5)

Any idea ?

Login / password and uid are verified.

I have the same script error when testing the copied script. Does somebody know how to solve this?

So since I’ve gotten the Wallbox I’ve been working on a specific Homey App. Which already contains the triggers and lock/unlock mechanism. I was waiting to work on the pause/resume functionality before I officially publish it. I think I can release a version 0.1.0 of this app this week.

For anyone interested in the code, please see the GH.

Will check it out later when both the app and my Homey will be in. Since we have two electric cars, we ran in the problem that we need two accounts to seperate sessions (private/business). So, we first need to login with the right account before charging. Will it be possible to create flows for different accounts or is it just possible within Homey to add two devices each with their own account attached.

Yeah that is definitely possible. When you add a charger, you will then have to login with your respective account to look the charger up and add it to Homey. So basically following the same procedure you can add chargers from two different accounts.

Good morning @rkokkelk ,

I installed your app, it’s awesome.

Did you have time to work on the /resume break?

Because I don’t want to work with WallBox planning to manage my loads.
Being French, I only recharge in “off-peak hours” from 11:30 p.m. to 7:30 a.m. and therefore this function interests me.

thanks in advance

The day before yesterday I lost connection to the app and since then I cannot log in. Whenever I try, I get a quick reply, “404”. e845a815-9a7f-40ac-8c0c-ae9e1697df8e

Same problem happend for me today

From today (and maybe yesterday) my flows can’t start the wallbox anymore. It gives an error that the device isn’t available at the moment. Restarted the app a few times, but nothing changed. When I open the wallbox app on my phone, everything seems to be working as it should.

I made a script with the help of our AI friends. I just updated it with the new API-mess-ups by Wallbox… For me it works fine. It’s not the most versatile script, but it reflects the right statusses (charging, connected,…) and you’re able to set the Amps and start or stop charging.

You need to run it with an argument via a flow. Possible arguments are ‘status’, ‘start’, ‘stop’, ‘set 6’ & ‘set 10’.

If you need anything extra (like set 16), I think the script will be easily adaptible.

I run the status every 3 minutes and set/start/stop whenever necessary. Running the script more often will probably work, but you will also run into temporary blockings from the API…

// === WALLBOX PULSAR PLUS - HOMEYSCRIPT (bijgewerkt juni 2026) ===

const username = 'login';       // myWallbox e-mail
const password = 'password'; // wijzig dit naar je nieuwe wachtwoord!
const MYCHARGERID = chargerid;

const API_BASE  = "https://api.wall-box.com/";
const URL_GROUPS      = 'v3/chargers/groups';
const URL_REMOTE      = `v3/chargers/${MYCHARGERID}/remote-action`;
const URL_SET_CURRENT = `v2/charger/${MYCHARGERID}`;

function toBase64(str) {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  let output = '';
  let i = 0;
  str = unescape(encodeURIComponent(str));
  while (i < str.length) {
    const a = str.charCodeAt(i++);
    const b = str.charCodeAt(i++);
    const c = str.charCodeAt(i++);
    const triplet = (a << 16) | (isNaN(b) ? 0 : b << 8) | (isNaN(c) ? 0 : c);
    output += chars.charAt((triplet >> 18) & 63) +
              chars.charAt((triplet >> 12) & 63) +
              (isNaN(b) ? '=' : chars.charAt((triplet >> 6) & 63)) +
              (isNaN(c) ? '=' : chars.charAt(triplet & 63));
  }
  return output;
}

async function getToken() {

  const auth = Buffer.from(username + ":" + password).toString("base64");

  const response = await fetch("https://user-api.wall-box.com/users/signin", {
    method: "GET",
    headers: {
      "Authorization": "Basic " + auth,
      "Partner": "wallbox",
      "Accept": "application/json"
    }
  });

  const raw = await response.text();

  let data;

  try {
    data = JSON.parse(raw);
  } catch (e) {
    throw new Error("Login is not JSON: " + raw);
  }

  if (
    !data.data ||
    !data.data.attributes ||
    !data.data.attributes.token
  ) {
    throw new Error("No token received: " + raw);
  }

  return data.data.attributes.token;
}

async function getStatus(token) {
  const response = await fetch(API_BASE + URL_GROUPS, {
    method: 'GET',
    headers: { 'Authorization': 'Bearer ' + token, 'Accept': 'application/json' }
  });

  if (!response.ok) {
    const err = 'Groups fout: HTTP ' + response.status;
    console.log(err);
    await tag('Wallbox_error', err);
    throw new Error(err);
  }

  const data = await response.json();
  let found = false;
  let chargerStatus = {
  status: 0,
  chargingPower: 0,
  maxChargingCurrent: 0,
  addedEnergy: 0,
  locked: false,
  online: false,
  isCharging: false,
  carConnected: false
};

  if (data.result && data.result.groups) {
    for (const group of data.result.groups) {
      if (group.chargers) {
        for (const ch of group.chargers) {
         if (ch.id === MYCHARGERID) {
  found = true;

const statusCode = ch.status || 0;

const isOnline = statusCode !== 0;

// Alleen werkelijk laden als er effectief vermogen loopt
const isCharging = (ch.chargingPower || 0) > 100;

// Auto verbonden?
const carConnected = statusCode !== 161;

chargerStatus = {
  status: statusCode,
  chargingPower: ch.chargingPower || 0,
  maxChargingCurrent: ch.maxChargingCurrent || 0,
  addedEnergy: ch.addedEnergy || 0,
  locked: ch.locked === 1,
  online: isOnline,
  isCharging: isCharging,
  carConnected: carConnected
};

break;
}

        }
      }
    }
  }

  if (!found) {
    const err = 'Charger niet gevonden in groups';
    console.log(err);
    await tag('Wallbox_error', err);
    throw new Error(err);
  }

  return chargerStatus;
}

async function startCharging(token) {
  const response = await fetch(API_BASE + URL_REMOTE, {
    method: 'POST',
    headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' },
    body: JSON.stringify({ action: 1 })
  });
  if (!response.ok) {
    const err = 'Start fout: HTTP ' + response.status;
    console.log(err);
    await tag('Wallbox_error', err);
    throw new Error(err);
  }
}

async function stopCharging(token) {
  const response = await fetch(API_BASE + URL_REMOTE, {
    method: 'POST',
    headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' },
    body: JSON.stringify({ action: 2 })
  });
  if (!response.ok) {
    const err = 'Stop fout: HTTP ' + response.status;
    console.log(err);
    await tag('Wallbox_error', err);
    throw new Error(err);
  }
}

async function setAmps(token, amps) {
  if (amps < 6 || amps > 32) {
    const err = 'Amps moet tussen 6 en 32 liggen';
    console.log(err);
    await tag('Wallbox_error', err);
    throw new Error(err);
  }
  const response = await fetch(API_BASE + URL_SET_CURRENT, {
    method: 'PUT',
    headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' },
    body: JSON.stringify({ maxChargingCurrent: amps })
  });
  if (!response.ok) {
    const err = 'Set amps fout: HTTP ' + response.status;
    console.log(err);
    await tag('Wallbox_error', err);
    throw new Error(err);
  }
}

if (!args || args.length === 0 || typeof args[0] !== 'string') {
  const err = 'Geef een argument: status | start | stop | set 6 | set 10';
  console.log(err);
  await tag('Wallbox_error', err);
  throw new Error(err);
}

const arg = args[0].trim().toLowerCase();

try {
  const token = await getToken();

  if (arg === 'status') {
    const status = await getStatus(token);
    await tag('Wallbox_status', status.status);
    await tag('Wallbox_chargingPower', status.chargingPower);
    await tag('Wallbox_maxCurrent', status.maxChargingCurrent);
    await tag('Wallbox_addedEnergy', status.addedEnergy);
    await tag('Wallbox_locked', status.locked ? 'true' : 'false');
    await tag('Wallbox_online', status.online ? 'true' : 'false');
    await tag('Wallbox_isCharging', status.isCharging ? 'true' : 'false');
    await tag('Wallbox_carConnected', status.carConnected ? 'true' : 'false');
    await tag('Wallbox_lastUpdate', new Date().toLocaleString());
    await tag('Wallbox_error', '');
    console.log('Status tags aangemaakt:', status);
    return 'Status opgehaald en tags gezet';

  } else if (arg === 'start') {
    await startCharging(token);
    await tag('Wallbox_lastAction', 'Gestart');
    await tag('Wallbox_error', '');
    return 'Gestart';

  } else if (arg === 'stop') {
    await stopCharging(token);
    await tag('Wallbox_lastAction', 'Gestopt');
    await tag('Wallbox_error', '');
    return 'Gestopt';

  } else if (arg.startsWith('set ')) {
    const ampsStr = arg.split(' ')[1];
    const amps = parseInt(ampsStr, 10);
    if (isNaN(amps)) throw new Error('Ongeldig amps: ' + ampsStr);
    await setAmps(token, amps);
    await tag('Wallbox_lastAction', `Set ${amps}A`);
    await tag('Wallbox_maxCurrent', amps);
    await tag('Wallbox_error', '');
    return `Set ${amps}A`;

  } else {
    throw new Error('Ongeldig argument: ' + arg);
  }

} catch (err) {
  console.log('Hoofdfout:', err.message);
  await tag('Wallbox_error', err.message);
  throw err;
}

@Arne_Sch @peav @Henrik_Oscarsson