Convert String to Numbers

Hello All,

I want to convert strings to numbers. I have found several examples, but not all of them fit my problem.
I am using the Miele cloud binding and want to convert the strings coming from the binding to numbers to write the values to my S7 PLC.
For example the item Program phase of my washing machine:

Convert:
Main wash to 1
Rinse to 2
Drain to 3
Spin to 4
Anti-crease to 5
Finished to 6

Then I can make a rule to transfer these numbers to a byte in a DB.

Thanks for your help.
Ed.

1 Like

Try something like this:

rule "Converter"
when
    Item  program_phase changed
then
    var String phase = program_phase.state.toString()
    var Number phase_number

    if (var == "Main wash") { phase_number = 1}
    else  (var == "Rinse") { phase_number = 2}
    else  (var == "Drain ") { phase_number = 3}
    else  (var == "Spin") { phase_number = 4}
    else  (var == "Anti-crease") { phase_number = 5}
    else  (var == "Finished ") { phase_number = 6}
end

Another way is to use a map transformation

1 Like

Hi Felix,
Thanks for your reply.
I did put the rule in my OH-PLC.rules file and change the channel names a bit for my dish washer as followes:

rule “Afwasautomaat Programma fase Converter”
when
Item Afwasautomaat_ProgramPhase changed
then
var String phase = Afwasautomaat_ProgramPhase.state.toString()
var Number phase_number

if  (var == "UNDEF") { phase_number = 99}
else  (var == "NULL") { phase_number = 0}
else  (var == "Pre-Wash") { phase_number = 1}
else  (var == "Main Wash") { phase_number = 2}
else  (var == "Rinse") { phase_number = 3}
else  (var == "Final Rinse") { phase_number = 4}
else  (var == "Drying") { phase_number = 5}
else  (var == "Finished ") { phase_number = 6}

end

Unfortunately I get the following warning in the log:
2020-11-26 22:26:08.828 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model ‘OH-PLC.rules’ has errors, therefore ignoring it: [8,7]: no viable alternative at input ‘var’
[8,21]: mismatched input ‘)’ expecting ‘end’

Can you see what’s wrong?

Maybe try a switch case

Dose this give any errors


rule "Afwasautomaat Programma fase Converter"
when
  Item Afwasautomaat_ProgramPhase changed
then

  
  switch (recievedCommand.state.toString) {
   case "Pre-Wash": <YOUR PLC ITEM NAME>.sendCommand(1) ;
   case "Main Wash": <YOUR PLC ITEM NAME>.sendCommand(2) ;
   case "Rinse": <YOUR PLC ITEM NAME>.sendCommand(3) ;
   case "Final Rinse": <YOUR PLC ITEM NAME>.sendCommand(4) ;
   case "Drying": <YOUR PLC ITEM NAME>.sendCommand(5) ;
   case "Finished": <YOUR PLC ITEM NAME>.sendCommand(6) ;
   }

end
1 Like

I’m with @denominator on using the case statement. You don’t need any variables, you just read in the state of your triggering item and send the command.

Hi all helpers,
Thanks for the input. Because I am an absolute beginner in programming, all of your help is much appreciated.
The previous code gave an error about some }}}} that were missing. So by trial and error I changed the code to the following which is working now!!

rule "Afwasautomaat Programma fase Converter"
when
	Item Afwasautomaat_ProgramPhase changed
then
	switch (Afwasautomaat_ProgramPhase.state.toString) {
	case "NULL": { PLC_Afwasautomaat_Program_Phase.sendCommand(0) ;}
	case "Pre-Wash": { PLC_Afwasautomaat_Program_Phase.sendCommand(1) ;}
   	case "Main Wash": { PLC_Afwasautomaat_Program_Phase.sendCommand(2) ;}
   	case "Rinse": { PLC_Afwasautomaat_Program_Phase.sendCommand(3) ;}
   	case "Final Rinse": { PLC_Afwasautomaat_Program_Phase.sendCommand(4) ;}
   	case "Drying": { PLC_Afwasautomaat_Program_Phase.sendCommand(5) ;}
   	case "Finished": { PLC_Afwasautomaat_Program_Phase.sendCommand(6) ;}
	case "UNDEF": { PLC_Afwasautomaat_Program_Phase.sendCommand(8) ;}
   }
end

