Incrementing a variable and parsing string

Posted on
Tue Sep 25, 2018 6:33 pm
hamw offline
Posts: 1212
Joined: Mar 31, 2008

Incrementing a variable and parsing string

Was hoping I could get a little help with incrementing a variable +1. i use this for my home audio matrix to change the source. It advances through 4 sources, and then at 4 goes to 0 again, corresponding to "off."

This simple Applescript works:
Code: Select all
if value of variable "audio_7_source" = "4" then
      set value of variable "audio_7_source" to "0"
   else
      set value of variable "audio_7_source" to (value of variable "audio_7_source") + 1
   end if


My Python attempt seems to be OK up to the +1 part, but it increments "0" to "01", instead of just going to "1" :roll:

Code: Select all
audio_7_sourceVar = indigo.variables[718347542]
if audio_7_sourceVar.value == "4":
   indigo.variable.updateValue(718347542, "0")
else:
   indigo.variable.updateValue (718347542, ((audio_7_sourceVar.value) + ("1")))


On another note, I have a parser I wrote for that switch, and it uses some of the variable actions in this thread... Any easy suggestions as to how to convert this to Python? The issues are the if statement for the variable "vauxResponse", the text item delimiters, picking out the pieces of the serial response from the unit, then stringing the response together. This is the bass/treble set sequence. I moved this post from another thread as it seems this is more appropriate.

Code: Select all
using terms from application "IndigoServer"
   tell application "IndigoServer"
      
      if value of variable "vauxResponse" contains "!s" then
         
         set vauxResponseString to value of variable "vauxResponse"
         if value of variable "vauxLogging_Enabled" is equal to "true" then
            log vauxResponseString
         end if
         set {myTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {","}}
         set myList to text items of vauxResponseString
         
         set AppleScript's text item delimiters to myTID -- It's considered good practice to return the TID's to their original state
         --log list of myList
         --if myList contains less than 5 items then stop
      end if
      
      
      try
         if item 2 of myList is "40" then --this is for setting bass and treble.
            set vauxZoneNumber to item 3 of myList
            
            
            set vauxBassSetting to item 4 of myList
            
            set vauxTrebleSetting to item 5 of myList
            
            
            log ((vauxZoneNumber as string) & "  " & (vauxBassSetting as string) & "  " & (vauxTrebleSetting as string))
            
            
            if vauxZoneNumber is "0" then set value of variable "vauxZoneName" to "Off"
            if vauxZoneNumber is "1" then set value of variable "vauxZoneName" to "Kitchen"
            if vauxZoneNumber is "2" then set value of variable "vauxZoneName" to "FamRm"
            if vauxZoneNumber is "3" then set value of variable "vauxZoneName" to "Study"
            
            if vauxZoneNumber is "4" then set value of variable "vauxZoneName" to "LivDnRm"
            if vauxZoneNumber is "5" then set value of variable "vauxZoneName" to "GameRm"
            if vauxZoneNumber is "6" then set value of variable "vauxZoneName" to "Patio"
            if vauxZoneNumber is "7" then set value of variable "vauxZoneName" to "Pool"
            if vauxZoneNumber is "8" then set value of variable "vauxZoneName" to "MBR"
            
            
            set value of variable "vauxResponseBassTreble" to ((value of variable "vauxZoneName" as string) & "  Bass " & (vauxBassSetting as string) & "  Treble " & (vauxTrebleSetting as string))
            
            
            log value of variable "vauxResponseBassTreble" as string
            
         end if
         
      end try
      


This is that response sequence:

Code: Select all
   Simple Serial Plugin Debug      Queue has 1 command(s) waiting.
   Simple Serial Plugin Debug      Processing command: *CW,44,1
   Simple Serial Plugin Debug      Sending command:*CW,44,1
   Simple Serial Plugin            Response from serial device (text): !S,40,1,6,8

