[APP][Pro] go-e Charger

Technically the pro model should work with the same functionality as the Gemini models, so they could be paired with Homey. However it is untested and pro-specific features are not supported at this time. I need some funding arranged to get my self also a Pro model to be able to add any additional functionality for it.
See first post about how to support.

Hi! i have two EV’s. Leaf and Polestar. I need to change phases and amperes for the night depending witch car is connected. I tried Homey Polestar app but it®s no good for this. Could this be solved with RFID- tags? I tried but I couldn’t figure out how.

There is a User Card capability tag available for go-e Chargers using v2 API. However there are no events yet for it (no triggers). You could use Device Capabilities app to monitor the change of that capability.

1 Like

This worked perfectly for me! Thanks!

1 Like

Anyone tested? Works with homey app?

Doesn’t look like there is any API-changes that would impact.

1 Like

Hello,

I’m looking for an example of an advanced flow for Go e Gemini EV-charger with loadbalancing. On the P1 port of my digital counter, I have a Homewizard-dongle. I would limit the peak current of my total house consumption, while loading my electric car. I would also have the option to limit the load capacity - for example: loading has to stop at 90% of the battery capacity. And I have also another very important question: what to do with the Go e app on my mobile?

Thank you so much for your help!

There are several topics in this forum for generic load balancing flows. Such flows examples can be used in your case.

@Picsou621 has had great success in optimizing. For example have a look at Charging EV with Advanced Flows .

One note, that the EV charger does not know what is the percentage of charge in the car. You would need a car make/model specific app to read the state of charge.

Hello, will you plan add also go-e Charger PRO CORE? I bought one a week ago and I want to add it to my homey

helllo, it seems that it’s not working with new go-e charger pro core or I did something wrong. I allowed API v2, I was able to add device to homey but all values are empty - not updating

From Homey Mobile app, please go to 
 More → Apps and find the go-e Charger app. Then go to settings of the app from the gear icon and Create Diagnostic Report.

Hopefully the log will give me some idea why is not working.

Additionally, if you could check how it advertises itself in the network:

It could be that it is not recognized as it is a new model.

here is diagnostic report id = bd7f7dd1-4f60-43bc-b123-593fc15fbbad

and here is screenshot from bonjour discovery

Thank you, that will help me to introduce the model specific driver. But it won’t fix your problem.

based on the diagnostics report, the app is connecting to the go-e charger, but gets a “bad request” response from it.

Please try this and replace the IP-ADDR of your go-e Charger
http://IP-ADDR/api/status?filter=sse,fna,car,alw,acs,frc,trx,err,wh,pha,nrg,eto,tma,amp,ama,cbl,fsp

That should return a JSON formatted response. If not, then the API is not activated properly with the go-e mobile app.

Hello, here is result. It seems that it’s working

Hmm, this is becoming interesting. I will need to contact go-e to get some information on why the new Core/Pro models rejects the request when called from the app, but not from a browser.

FYI - It can help you.I tested api via homeyscript to set values for virtual device and it works correctly .

Could you share your HomeyScript. It just might help. There is something with the http request generated in the app making the charger to reject it.

of course - it was written in collaboration with Chat gpt

/**
 * go-e → AVD sync (capability auto-detect + DC app fallback)
 * - ZobrazĂ­ capability zoznam AVD (ID + title)
 * - NĂĄjde capability podÄŸa ID alebo podÄŸa title
 * - Zápis: setCapabilityValue → fallback cez Device Capabilities app (setvalue)
 */
const CFG = {
	IP: '192.168.88.24',
	AVD_NAME: 'Wallbox',
	STORE_KEY: 'DeviceCapabilityVirtualDevice_20',
	DEBUG: false,
	// Tu MĂ”ĆœEĆ  uvĂĄdzaĆ„ buď skutočnĂ© capability IDs (napr. ‘measure_power’),
	// alebo presnĂ© TITULKY polĂ­ v AVD (napr. ‘Vykon’, ‘Prud’...).
	CAP: {
		current: 'Prud',
		power: 'Vykon',
		allowText: 'Povolenie',
		state: 'Stav',
		error: 'Chyba',
		session: 'Session',
		total: 'Total',
	},
};

