Now to something completely different
Recently, I did some deeper investigations into mitigating SD card writes in OpenHABian. These checks and tools are described in this forum thread.
One of my findings was that a file maintained by the Signal binding was one of the largest contributors to write cycles: /var/lib/openhab/signal/data/<uid>.d/account.db
I found it being written almost once per second. Other than with the hueemulation binding, which does similar things, I could not retreive any information about what is actually changed / updated, as account.db is binary and no json file. This happens permanently, even when the Signal channel is acutally idle.
The resulting effect is actually the same: small chunks of data being written onto the main storage with a tremendous rate - the worst-case for SD card wearout.
As I said, I can only guess what kind of data is updated so frequently. But if itâs a API timestamp, it might be completely expendable. If not, or if itâs a rolling encryption key, it might be possible to keep in RAM or in a tmpfs like /run.
For now, I did some crazy symlink magic to keep it virtually together with the (practically never changed) other config files, but pull the account.db physically into the persistence ZRAM. Which is a good solution in my particular Raspberry Pi setup, but not everyone has ZRAM at all.
Therefore, @dalgwen I would be super grateful if you could have a look if the root cause of these write cycles could either be dropped or moved into RAM
First, thanks for the insightful informations and your investigation !
I have two observations:
I use a library, part of the signal-cli project, for all signal related functionalities. The database management is part of it, and so the code responsible for this regular write is not mine. So I canât answer why there are idle writes. I however opened an issue upstream, in the signal-cli project, to have more information.
I donât see the same behaviour as you. I see, for the account.db, a perfectly regular one write per minute when signal is idle. IMHO, it seems reasonable. But Iâm not very knowledgeable about SSD/sd-card overuse, and maybe there are arguments to consider this delay as an issue ?
Okay, so it comes from the upstream library⊠anyhow, I suppose they should be interested as their lib surely is used in many flash based machines, at least thatâs my hope?
I may have been mistaken by the way how often the writes occur, and I agree that from a functional point of view, one update per minute is absolutely reasonable.
But: Even one write per minute already is in the dark-red zone for flash writes!
I one had a weather station script (long before my OH time ) and it wrote one short line into a CSV file every three minutes. After two and a half years the SD card died from wearout.
Flash blocks are between 500k and 2M. Each write, even a few bytes, one of these blocks must be read, erased, changed and rewritten (conditions apply, more expensive âenduranceâ cards do way better wear levelling).
A flash block can be erased and written between 100k and 1M times, also depends on quality.
One year has 525600 minutes. And thatâs already the same order of magnitude, only for one process writing once per min. Thatâs the background.
The OH persistence has a default timebased of sample rate of once per minute. Thatâs why it is put into ZRAM. But I know, not everyone has ZRAM enabled, so therefore I would expect the Signal-cli project to consider storing such frequently updated contents in RAM or a tmpfs rather than on the main storage.
Hi, just FYI, maybe also interesting for the signal-cli guys.
I found I probably was mistaken about the 1s write cycle, but 1 minute is for real. In my other investigations about systemd-timesync also writing once per minute, I found warnings for SD card environments in the module docs (blue box âNOTEâ) that such cycles are problematic wrt. flash wear. So itâs definitely an issue.
Hi, I just upgraded to OH 5.0.3, and thereâs no Signal add-on displayed in the store anymore. Is there some version number which needs to be bumped up to match?
Restarting, Restarting, stopping the service, starting the service. Yup.
But thatâs probably related to the epic threadpool overflow issue which is mentioned at several places, not to this binding, as it came along with all event based triggers not working / working again.
Thanks for the quick reply, anyway!
2026-01-15 18:14:06.483 [WARN ] [gnal.internal.protocol.SignalService] - Signal get an exception while receiving message: org.signal.libsignal.protocol.InvalidMessageException: protobuf encoding was invalid
Yes, I got it too.
Despite being just several month old, the libsignal-client version used for this binding seems to be no longer supported (unfortunately, signal protocol frequently changes).
So it seems that receiving messages is broken (sending is still OK though).
Two weeks ago (so, not directly related to this, but because I do it regularly to prevent this kind of protocol update issue), I tried to update the signal-cli version. And bad news, I didnât manage to have a working binding with a new version. I spent probably 15+ hours on this . I only found that in one of the last version, integration of the native lib with an OSGi runtime is broken (a âregularâ java application is fine though). Absolutely no clue why.
So, as signal changing its protocol, and depending too much on library version changes, are the two things seriously getting on my nerves, I decided to stop being âsmartâ and instead of using signal-cli as a library, I will try to use it in âbrute forceâ mode.
It means that I will design this binding to use the full signal-cli binary, as an external process, and communicate with it with its socket feature.
I hope to do so in a transparent way (you wonât have to manage downloading, executing it as a daemon, etc), but it means:
not so good integration (external process will consume more memory/cpu and I have less control on it)
I have a good chunk of work to do. Will try to do it on top priority
Once done, maybe less work for me for updates ? (I may add an automatic âdownload new signal-cli versionâ feature). And so hopefully less breaking period like this one.
The binding will be lighter, as it wonât include all binaries and will only download what is necessary in the data dir. (but the user data dir will be bigger )
As it wonât be a gigantic bundle anymore, it may be a candidate for an official inclusion in openHAB.
No promise, no date for the next version, but I will try to be as fast as possible.
Argh, that sounds painful. Yes, I remember that you always struggled to keep pace to Signalâs API changes. No good style from their side, but even more thanks to you!
At least that relieves me from worrying about having broken my OH installation as I am currently doing hardcore tests with the Shelly binding.
Just FYI, the Matter binding does a very similar thing (running matter.js and providing a WebSocket-based RPC), so using signal-CLIâs HTTP-based RPC is perfectly fine IMO. It will be less overhead than running signal-cli-rest-api in Docker.
I would absolutely love to see that! The upgrade process (which I do quite often) is way more comfortable with official distribution add-ons.
is this OK for an official add-on to download some external code ? I want to ease the process of choosing/upgrading the signal-cli version and the related inclusion of libsignal binaries, so ideally the add-on would be able to fully manage the lifecycle.
If an add-on needs an update, outside of standard openHAB lifecycle, what is the official process, (and the inevitable delay) ?
Iâm also thinking about something else. The add-on could periodically check some page displaying information about the current signal-cli version to use (which is compatible with its codebase). But Iâm wondering 1- if itâs a good idea, and 2- where to host such information ? The goal is to be fully automatic and transparent on the upgrade.
Just so you know all, Iâm not dead and Iâm still working on an update.
For now, I got this working:
running external signal-cli process and all the wiring for exchanging json rcp message with it.
ability to connect to a remote signal-cli instance (tcp)
sending / receiving signal message for already registered account
And I still need to do this:
automatic download of signal-cli (partial work done)
the more important : ability to register new account with the same procedure as now
IMO yes. The Whisper TTS add-on also does this due to licensing => we canât bundle the GPL-3.0 licensed binaries with openHAB (EPL-2.0), so they will be downloaded at runtime. And JRuby/Python Scripting download their helper libraries at runtime (this is our code, but still they download code).
Update for the current development version and ask for backporting the changes to the backport branch. We are building patch releases from time to time, and if thereâs a good reason (e.g. broken binding), we have a reason to do it soon.
Ideally, we host everything that openHAB depends on ourselves. In case of signal-cli this would mean to upload the binary to our JFrog artifactory (havenât uploaded binaries before though). openHAB could then check our JFrog for available versions and download a new one if available. By hosting it ourselves, weâd also have full control what is available to openHAB.
I would vote though to only make it do that on startup and user trigger.
I can experiment a bit with uploading stuff to JFrog.
Double for your work, @dalgwen !
I am really looking forward to installing the new version once youâre done with it!
As a little reminder Remember my request concerning SD card frequent writes. I noticed that your inquiry to the signal-cli project was actually responded and they reduced the writing frequency!
I would be very pleased if you just keep such things in mind, and it would be a nice thing to know the locations where the external lib writes its data into
Something different: on my OH 5.1 i surprisingly lost my Signal Binding and canât find it in the Add-Ons to reinstall. Does anybody know how that could have had happened?
I updated my system from 5.1.1 to 5.1.3 â now I could reinstall the Signal-Add-on from the add-on-Store.
BUT: It still doesnât work. The Signal Linked device says: âIOException - org.asamk.signal.manager.api.AccountCheckException: Error while checking account +49xxxxxxxx: Closed unexpectedlyâ
and in the logs: âCannot send message to +49xxxxxxxx, cause : no manager running/initializedâ