, of length 13 characters
   Simple Serial Plugin Debug      *CW,44,1
 command completed
   Script                          !S,40,1,6,8

   Script                          1  6  8

   Script                          Kitchen  Bass 6  Treble 8

   Script                          Kitchen(K)  Off   0
   Script                          Kitc Off  0



Thanks very much; just not sure where to get specifics for a situation like this.

Posted on
Wed Sep 26, 2018 12:13 am
howartp offline
Posts: 4559
Joined: Jan 09, 2014
Location: West Yorkshire, UK

Incrementing a variable and parsing string

hamw wrote:
Code: Select all
indigo.variable.updateValue (718347542, int(audio_7_sourceVar.value) + 1)


Change to what I’ve changed it to.

Variables are string (text) values so you need the integer (numeric) value of it. Also “1” is a string (text) whereas 1 is an integer.

Peter


Sent from my iPhone using Tapatalk Pro

Posted on
Wed Sep 26, 2018 1:45 pm
hamw offline
Posts: 1212
Joined: Mar 31, 2008

Re: Incrementing a variable

Thanks for the hint... I tried the new line here:

Code: Select all
audio_7_sourceVar = indigo.variables[718347542]
if audio_7_sourceVar.value == "4":
   indigo.variable.updateValue(718347542, "0")
else:
   indigo.variable.updateValue (718347542, int(audio_7_sourceVar.value) + 1)


but it threw this error:

Code: Select all
[ Script Error                    embedded script: Python argument types in
    VariableCmds.updateValue(VariableCmds, int, int)
did not match C++ signature:
    updateValue(_VariableCmds {lvalue}, boost::python::api::object elem, CCString value)
   Script Error                    Exception Traceback (most recent call shown last):

     embedded script, line 6, at top level
ArgumentError: Python argument types in
    VariableCmds.updateValue(VariableCmds, int, int)
did not match C++ signature:
    updateValue(_VariableCmds {lvalue}, boost::python::api::object elem, CCString value)


Does the initial variable request need to set the number to an integer first? I tried what I think will set to integer and stripped out the quotes, but no joy:

Code: Select all
audio_7_sourceVar = int(indigo.variables[718347542].value)
if audio_7_sourceVar == 4:
   indigo.variable.updateValue(718347542, 0)
else:
   indigo.variable.updateValue(718347542, int(audio_7_sourceVar) + 1)


getting this result:

Code: Select all
 Script Error                    embedded script: Python argument types in
    VariableCmds.updateValue(VariableCmds, int, int)
did not match C++ signature:
    updateValue(_VariableCmds {lvalue}, boost::python::api::object elem, CCString value)
   Script Error                    Exception Traceback (most recent call shown last):

     embedded script, line 4, at top level
ArgumentError: Python argument types in
    VariableCmds.updateValue(VariableCmds, int, int)
did not match C++ signature:
    updateValue(_VariableCmds {lvalue}, boost::python::api::object elem, CCString value)

Posted on
Thu Sep 27, 2018 11:52 am
jay (support) offline
Site Admin
User avatar
Posts: 18220
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Incrementing a variable

You're very close:

Code: Select all
audio_7_sourceVar = int(indigo.variables[718347542].value)
if audio_7_sourceVar == 4:
   indigo.variable.updateValue(718347542, "0")
else:
   indigo.variable.updateValue(718347542, str(audio_7_sourceVar + 1))


When you set a variable value, it has to be a string so we do the addition then convert the result to a string (also changed the first update to the string 0).

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Thu Sep 27, 2018 12:34 pm
hamw offline
Posts: 1212
Joined: Mar 31, 2008

Re: Incrementing a variable

Thank you Jay!

Could I beg for a little help on my parser?

Posted on
Thu Sep 27, 2018 12:43 pm
jay (support) offline
Site Admin
User avatar
Posts: 18220
Joined: Mar 19, 2008
Location: Austin, Texas

Parsing string

hamw wrote:
On another note, I have a parser I wrote for that switch, and it uses some of the variable actions in this thread... Any easy suggestions as to how to convert this to Python? The issues are the if statement for the variable "vauxResponse", the text item delimiters, picking out the pieces of the serial response from the unit, then stringing the response together. This is the bass/treble set sequence. I moved this post from another thread as it seems this is more appropriate.

Code: Select all
using terms from application "IndigoServer"
   tell application "IndigoServer"
      
      if value of variable "vauxResponse" contains "!s" then
         
         set vauxResponseString to value of variable "vauxResponse"
         if value of variable "vauxLogging_Enabled" is equal to "true" then
            log vauxResponseString
         end if
         set {myTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {","}}
         set myList to text items of vauxResponseString
         
         set AppleScript's text item delimiters to myTID -- It's considered good practice to return the TID's to their original state
         --log list of myList
         --if myList contains less than 5 items then stop
      end if
      
      
      try
         if item 2 of myList is "40" then --this is for setting bass and treble.
            set vauxZoneNumber to item 3 of myList
            
            
            set vauxBassSetting to item 4 of myList
            
            set vauxTrebleSetting to item 5 of myList
            
            
            log ((vauxZoneNumber as string) & "  " & (vauxBassSetting as string) & "  " & (vauxTrebleSetting as string))
            
            
            if vauxZoneNumber is "0" then set value of variable "vauxZoneName" to "Off"
            if vauxZoneNumber is "1" then set value of variable "vauxZoneName" to "Kitchen"
            if vauxZoneNumber is "2" then set value of variable "vauxZoneName" to "FamRm"
            if vauxZoneNumber is "3" then set value of variable "vauxZoneName" to "Study"
            
            if vauxZoneNumber is "4" then set value of variable "vauxZoneName" to "LivDnRm"
            if vauxZoneNumber is "5" then set value of variable "vauxZoneName" to "GameRm"
            if vauxZoneNumber is "6" then set value of variable "vauxZoneName" to "Patio"
            if vauxZoneNumber is "7" then set value of variable "vauxZoneName" to "Pool"
            if vauxZoneNumber is "8" then set value of variable "vauxZoneName" to "MBR"
            
            
            set value of variable "vauxResponseBassTreble" to ((value of variable "vauxZoneName" as string) & "  Bass " & (vauxBassSetting as string) & "  Treble " & (vauxTrebleSetting as string))
            
            
            log value of variable "vauxResponseBassTreble" as string
            
         end if
         
      end try
      



Here's my Pythonic conversion (I've made some assumptions which are listed). I used Pythonic variable names (not camelCase), value unpacking (setting all 5 items in the split string at once), an id to name map via a Python dictionary, etc. This should give you not only how to translate, but also Python features that make things easier than in AppleScript. Untested, but I think it's right.