function dbg(...a) {
	if (CFG.DEBUG) log('[goe - avd]', ...a);
}
// — tvoje fetchovanie z predoĆĄlĂ©ho skriptu (skrĂĄtenĂ© na podstatnĂ©) —
async function fetchJson(url) {
	const t0 = Date.now();
	const res = await fetch(url);
	const t = Date.now() - t0;
	dbg(`Fetch ${url} → ${res.status} in ${t}ms`);
	if (!res.ok) throw new Error(`HTTP ${res.status}`);
	return res.json();
}

function carToText(car) {
	const c = Number(car);
	return c === 2 ? 'nabĂ­ja' : c === 3 ? 'čakĂĄ na vozidlo' : c === 4 ? 'hotovo(auto pripojenĂ©)' : 'pripravenĂ©(bez vozidla)';
}

function errToText(err) {
	const e = Number(err);
	if (!e) return 'OK';
	const map = {
		1: 'RCCB',
		3: 'Chyba fĂĄzy',
		8: 'ChĂœba zem',
		10: 'InternĂĄ chyba'
	};
	return map[e] ? 'Chyba ${e}' : sdf;
}
// ---------------------------------------------------------------
// v2 bez filtra (u teba funguje)
const STATUS_URL = `http://${CFG.IP}/api/status`;
	async function resolveDeviceIdByName(name) {
		// 1) skĂșsiĆ„ uloĆŸenĂ© id
		const cached = global.get(CFG.STORE_KEY);
		if (cached) {
			dbg('Using cached deviceId: ', cached);
			return String(cached);
		}
		// 2) hÄŸadaĆ„ podÄŸa nĂĄzvu
		const devices = await Homey.devices.getDevices(); // map id->device
		const list = Object.values(devices);
		const match = list.filter(d => d.name === name);
		if (match.length === 1) {
			const id = match[0].id;
			global.set(CFG.STORE_KEY, id);
			dbg('Matched AVD by name:', name, '→', id);
			return id;
		}
		const all = list.map(d => `‱ ${d.name} (${d.id})`).join('\n');
		throw new Error(match.length === 0 ?
			`NenaĆĄiel som zariadenie s nĂĄzvom “${name}”. DostupnĂ©:\n${all}` :
			`NaĆĄiel som viac zariadenĂ­ s nĂĄzvom “${name}”. Uprav CFG.AVD_NAME tak, aby bol jedinečnĂœ.`);
	}
// Pomocník: vypíơe capabilities a vráti mapu {id → {title,type}}
function listCapabilities(device) {
	const map = {};
	const ids = device.capabilities || `[ ]`;
	ids.forEach(id => {
		const obj = device.capabilitiesObj[id] || {};
		map[id] = {
			title: obj.title || id,
			type: obj.type
		};
	});
	// Log pekne zoradenĂœ pre kontrolu
	const lines = Object.entries(map).map(([id, meta]) => `‱ ${id}  —  “${meta.title}”  (type=${meta.type||'?'})`);
	dbg('AVD capabilities: \n' + lines.join('\n'));
	return map;
}
// NĂĄjde capability podÄŸa presnĂ©ho ID alebo podÄŸa titulku (bez diakritiky/porovnanie case-insensitive)
function normalize(s) {
	return String(s || '').toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, '').trim();
}