I have 2 more questions:

  1. It could be that there are other possible cases which are unknown at this moment. Which line do I have to add (something starting with ‘else’), so I can trap these values and add them to the case list. I’ve tried something like below but this gives an error and I don’t know wat is wrong.
rule "Afwasautomaat Programma fase Converter"
when
	Item Afwasautomaat_ProgramPhase changed
then
	switch (Afwasautomaat_ProgramPhase.state.toString) {
	case "NULL": { PLC_Afwasautomaat_Program_Phase.sendCommand(0) ;}
	case "Pre-Wash": { PLC_Afwasautomaat_Program_Phase.sendCommand(1) ;}
   	case "Main Wash": { PLC_Afwasautomaat_Program_Phase.sendCommand(2) ;}
   	case "Rinse": { PLC_Afwasautomaat_Program_Phase.sendCommand(3) ;}
   	case "Final Rinse": { PLC_Afwasautomaat_Program_Phase.sendCommand(4) ;}
   	case "Drying": { PLC_Afwasautomaat_Program_Phase.sendCommand(5) ;}
   	case "Finished": { PLC_Afwasautomaat_Program_Phase.sendCommand(6) ;}
	case "UNDEF": { PLC_Afwasautomaat_Program_Phase.sendCommand(8) ;}
   }
else
	PLC_Afwasautomaat_Program_Phase.sendCommand(9)
end
  1. How can I forward an output from a channel 1:1 to my plc
    eg: Afwasautomaat_ProgramRemainingTime changed from 10860 to 10800
    How do I get the value 10800 forwarded to PLC_Afwasautomaat_ProgramRemainingTime

Thanks again!!

Ed.

1 Like

ok, default does the trick. It’s working. Thanks, Scott.

1 Like

Without more context, I think the simple answer is to link the Item to the Channel. If you have textually defined Items, post what you have for PLC_Afwasautomaat_ProgramRemainingTime. What is your plc?

This is what I did, but it’s not working:

rule "Afwasautomaat Resterende tijd"
when
	Item Afwasautomaat_ProgramRemainingTime changed
then
	val Afwasautomaat_ProgramRemainingTime = AA_ProgramRemainingTime
end

In the log the incoming value from the dishwasher can be seen and looks like:
Afwasautomaat_ProgramRemainingTime changed from 11160 to 11100

I want to forward the value 11100 to my plc. The line in the items file looks like:

Number  AA_ProgramRemainingTime  "PLC Afwasautomaat Resterende tijd"  { simatic="plc1:DB803.DBW14:word" }

What am I doing wrong?

So are you trying to forward the state of

Afwasautomaat_ProgramRemainingTime

To

AA_ProgramRemainingTime

? Presumably Afwasautomaat_ProgramRemainingTime is an Item?

You could sendCommand in the rule, perhaps? Or maybe use a follow profile, no rule needed.

Hi hafniumzinc,
But how do I do that. I am an absolute beginner.

You must read through the documentation, experiment, search the forum, repeat, repeat, repeat, …

rule "Afwasautomaat Resterende tijd"
when
	Item Afwasautomaat_ProgramRemainingTime changed
then
	AA_ProgramRemainingTime.sendCommand(newState)
end

But as @hafniumzinc suggested, a follow profile would eliminate the need for a rule.

1 Like

Thanks Scott,
I’m doing my best but mostly I find lot’s of solutions that doesn’t fit to my problem.
Unfortunately your rule is not working. I found the following error in the log: “Rule ‘Afwasautomaat Resterende tijd’: An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.String) on instance: null”

The profile would not have had this problem. Apparently, Afwasautomaat_ProgramRemainingTime is changing to NULL, which can’t be sent as a Command, so you will need to check for that…

rule "Afwasautomaat Resterende tijd"
when
	Item Afwasautomaat_ProgramRemainingTime changed
then
    if (newState != NULL) {
        AA_ProgramRemainingTime.sendCommand(newState)
    }
end

Hi Scott,

I tried your example. Unfortunately I got the same error.
For this test I used another time which is coming from the dishwasher in the same format.
The output from the dishwasher looks like:

2020-11-30 19:58:05.929 [vent.ItemStateChangedEvent] - Afwasautomaat_DelayedStartTime changed from UNDEF to 0
2020-11-30 19:58:22.042 [vent.ItemStateChangedEvent] - Afwasautomaat_DelayedStartTime changed from 0 to 14520
2020-11-30 19:59:20.778 [vent.ItemStateChangedEvent] - Afwasautomaat_DelayedStartTime changed from 14520 to 14460
2020-11-30 20:00:21.142 [vent.ItemStateChangedEvent] - Afwasautomaat_DelayedStartTime changed from 14460 to 14400