Code: Select all
# Get the entire response string
vaux_response_string = indigo.variables[IDOF_vauxResponse].value
# I'm assuming that the list will always split into 5 items. This avoids setting
# each variable individually. If not, it can be done much like you do it in
# AppleScript by splitting into a list then just grabbing each item.
first_value, second_value, vaux_zone_number, vaux_bass_setting, vaux_treble_setting = vaux_response_string.split(",")
if "!s" in first_value.lower():
    # Get the boolean value of the logging variable and log if it's true
    if indigo.variables[IDOF_vauxLogging_Enabled].getValue(bool):
        indigo.server.log(vaux_response_string)
   
if second_value == "40":
    # Log the zone and it's settings
    indigo.server.log("{}  {}  {}".format(vaux_zone_number, vaux_bass_setting, vaux_treble_setting))
   
    # This is a more Pythonic way of doing your zone number map
    zone_map = {
        "0": "Off",
        "1": "Kitchen",
        "2": "FamRm",
        "3": "Study",
        "4": "LivDnRm",
        "5": "GameRm",
        "6": "Patio",
        "7": "Pool",
        "8": "MBR",
    }
    # Save off the current zone name for use later in case it doesn't change for some reason
    vaux_zone_variable = indigo.variables[IDOF_vauxZoneName]
    temp_zone_name = vaux_zone_variable.value
    # If the zone number from the list is in the map's keys, save off the new name and set the Indigo variable
    if vaux_zone_number in zone_map.keys():
        temp_zone_name = zone_map[vaux_zone_number]
        indigo.variable.updateValue(vaux_zone_variable, value=temp_zone_name)
       
    # Create the string that's going to be set in the variable and logged
    new_string_value = "{}  Bass {}  Treble {}".format(temp_zone_name, vaux_bass_setting, vaux_treble_setting)
    # Set the Indigo variable
    indigo.variable.updateValue(IDOF_vauxResponseBassTreble, value=new_string_value)
    # Log the string
    indigo.server.log(new_string_value)