function resolveCapIdByIdOrTitle(device, desired) {
	const caps = listCapabilities(device);
	const wanted = normalize(desired);
	// 1) priama zhoda ID
	for (const id of Object.keys(caps)) {
		if (normalize(id) === wanted) return id;
	}
	// 2) zhoda podÄŸa title
	for (const [id, meta] of Object.entries(caps)) {
		if (normalize(meta.title) === wanted) return id;
	}
	dbg(`WARN: Nenaơiel som capability pre “${desired}”`);
	return null;
}
// Fallback zĂĄpis cez appku Device Capabilities (oficiĂĄlny spĂŽsob AVD)
async function setViaDeviceCapabilitiesApp(deviceId, fieldId, value) {
	try {
		const dcApp = await Homey.apps.getApp({
			id: 'nl.qluster - it.DeviceCapabilities'
		});
		await dcApp.post({
			path: 'setvalue',
			body: {
				device: deviceId,
				field: fieldId,
				value
			}
		});
		dbg(`DC-app setvalue OK: ${fieldId} =`, value);
		return true;
	} catch (e) {
		dbg(`DC-app setvalue FAIL ${fieldId}:`, e.message);
		return false;
	}
}
// NajbezpečnejĆĄĂ­ zĂĄpis: skĂșsiĆ„ setCapabilityValue, ak spadne → DC app
async function safeSetCapability(device, fieldId, value) {
		if (!fieldId) return;
		try {
			await device.setCapabilityValue(fieldId, value);
			dbg(`setCapabilityValue OK: ${fieldId} =`, value);
		} catch (e) {
			dbg(`setCapabilityValue FAIL ${fieldId}:`, e.message);
			await setViaDeviceCapabilitiesApp(device.id, fieldId, value);
		}
	}
	(async () => {
		dbg('-- -- - RUN START-- -- - ');
		// 1) načítaj status
		const j = await fetchJson(STATUS_URL);
		// odvodené hodnoty
		const currentA = Number.isFinite(Number(j.amp)) ? Number(j.amp) : null;
		let powerkW = null;
		if (Array.isArray(j.nrg) && j.nrg.length > 11 && Number.isFinite(Number(j.nrg[11]))) {
			powerkW = Number((Number(j.nrg[11]) / 1000).toFixed(2));
		} else if (j.tpa != null && Number.isFinite(Number(j.tpa))) {
			powerkW = Number((Number(j.tpa) / 1000).toFixed(2));
		} else if (j.pwr != null && Number.isFinite(Number(j.pwr))) {
			powerkW = Number((Number(j.pwr) / 1000).toFixed(2));
		}
		const allow = Number.isFinite(Number(j.alw)) ? Number(j.alw) : (j.alw === true ? 1 : 0);
		const stateText = carToText(j.car);
		const errorText = errToText(j.err);
		let sessionkWh = null;
		if (j.dws != null && Number.isFinite(Number(j.dws))) {
			sessionkWh = Number((Number(j.dws) / 360000).toFixed(3));
		} else if (j.wh != null && Number.isFinite(Number(j.wh))) {
			sessionkWh = Number((Number(j.wh) / 1000).toFixed(3));
		}
		const totalkWh = (j.eto != null && Number.isFinite(Number(j.eto))) ?
			Number((Number(j.eto) / 1000).toFixed(1)) :
			null;
		dbg('Derived: ', {
			currentA,
			powerkW,
			allow,
			stateText,
			errorText,
			sessionkWh,
			totalkWh
		});
		// 2) AVD
		const deviceId = await resolveDeviceIdByName(CFG.AVD_NAME);
		const device = (await Homey.devices.getDevices())[deviceId];
		if (!device) throw new Error(`DeviceID ${deviceId} neexistuje`);
		// 3) premapuj nĂ­m zadanĂ© menĂĄ/IDs na skutočnĂ© capability IDs
		const map = {
			current: resolveCapIdByIdOrTitle(device, CFG.CAP.current),
			power: resolveCapIdByIdOrTitle(device, CFG.CAP.power),
			allow: resolveCapIdByIdOrTitle(device, CFG.CAP.allowText),
			state: resolveCapIdByIdOrTitle(device, CFG.CAP.state),
			error: resolveCapIdByIdOrTitle(device, CFG.CAP.error),
			session: resolveCapIdByIdOrTitle(device, CFG.CAP.session),
			total: resolveCapIdByIdOrTitle(device, CFG.CAP.total),
		};
		dbg('Resolved capability IDs: ', map);
		// 4) zápis (safeSet → ak treba DC app)
		await safeSetCapability(device, map.current, currentA);
		await safeSetCapability(device, map.power, powerkW);
		await safeSetCapability(device, map.allow, allow ? 'Áno' : 'Nie');
		await safeSetCapability(device, map.state, stateText);
		await safeSetCapability(device, map.error, errorText);
		await safeSetCapability(device, map.session, sessionkWh);
		await safeSetCapability(device, map.total, totalkWh);
		// 5) info do logu
		dbg('DONE for device', device.name, deviceId);
		return JSON.stringify({
			deviceId,
			map,
			currentA,
			powerkW,
			allow,
			stateText,
			errorText,
			sessionkWh,
			totalkWh
		});
	})().catch(e => {
		log('[goe - avd] ERROR: ', e.message);
		throw new Error(e.message);
	});```