Signal Binding

You can always register, even on phone number previously used, without “unregistering”.
The new process simply disables previous registrations.

The BETA4 does this two steps request for you, and it seems that it can use the same captcha, so no action required (except waiting longer for the registration to process, at least a minute). I made a test and it seems to work.

I’m now used to and if it works,I don’t try to understand anymore :sweat_smile:

Hi @dalgwen , When you are doing the captcha, what exactly do you need to paste in? I get a link to open Signal that has a UUID and then a very long generated string. Does the binding want the entire URL pasted including signalcaptcha://signal-hcaptcha ? Or is this not even what it is looking for?

Everything I try gets a 422 Error: NonSuccessfulResponseCodeException - [422] Bad response: 422

Thanks
Jim

Hi All,

i have a question on setting it up with multple rule files.
Do i always have to register the bridge in every rule like this:

rule "Switch Change Notification"
when
    Item NewItem changed
then
    val signalAction = getActions("signal","signal:signalaccountbridge:701746fc6b")
signalAction.sendSignal("+332121212121212", "Alert !")

end

or can this part(val signalAction = getActions(“signal”,“signal:signalaccountbridge:701746fc6b”)

Blockquote

be “outsourced” in a central location like things or item file?
Like

rule "Switch A Change Notification"
when
    Item NewItem changed
then
signalAction.sendSignal("+332121212121212", "Alert in rule 1")
end

rule "Switch B Change Notification"
when
    Item NewItem changed
then
signalAction.sendSignal("+332121212121212", "Alert a in rule 2")
signalAction.sendSignal("+332121212121212", "Alert b in rule 2")
end

rule "Switch C Change Notification"
when
    Item NewItem changed
then
signalAction.sendSignal("+332121212121212", "Temp var in rule 3")
end

I have the feeling that OH3&4 are not intializing the bridge properly on startup and it hangs often. And i think its because i register the bridge in every rule.

Any hint is highly appreciated

Hello,

Sorry for the delay.
You have to copy paste everything, including signalcaptcha://signal-hcaptcha.
It is very long indeed. I just tried to register another number today and it worked.
Mine was something like this :
signalcaptcha://signal-hcaptcha.5fad97ac-7d06-4e44-b18a-b950b20148ff.registration.P1_eyJ0eXAiOiJKV1QiLCJ[......................]F8izmndtjI9C9dCoVUQmlJ_k
(edited in the middle because, as I said, very long)

Did you try again since then ? It could be a temporary issue on the registering server (not the first time)

I outsource mine as a “script” in ECMAScript-2021. It is defined in the UI, but I think it is the same with a file in the script directory :

var { actions } = require('openhab');
actions.Things.getActions("signal", "signal:signalaccountbridge:bab72f1f7d").sendSignal("+33123456789", notificationtext)

notificationtext is a context variable that is setted when I call the script from something else.
For example, to call it, I use it from blockly (“run rule or script with context” in “openHAB” “runProcess” block section).

For information, it transcripts to this jsr javascript code :
ruleManager.runNow('notification', true, convertDictionaryToHashMap({'notificationtext': 'Hello Word'}));

And the convertDictionaryToHashMap function is defined like this :

function convertDictionaryToHashMap (dict) {
  if (!dict || dict.length === 0) return null;
  var map = new java.util.HashMap();
  Object.keys(dict).forEach(function (key) {
    map.put(key, dict[key]);
  });
  return map;
}

(again, it is not my code but the blockly transcription)

I’m not 100% sure, but I don’t think it’s feasible from a rule in the rule DSL.

BUT, you can also check ideas here for a great post by the greatest forum member here. .

For all practical purposes they can be thought of as the same. However, they are actually quite different.in some ways but those don’t matter here.

But this is actually a relatively recent situation. Prior to a change to core that loaded everything from the Script folder and treat it like a rule, the only way to execute a Rules DSL Script was through the callScript Action.

I don’t see anything here that can’t work with Rules DSL.

Maybe, most dedicated?

I keep running into old post /dead end when I search “run script from rule”, and so my claim was about calling a script with argument from a rule (DSL), the same way we can do it from jsr script.
For example Here it is said that you can’t use argument when calling script from rule.
But I think, as I see you saying several time, “script” is a little bit misleading, and you can indeed do everything with pattern like the ones you made.

And humble, too ! :smile:

The term “script” is way overloaded in OH. See Rules | openHAB

Back when that design pattern was written, it only had one meaning and that was a Rules DSL .script file called with the callScript action. You couldn’t have a rule that called another rule. UI rules were not a thing so there were not UI Script rules or Script Actions.

Hi @dalgwen and thanks for you reply.
So what i understand is, that you can use a script and rules to fire up a signal message.
However you cannot pass on own text in terms of a value.
Now my ultimate goal is to call a global function like the below from any rule since i need my own messages and not states of items etc.

sendSignalMessagetoMyPhone(textvariablecomeshere)

I also checked Design Pattern: Separation of Behaviors but it doesnt look like that i can use the signal binding.

Any clues?

Yes you can and @dalgwen demonstrates how to do it. You create a map and pass that map as the third argument in the call to runNow. Each entry in the map will be injected into the called rule as a variable.

That’s what the whole convertDictionaryToHashMap stuff is all about. Though I wonder why that’s strictly necessary. At least in JS Scripting (the replacement for Nashorn JS) it isn’t. Here’s a call from one of my rule tempaltes.

        rules.runRule(ruleID, {'alertItem':        record.name,
                               'alertState':       ''+state,
                               'isAlerting':       isAlerting,
                               'threshItems':      allAlerting,
                               'threshItemLabels': alertingNames,
                               'nullItems':        nullItems,
                               'nullItemLabels':   nullItemNames}, true);

??? There must be something missing from your understanding of either that design pattern or OH itself.

At a high level that design pattern says: Command a String Item with a message to send. That triggers a rule that has the code to call the Signal binding’s Action to send that string as the message.

If you can use the Signal binding in any rule, you can use it with separation of behaviors.

Yes. Everywhere, whatever rule language you use.

You can, from a rule defined in a JSR scripting langage or blockly (as Rich and I shows). But not directly from a rule written in the rule DSL as you seem to want.
I said “directly”, because in fact you also can from a rule in the rule DSL, but you have to add an intermediary trick like those in the post explaining separation of concern.
In the rule written in rule DSL, you send your text as a command to an item, and a rule (still in DSL) monitor this item event and use the receivedCommand.toString to get the text. You can then call the Signal action from this. And so you achieve what you wanted : calling signal from one and only one place.

I’m no expert in Rule, I hope I’m not saying anything erroneous…

Thanks @rlkoshak and @dalgwen. I really believe i need to play around withit to grasp the whole concept and approach.
Because to your question @rlkoshak :

Both is unfortunately to some extend true :joy:

Indeed, that is a limitation of Rules DSL. I used to be the Rules DSL champion but once we got good Blockly support I simply cannot recommend it any more. It was never a great environment for those who already know how to program but Blockly is a far superior environment for those who do not know how to program. So Rules’ DSL niche has been replaced by Blockly.

I cannot recommend Rules DSL except for some old timers who have a bunch of rules written in Rules DSL and they don’t want to rewrite them. I strongly recommend new work and new users choose anything else (except Jython which has different problems). If don’t know programming, Blockly is excellent. If you do, JS Scripting or jRuby are excellent. Groovy and Java are options as well.

1 Like

No worries. I just tried again after reading your reply. I did a fresh captcha, pasted the whole string (as I did before), but I am still getting the 422. My secondary dedicated number is a google voice number. Do you know if it works with those?

I just realized that another user (just above you) had the same error code. (maybe you already saw it but I didn’t :sweat_smile: )
As you can see, he eventually managed to get it working without knowing why.

  • Is your phone number in international format ? Without space or strange character ?
  • Has the device name non conventional character ? I never tested anything beside very simple one like “openHAB”. I found one occurence of the 422 code in the signal code and it relates to a “UsernameMalformedException”

Hi,
unfortunately I have trouble to set up the binding.
I tried first with the account bridge, but didn’t receive any text or call.
Then I set up the signal account using an emulated phone with bluestacks, that did work and I’m able to scan the QR code there.
Trying to link it to linked device then the next problem(s)
when using the accounts phone number in the format +34 123456789 (using a space between country code and number) I get a QR code, which I can scan, which is successful on the (emulated) phone but leaves me with this error:

2023-09-01 14:14:35.191 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'signal:signallinkedbridge:signallinked' changed from OFFLINE (COMMUNICATION_ERROR): IOException - Connection closed! to OFFLINE (CONFIGURATION_PENDING): Waiting for QR code scan
	at org.asamk.signal.manager.storage.Database.getHikariDataSource(Database.java:104) ~[?:?]
	at org.asamk.signal.manager.storage.Database.initDatabase(Database.java:33) ~[?:?]
	at org.asamk.signal.manager.storage.AccountDatabase.init(AccountDatabase.java:33) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.lambda$48(SignalAccount.java:1133) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.getOrCreate(SignalAccount.java:1587) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.getAccountDatabase(SignalAccount.java:1131) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.lambda$38(SignalAccount.java:1106) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.getOrCreate(SignalAccount.java:1587) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.getRecipientStore(SignalAccount.java:1105) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.getProfileStore(SignalAccount.java:1110) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.migrateLegacyConfigs(SignalAccount.java:341) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.load(SignalAccount.java:188) ~[?:?]
	at org.asamk.signal.manager.ProvisioningManagerImpl.canRelinkExistingAccount(ProvisioningManagerImpl.java:182) ~[?:?]
	at org.asamk.signal.manager.ProvisioningManagerImpl.finishDeviceLink(ProvisioningManagerImpl.java:108) ~[?:?]
	at org.openhab.binding.signal.internal.protocol.SignalService.registerLinked(SignalService.java:216) ~[?:?]
	at org.openhab.binding.signal.internal.protocol.SignalService.start(SignalService.java:154) ~[?:?]
	at org.openhab.binding.signal.internal.handler.SignalBridgeHandler.checkAndStartServiceIfNeeded(SignalBridgeHandler.java:161) ~[?:?]

If I try it on the other hand without the space behind the country code, the binding is stuck in initialisation

023-09-01 14:27:56.310 [WARN ] [mmon.WrappedScheduledExecutorService] - Scheduled runnable ended with an exception: 
java.lang.UnsatisfiedLinkError: 'void org.sqlite.core.NativeDB._open_utf8(byte[], int)'
	at org.sqlite.core.NativeDB._open_utf8(Native Method) ~[?:?]
	at org.sqlite.core.NativeDB._open(NativeDB.java:75) ~[?:?]
	at org.sqlite.core.DB.open(DB.java:216) ~[?:?]
	at org.sqlite.SQLiteConnection.open(SQLiteConnection.java:285) ~[?:?]
	at org.sqlite.SQLiteConnection.<init>(SQLiteConnection.java:65) ~[?:?]
	at org.sqlite.jdbc3.JDBC3Connection.<init>(JDBC3Connection.java:28) ~[?:?]
	at org.sqlite.jdbc4.JDBC4Connection.<init>(JDBC4Connection.java:19) ~[?:?]
	at org.sqlite.JDBC.createConnection(JDBC.java:104) ~[?:?]
	at org.sqlite.SQLiteDataSource.getConnection(SQLiteDataSource.java:440) ~[?:?]
	at org.sqlite.SQLiteDataSource.getConnection(SQLiteDataSource.java:432) ~[?:?]
	at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) ~[?:?]
	at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) ~[?:?]
	at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) ~[?:?]
	at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) ~[?:?]
	at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100) ~[?:?]
	at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:81) ~[?:?]
	at org.asamk.signal.manager.storage.Database.getHikariDataSource(Database.java:104) ~[?:?]
	at org.asamk.signal.manager.storage.Database.initDatabase(Database.java:33) ~[?:?]
	at org.asamk.signal.manager.storage.AccountDatabase.init(AccountDatabase.java:33) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.lambda$48(SignalAccount.java:1133) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.getOrCreate(SignalAccount.java:1587) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.getAccountDatabase(SignalAccount.java:1131) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.lambda$38(SignalAccount.java:1106) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.getOrCreate(SignalAccount.java:1587) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.getRecipientStore(SignalAccount.java:1105) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.getProfileStore(SignalAccount.java:1110) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.migrateLegacyConfigs(SignalAccount.java:341) ~[?:?]
	at org.asamk.signal.manager.storage.SignalAccount.load(SignalAccount.java:188) ~[?:?]
	at org.asamk.signal.manager.SignalAccountFiles.initManager(SignalAccountFiles.java:92) ~[?:?]
	at org.asamk.signal.manager.SignalAccountFiles.initManager(SignalAccountFiles.java:80) ~[?:?]
	at org.openhab.binding.signal.internal.protocol.SignalService.start(SignalService.java:147) ~[?:?]
	at org.openhab.binding.signal.internal.handler.SignalBridgeHandler.checkAndStartServiceIfNeeded(SignalBridgeHandler.java:161) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?]
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) ~[?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
	at java.lang.Thread.run(Thread.java:833) ~[?:?]

anyone can guide me what I’m doing wrong?

edit:
tried it with a different number and now I only get this:

2023-09-01 14:54:03.856 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'signal:signallinkedbridge:443bd035a5' changed from OFFLINE (CONFIGURATION_PENDING): Waiting for QR code scan to OFFLINE (CONFIGURATION_PENDING): Incomplete registration: NO_VALID_USER null

Hello,

There is a known issue with sqlite and this binding in an OSGi environment like openHAB. Your log with “HikariDataSource” and “UnsatisfiedLinkError” seems to tell that you are affected. I will rework log in the next version to be more informative.
I still don’t know why it happens and I don’t know how to fix it.
In some cases, it even resolves itself without doing anything, apart restarting.
But even so, it can also mess the binding and put it in a corrupted state.
Maybe you can try to delete your things, and when it’s done, delete the content of the signal folder (e.g. /var/lib/openhab/signal) ? Then recreate it and make a call to the God of Unknown Bugs.
Sorry for not being able to help you better.

Hey Gwendal,

don’t worry, thank you for your reply. I will try deleting/reinstalling.

With openhab 4.0.2 the sqlite problem was back for me. Wasn’t able to get the addon running at all.
Updated to 4.0.3 right now and the addon magically started working without a single problem.

Edit: After restarting openhab the error is back again.

java.lang.RuntimeException: Failed to get driver instance for jdbcUrl=jdbc:sqlite:/opt/openhab/userdata/signal/data/931913.d/account.db
at com.zaxxer.hikari.util.DriverDataSource.(DriverDataSource.java:114) ~[?:?]

I’d say the sqlite problem is a simple timing issue.

If you stop openhab, delete cache and tmp folder, restart openhab then openhab will take a lot longer to load up and the addon will work fine.

maybe you can specify some kind of dependency to wait for?
like “start addon if jdbc driver is available and ready”.