You'll notice that if you take out all of my explanatory comments, the script is MUCH shorter and more concise than it's AppleScript counterpart.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Thu Sep 27, 2018 3:11 pm
hamw offline
Posts: 1212
Joined: Mar 31, 2008

Re: Parsing string

Jay, thank you so much for your effort on this. I am working hard to make these conversions… For me this script would require a ton of digging and trial and error. You have saved me a bunch of time. I will report back in the next few days how it goes.

Ham

Posted on
Thu Sep 27, 2018 3:56 pm
jay (support) offline
Site Admin
User avatar
Posts: 18220
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Parsing string

NP. Given the quantity of scripts you seem to have, you're really going to want to become more self-sufficient, so you might want to do a Python basics/intro tutorial so you're more familiar with basic syntax and concepts (strings vs number literals, etc). It'll help you avoid some of the errors in your first attempt above.

[MODERATOR NOTE] split from original topic and moved to the AppleScript conversion help forum.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Thu Sep 27, 2018 4:12 pm
jay (support) offline
Site Admin
User avatar
Posts: 18220
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Parsing string

hamw wrote:
For me this script would require a ton of digging and trial and error.


Note that you could have done pretty much a straight conversion which would have looked very similar to the AppleScript - I chose to use Pythonic features in an effort to help illustrate those.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Fri Sep 28, 2018 3:49 pm
hamw offline
Posts: 1212
Joined: Mar 31, 2008

Re: Incrementing a variable and parsing string

Code: Select all
audio_7_sourceVar = int(indigo.variables[718347542].value)
if audio_7_sourceVar == 4:
   indigo.variable.updateValue(718347542, "0")
else:
   indigo.variable.updateValue(718347542, str(audio_7_sourceVar + 1))



This worked fine... much appreciated.

Quick question... your "pythonic conversion" for my parser script looks great and I will try to get to that shortly. Since I'm kind of limited in my approach to programming, is there a straightforward conversion for a line like this, just using the variable names and not worrying about IDs etc?

if vauxZoneNumber is "0" then set value of variable "vauxZoneName" to "Off"

Finally, you are right, I should try to sit down and do a tutorial of some kind.... but since my day job keeps me busy 60+ hours per week it is a bit tough... My wife expects me to talk to her when I get home... :-) So I appreciate your generous help and will muddle through.

Posted on
Fri Sep 28, 2018 4:34 pm
jay (support) offline
Site Admin
User avatar
Posts: 18220
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Incrementing a variable and parsing string

You should never use names. If you change the name of the variable (even by accident) the script breaks. Believe me, it's a VERY BAD IDEA. Substituting the ID is simple.

But, if you insist on shooting yourself in the foot:

Code: Select all
if indigo.variables["vauxZoneNumber"].value == "0":
    indigo.variable.updateValue("vauxZoneName", value="Off")

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Mon Oct 29, 2018 9:00 pm
hamw offline
Posts: 1212
Joined: Mar 31, 2008

Re: Incrementing a variable and parsing string

This is not quite the same situation. I'm trying to set a variable to select an image for a control page based on whether the pool heat is on or the spa heat is on, or neither. Can't figure out how to get this simple translation to work. Here's the applescript that works just fine:

Code: Select all
if ((value of variable "Pool_Heat_Pool_Status" is "on") or (value of variable "Pool_Heat_Spa_Status" is "on")) then
   set value of variable "Pool_Heat_Actual_Status" to "true"
   log "Pool/Spa Heat has turned ON"
else
   set value of variable "Pool_Heat_Actual_Status" to "false"
   log "Pool/Spa Heat has turned OFF"
end if


My first attempt:

Code: Select all
PoolHeatON = indigo.variables[1920760143]   #Pool_Heat_Pool_Status
SpaHeatOn = indigo.variables[585319771]  #Pool_Heat_Spa_Status

PoolHeatON.value == "on" or SpaHeatOn.value == "on":
  indigo.variable.updateValue(PoolHeatON, "true"
indigo.server.log("Pool/Spa Heat has turned ON")

else:

    indigo.variable.updateValue(SpaHeatOn, "false"
indigo.server.log("Pool/Spa Heat has turned OFF")


Did not work with an error on "else:.".

Code: Select all
PoolHeatON = indigo.variables[1920760143]   #Pool_Heat_Pool_Status
SpaHeatOn = indigo.variables[585319771]  #Pool_Heat_Spa_Status

PoolHeatON.value =="on" or SpaHeatOn.value =="on":
   ((indigo.server.log("Pool/Spa Heat has turned ON") and (indigo.variable.updateValue(PoolHeatON, "true"))

else:

    ((indigo.variable.updateValue(SpaHeatOn, "false") and (indigo.server.log("Pool/Spa Heat has turned OFF"))



Does not work either. Thanks!

Posted on
Tue Oct 30, 2018 5:47 am
DaveL17 offline
User avatar
Posts: 6753
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Incrementing a variable and parsing string

There's a couple of things. First, it looks like your indentation is messed up. Python is very particular about indentation. Second, your first example is missing an 'if'. Thirdly, it looks like you're testing the value of the variable PoolHeatON and--if its value is 'on'--changing its value to 'true'. If neither is true, you're changing the value of SpaHeatOn. Is this what you want to do? In your AppleScript, you're changing the same variable. Here is a modified version which I think matches your AppleScript's logic (obviously untested).

Code: Select all
PoolHeatON = indigo.variables[1920760143]   #Pool_Heat_Pool_Status
SpaHeatOn = indigo.variables[585319771]  #Pool_Heat_Spa_Status

if PoolHeatON.value == "on" or SpaHeatOn.value == "on":
    indigo.variable.updateValue(PoolHeatON, "true")
    indigo.server.log("Pool/Spa Heat has turned ON")

else:
    indigo.variable.updateValue(PoolHeatON, "false")
    indigo.server.log("Pool/Spa Heat has turned OFF")


EDIT: also saw that you were missing some close parentheses.

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Tue Oct 30, 2018 9:12 am
jay (support) offline
Site Admin
User avatar
Posts: 18220
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Incrementing a variable and parsing string

Going from his original AppleScript, I believe this is correct:

Code: Select all
PoolHeatON = indigo.variables[1920760143]   #Pool_Heat_Pool_Status
SpaHeatOn = indigo.variables[585319771]  #Pool_Heat_Spa_Status

if PoolHeatON.value == "on" or SpaHeatOn.value == "on":
    indigo.variable.updateValue(123, "true")  # insert ID of Pool_Heat_Actual_Status
    indigo.server.log("Pool/Spa Heat has turned ON")

else:
    indigo.variable.updateValue(123, "false")  # insert ID of Pool_Heat_Actual_Status
    indigo.server.log("Pool/Spa Heat has turned OFF")

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Thu Nov 01, 2018 4:18 pm
hamw offline
Posts: 1212
Joined: Mar 31, 2008

Re: Incrementing a variable and parsing string

Thanks again; that works fine. In my original version I actually tried to set the correct variable, "Pool_Heat_Actual_Status", but then confused myself! :oops:

Appreciate the assistance, Making progress!

Who is online

Users browsing this forum: No registered users and 5 guests