I changed

if (newState != NULL) {

into

if (newState != UNDEF)

but that doesn’t work either.
Do you have another tip?
Thanks.

Please post the Item definitions for both Items, the rule you are currently using, and the error message. Also, paste this into a rule file, save, and post the logs…

rule "Test"
when
	System started
then
	logWarn("Rules", "AA_ProgramRemainingTime.state: {}", AA_ProgramRemainingTime.state)
	logWarn("Rules", "Afwasautomaat_ProgramRemainingTime.state: {}", Afwasautomaat_ProgramRemainingTime.state)
end

The item from the miele cloud binding is in Paper UI and the item to the Siemens PLC is in a .items file.

Number  AA_DelayedStartTime         "PLC Afwasautomaat Vertraagde starttijd"        { simatic="plc1:DB803.DBW12:word" }
rule "Afwasautomaat Vertraagde Starttijd"
when
	Item Afwasautomaat_DelayedStartTime changed
then
	if (newState != NULL) {
	AA_DelayedStartTime.sendCommand(newState)
	}
end

openhab.log
2020-12-02 22:48:13.631 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'OH-PLC.rules'
2020-12-02 22:48:25.338 [WARN ] [eclipse.smarthome.model.script.Rules] - AA_ProgramRemainingTime.state: 0
2020-12-02 22:48:25.344 [WARN ] [eclipse.smarthome.model.script.Rules] - Afwasautomaat_ProgramRemainingTime.state: UNDEF
2020-12-02 22:48:29.930 [INFO ] [al.webservice.DefaultMieleWebservice] - Fetch action state description for Miele device 000104474723
2020-12-02 22:48:30.005 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Afwasautomaat Vertraagde Starttijd': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.String) on instance: null
2020-12-02 22:48:32.802 [INFO ] [al.webservice.DefaultMieleWebservice] - Fetch action state description for Miele device 000104476258
2020-12-02 22:48:39.868 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Afwasautomaat Vertraagde Starttijd': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.String) on instance: null
2020-12-02 22:49:21.564 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Afwasautomaat Vertraagde Starttijd': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.String) on instance: null
2020-12-02 22:50:21.542 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Afwasautomaat Vertraagde Starttijd': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.String) on instance: null
2020-12-02 22:51:21.609 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Afwasautomaat Vertraagde Starttijd': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.String) on instance: null
2020-12-02 22:51:47.436 [INFO ] [al.webservice.DefaultMieleWebservice] - Fetch action state description for Miele device 000104474723
2020-12-02 22:51:47.570 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Afwasautomaat Vertraagde Starttijd': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.String) on instance: null

events.log
2020-12-02 22:48:30.012 [vent.ItemStateChangedEvent] - Afwasautomaat_Power changed from off to on
2020-12-02 22:48:30.028 [vent.ItemStateChangedEvent] - Afwasautomaat_DelayedStartTime changed from UNDEF to 0
2020-12-02 22:48:39.848 [vent.ItemStateChangedEvent] - Afwasautomaat_DelayedStartTime changed from 0 to 720
2020-12-02 22:49:21.560 [vent.ItemStateChangedEvent] - Afwasautomaat_DelayedStartTime changed from 720 to 660
2020-12-02 22:50:21.529 [vent.ItemStateChangedEvent] - Afwasautomaat_DelayedStartTime changed from 660 to 600
2020-12-02 22:51:21.548 [vent.ItemStateChangedEvent] - Afwasautomaat_DelayedStartTime changed from 600 to 540
2020-12-02 22:51:47.481 [vent.ItemStateChangedEvent] - Afwasautomaat_Power changed from on to off
2020-12-02 22:51:47.538 [vent.ItemStateChangedEvent] - Afwasautomaat_DelayedStartTime changed from 540 to UNDEF

After I loaded the test rule I started a delayed start program on my dishwasher. A couple of minutes later I aborted the program and switched the machine off.

No test rule?

Use this instead…

rule "Afwasautomaat Vertraagde Starttijd"
when
	Item Afwasautomaat_DelayedStartTime changed
then
	if (newState != NULL) {
	    AA_DelayedStartTime.sendCommand(newState.toString)
	}
end