External integrations in Gladys Assistant

For the « Force Update » button, are you sure you installed the integration with the correct manifest?

Did you copy the manifest from the build?

Oh dear, oh dear, oh dear, it’s working way too hard here

Yes, in this case, 100% sure.

The only time the manifest changed, I found it logical and instinctively deleted and recreated it. If it’s possible in dev, to modify the manifest directly from the integration or even better if it checks/reloads itself would be even better (especially for testers), but here I’m just asking about feasibility ^^

And in this case:

  • If no production image (Tuya), the dev update creates an error:

  • If a production image is active (Zendure), the container update loads the production image and overwrites the dev (annoying ^^) => See the Docker image version below after clicking update vs the address http://10.5.0.227:1444/dashboard/integration/device/external/ext-dev-zendure-2/config which indicates that I was on the dev image


    => the production address is http://10.5.0.227:1444/dashboard/integration/device/external/ext-terdious-gladys-zendure/config

Ouch ^^ :face_with_peeking_eye:

Concretely, all manufacturers of consumer batteries (Anker, Zendure, EcoFlow, Marstek, Bluetti…) offer:

  • solar batteries (with PV inputs),
  • simple batteries (without PV inputs).

So the category is not specific to Zendure (the name in the title is just the integration that originated the need) — on the contrary, it makes it reusable for all storage batteries. The PR focused on solar batteries, but we can certainly cover both cases.
And indeed the remarks of GPT5.6.
I am updating the PR in this regard.

For information:
Generic names (no Zendure terms), aligned with VE/Gladys.

State of charge

Type Meaning Unit
battery-level State of charge percent

Powers (instantaneous, ≥ 0)

Type Meaning Unit
charge-power Power entering the battery watt / kilowatt
discharge-power Power exiting the battery watt / kilowatt
solar-input-power PV input watt / kilowatt
output-power Total to the house (direct PV + discharge) watt / kilowatt
grid-power Grid import watt / kilowatt
off-grid-power Off-grid output (backup) watt / kilowatt

Energies (cumulative counters) + state

Type Meaning Unit
charge-energy Total energy charged kilowatt-hour
discharge-energy Total energy discharged kilowatt-hour
solar-energy Total solar energy kilowatt-hour
output-energy Total energy provided to the house kilowatt-hour
grid-energy Total energy imported kilowatt-hour
off-grid-energy Total off-grid output energy kilowatt-hour
available-energy Current available energy (instantaneous) kilowatt-hour

UNITS_BY_CATEGORY['battery-storage'] = [PERCENT, WATT, KILOWATT, WATT_HOUR, KILOWATT_HOUR], default by type: percent (level), watt (powers), kilowatt-hour (energies) — which addresses the reviewer’s fallback point. And category added to isSensorCategory.

  • Integration store updated with the new manifest format, so you can go ahead @Terdious if you want to publish Tuya or Zendure
  • SDK updated to v0.5.0 ( changelogs )
  • JS template updated with the SDK v0.5.0
  • Gladys updated in #2665 with all the latest features, and a fix for the « Force update » button :slight_smile:

Don’t hesitate if you have any questions :slight_smile:

A small new feature to avoid having to wait 1 hour between each integration store submission, I created a small npx tool to validate locally (or let your AI agent validate) that an integration passes the validation rules well:

npx github:GladysAssistant/integration-store

To read on the store’s README.

I’m updating the JS template

@Terdious, is there anything else you need for Zendure, Tuya, Netatmo, Shelly, or other integrations?

My goal is to release a first V1 next week. The idea is obviously not to cover all cases right away, but to have a solid foundation on which we can iterate. If we can already offer some integrations at that point, that would be really great! :heart_eyes:

We think so yes!! At least for v1 without a doubt ^^ Thanks a lot !!!

Of course, I’m aware of that, it would be impossible anyway to determine all current and future needs without iterating on them ^^
I think that for a V1, everything that is already proposed is sufficient! Proof, I’m making almost everything work!!

Listen, I’m on SDK 0.5.0, and it works!!^^

Well, it has made quite a few modifications in the meantime, so I assume it was on our side. UDP works on 6 out of 10 devices, and the others will need to be added manually. And it was already the case with the Tuya Core integration, so we’re good!!
:sweat_smile: :clap: :star_struck:

Edit: Well, that was me, now I’ll let Claude speak :joy: It’s clever, it gives more work to do :partying_face::
YES, I read the entire SDK 0.5.0 (via your fork, in my scope) — and it’s huge: PG has industrialized almost everything we discussed. Three game-changers that directly impact our roadmap:

SDK 0.5.0 New Feature What It Does Solves
publishTransports() + DEVICE_TRANSPORTS + manifest transports:["local","cloud"] Local/cloud/unreachable badge per device (sticker) rendered by the core; and when both channels are declared, the core displays a standard « Prefer local » toggle delivered as a reserved key GLADYS_PREFER_LOCAL #8 + our point 3 (our custom local_mode becomes standard!) — it’s exactly what we argued to PG
publishDiscoveredDevices now does an UPSERT of the params of an already created device (changing DHCP IP, cloud→local…) without touching the name/features; a structural change displays the « Update » button No need to delete/recreate C (the lack of « update params ») + DHCP churn
Manifest actions + onAction(key, cb) with the example detect_protocol (manually entered IP → protocol detection, timeout_seconds up to 120 s) Action button with displayed result #7 (devices not seen by UDP: manual IP + detection)

Also available as a bonus: onGetImage/publishCameraImage (cameras/doorbells), OAuth2 (onOAuthAuthorizeUrl/onOAuthCallback, Netatmo-style), sub-containers (getContainers/startContainer + onHardwareUpdated), setConnectionStatus (app connection status).

What This Implies for Us (Big but in a Good Way)

We should migrate to the standard model:

  1. replace our custom local_mode config with transports:["local","cloud"] + reading GLADYS_PREFER_LOCAL (my « toggle live » model from earlier plugs right into it);
  2. call publishTransports on each poll to display the local/cloud/unreachable badge (and our circuit-breaker → unreachable);
  3. add the detect_protocol action for unscanned devices;
  4. take advantage of the param upsert: our re-scan at the toggle now really updates existing devices (including IP) → we can remove the resolveDevice/mergeParams workaround in the long run.

BUT it depends on what the core branch you’re running actually implements (transports, GLADYS_PREFER_LOCAL, onAction, upsert). Before migrating, I want to read your core.

Excellent !! :grin:

I would be very curious to hear your feedback on Netatmo and Frigate afterwards

Netatmo is normally covered, there is a whole OAuth management.
Frigate is also managed with sub-container management.

@ProtZ do you think the Nuki integration could become an external integration? :slight_smile:

@cicoub13 Same for TP-Link!

@bertrandda let’s see what we do for Airplay and Google Cast :slight_smile:

It is now possible to favorite a community integration:

If anyone wants to test the external integrations, here’s a Docker build (amd64 only):

ghcr.io/gladysassistant/gladys-preview:claude-magical-turing-qhh7q2

The image is automatically updated with all the developments I make :slight_smile:

The documentation is up to date!

In French:

In English:

Bravo for all the work done on this architecture that will unlock so many worlds
There’s just one detail that bothers me :thinking:
Before, an integration developed by someone was integrated into Gladys and other developers or you @pierre-gilles could come and fix or evolve it if the main developer didn’t have time or was no longer responding.
In the future, with these external integrations, what happens if an integration is no longer maintained? Does it become unusable? Do we need to fork it and ask people to migrate manually?

A bonus question? How do you decide whether an integration should be external or internal?

Yes, one can certainly imagine a fork in this case. And if an integration becomes very popular with a real demand for simplified migration, we could consider a migration process to support users.

The idea is also that the community can easily take over an abandoned integration: since everything is open and decoupled from the core, maintenance is no longer solely my responsibility.

Apart from truly “universal” integrations (Matter, Zigbee, MQTT…), for me, almost everything that can be external should be. :slight_smile:

What surprises me the most with this new system is how identical the user experience is to a native integration. With Fable 5, we’ve managed to create an experience where, from the user’s perspective, there’s virtually no difference between an internal and an external integration.

On the other hand, for the project, the difference is huge: contributions can be made in parallel without requiring my time, and the experience is standardized across integrations.

Honestly, I wouldn’t be surprised if we reach several hundred integrations in the coming months thanks to this approach. :slight_smile:

OK, thanks for the answers.
I’m a bit worried about the quality of external integrations and, as a result, user perception of Gladys. One of Gladys’s strengths is its stability.
Even if the installation points to an external repo (and the Docker containers are secured to not affect the Gladys instance), users will come here saying Gladys doesn’t work.
Home Assistant has implemented an integration scoring system to guide users on their quality. Are we heading in that direction too?

This is a legitimate concern, and we will indeed need to be vigilant about it. But today, we actually have the opposite problem: a lack of integrations :grinning_face_with_smiling_eyes:

Since the beginning of v4, this has probably been the number one complaint: many users would like to use Gladys, but their devices are simply not supported.

In the long run, if we manage to have hundreds of external integrations, I think we will indeed need to implement mechanisms to help users make their choices: ratings, comments, maintenance indicators, number of users, last published version, etc.

But let’s not put the cart before the horse :wink: The priority today is to have a much broader ecosystem of integrations. We can then build the necessary tools to maintain overall good quality.

Ok, I’ve made progress on the « Communication » type integrations (e.g.: Telegram), and it’s available in SDK v0.6.0.

I just ported the Telegram integration with Fable in one go, and it works perfectly.
I even find the experience better than the integration we have in Gladys :joy:

The Github repo:

Is it possible to have an ARM v8 build?