Announcement

Collapse
No announcement yet.

Comparing 2 device strings in an "expression is true" event condition

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Comparing 2 device strings in an "expression is true" event condition

    I'm using EasyTrigger's "A device value is this expression is true" condition in an event. In the expression I'm trying to compare the string of 2 devices (RadtionStation Name devices for a couple of Sonos players).

    The expressions I'm trying to use are "$$DTR:833:=$$DTR:887:" as a condition for one event and "$$DTR:833:<>$$DTR:887:" for another event. Neither of these conditions seem to ever be true. I have the 2 sonos players linked and they are playing the same thing. Looking at each device details Advanced tab, I confirmed both devices have a string = "Christina Perri Radio". However, EasyTrigger is throwing an error to the log that says "ERROR missing EOF at 'Perri' at line 1:10". It's like the "space" character is throwing a monkey wrench into the analysis. I've also tried using the expressions "hs.DeviceString(833) = hs.DeviceString(887)" and "hs.DeviceString(833) <> hs.DeviceString(887)" but those conditions never match either.

    Any help or guidance is appreciated!

    #2
    You can't compare strings with an expression, it only works with numerical expressions.

    With EasyTrigger you can compare a device's string to a predefined string, but not to another device's string. I don't think there is an easy way to do what you want without a script.

    Comment


      #3
      So maybe I'm missing something, but wouldn't these 2 events below accomplish what you are looking for??

      First event is true if both device strings contain Christina Perri Radio

      Click image for larger version

Name:	contains.png
Views:	330
Size:	50.6 KB
ID:	1341530

      Second event is true if neither device string contains Christina Perri Radio.

      Click image for larger version

Name:	does not contain.png
Views:	300
Size:	35.9 KB
ID:	1341531


      Another option is to assign a device value for each radio station you regularly listen to for each Sonos player's "RadioStation" device.

      You can do this too using Easy Trigger where IF RadioStation string changes and contains "Christina Perri Radio", THEN set RadioStation value to 1. You would need a separate event for each station, The second station would be given RadioStation value 2 and so forth. If you only listen to a handful of stations, this would easy to do. You could then use an equation to compare the device values of each Sonos player.

      --Barry

      Comment


        #4
        Thanks for the fast response guys. Unfortunately, I use some predefined RadioStations, but I also use a lot of different music services with all sorts of different playlists. So it wouldn't be practical to setup a device for each predefined string. I really need something that takes reads the current Radiostation String from one Sonos device and compares it to the current Radiostation string over another Sonos device.

        I'm wondering if I could setup an event that triggers when the Master Bedroom Sonos Radiostation changes. That event then takes the RadioStation device string and runs it through some sort of encoding that converts the text into numbers. Those numbers are then saved as a value in a virtual device. Then I could more easily compare the device values using EasyTrigger to determine if the two sonos devices are playing the same radiostations.
        Here's an example of the type of string to number encoding I was thinking about:
        https://onlinestringtools.com/conver...-spacing=false

        I'm just not sure now to incorporate such a conversion in Homeseer script or event.

        Comment


          #5
          The easiest would be to compare the strings in a script. There’s no need to do any kind of encoding.
          HS 4.2.8.0: 2134 Devices 1252 Events
          Z-Wave 3.0.10.0: 133 Nodes on one Z-Net

          Comment


            #6
            Here is another option if you don't want to tackle a script: Compare the string length of the 2 devices to see if they are equal or not equal:

            Code:
            Length($$DTR:833) = Length($$DTR:887)
            Length($$DTR:833) <> Length($$DTR:887)
            For greater accuracy, if you also have a string device for the current "Track" that each Sonos is playing, you could also count the length of those strings as well and add the result to the station string length:

            Code:
            Length($$DTR:833+$$DTR123) = Length($$DTR:887+$$DTR456)
            Length($$DTR:833+$$DTR123) <> Length($$DTR:887+$$DTR456)
            Note: I haven't tested this, I'm just assuming Easy Trigger supports the "Length" expression.

            --Barry

            Comment


              #7
              Sorry for bringing up an old thread, but I'm looking to do something similar with my Sonos.

              I would like to lower the volume of the player(s) when a commercial is playing with certain stations and then return the volume to original when the commercial is over. I plan on using global variables to keep track of original volume(s).

              I can trigger lowering volume easy enough because the Artist/Track is always the same for certain stations during commercials, eg. Hit List station has Artist= "Station" and Track = "Hit List".

              However, I am running into problems with retruning the volume to normal. If I trigger on changing to not Artist="Station", then the event is triggered each time there is a new song.... not acceptable.

              Would be nice to be able to trigger like this: If Artist changes from "Station" to not "Station" then....

              Is this possible?

              Comment


                #8
                Originally posted by prsmith777 View Post
                Sorry for bringing up an old thread, but I'm looking to do something similar with my Sonos.

                I would like to lower the volume of the player(s) when a commercial is playing with certain stations and then return the volume to original when the commercial is over. I plan on using global variables to keep track of original volume(s).

                I can trigger lowering volume easy enough because the Artist/Track is always the same for certain stations during commercials, eg. Hit List station has Artist= "Station" and Track = "Hit List".

                However, I am running into problems with retruning the volume to normal. If I trigger on changing to not Artist="Station", then the event is triggered each time there is a new song.... not acceptable.

                Would be nice to be able to trigger like this: If Artist changes from "Station" to not "Station" then....

                Is this possible?
                Without really having thought this through, could you do something like keep an extra global variable that you set to True when when the commercials come on - you're already storing the old volume on another global variable when you do it, so that should be easy. Then do something like:

                - If Artist changes AND GlobalVariable1 is True THEN
                - reset the volume AND set GlobalVariable1 to False

                OR, if you don't want to use yet another global variable, set the global variable to zero when you're not on a commercial and key off of that. So:

                When you trigger that a commercial hit:
                - set globalvariable to volume level
                - change volume

                For coming out of commercial:
                - If Artist changes AND GlobalVariable is != 0:
                - Change volume to GlobalVariable
                - Reset GlobalVariable to 0


                Paul

                Comment


                  #9
                  Originally posted by paul View Post

                  Without really having thought this through, could you do something like keep an extra global variable that you set to True when when the commercials come on - you're already storing the old volume on another global variable when you do it, so that should be easy. Then do something like:

                  - If Artist changes AND GlobalVariable1 is True THEN
                  - reset the volume AND set GlobalVariable1 to False

                  OR, if you don't want to use yet another global variable, set the global variable to zero when you're not on a commercial and key off of that. So:

                  When you trigger that a commercial hit:
                  - set globalvariable to volume level
                  - change volume

                  For coming out of commercial:
                  - If Artist changes AND GlobalVariable is != 0:
                  - Change volume to GlobalVariable
                  - Reset GlobalVariable to 0


                  Paul
                  I think that idea could work.

                  However I worked it out the other day using a more generic method.

                  Click image for larger version

Name:	Triggers.jpg
Views:	161
Size:	79.7 KB
ID:	1530862

                  I made a Trigger based on Track any value set or changed and State is playing. As you can see I have a lot of Sonos players; in fact the list keeps going. This triggers a script.

                  Code:
                  Sub Main(ByVal Parms as Object)
                  
                  
                  Dim roomName as String
                  Dim mostRecentRoomName as String
                  Dim mostRecentDevTime as DateTime = new DateTime(2000,1,1)
                  Dim commercialPlaying as Boolean = False
                  Dim announcementPlaying as Boolean = False
                  Dim intercomPlaying as Boolean = False
                  
                  
                  Try 'get most recent Sonos Room that triggered script
                  
                  Dim dv as Scheduler.Classes.DeviceClass
                  Dim EN As Scheduler.Classes.clsDeviceEnumeration
                  EN = hs.GetDeviceEnumerator
                  
                  Do
                  dv = EN.GetNext
                  If dv Is Nothing Then Continue Do
                  If dv.location2(hs) = "Sonos" and dv.name(hs) = "Artist" Then
                  roomName = dv.location(hs)
                  If DateTime.Compare(mostRecentDevTime,hs.devicelastchangeref(dv .Ref(hs))) < 0 Then
                  mostRecentRoomName = roomName
                  mostRecentDevTime = hs.devicelastchangeref(dv.Ref(hs))
                  End If
                  End If
                  
                  Loop Until EN.Finished
                  
                  Catch ex As Exception : hs.writelog("Script Info", "Exception: " & ex.message)
                  
                  End Try
                  
                  'check if add is playing
                  
                  If String.IsNullOrEmpty(hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Artist")) _
                  And String.IsNullOrEmpty(hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Album")) _
                  And hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Radiostation Name") = "Indie Chill Radio" Then
                  commercialPlaying = True
                  End If
                  
                  If String.IsNullOrEmpty(hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Artist")) _
                  And String.IsNullOrEmpty(hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Album")) _
                  And hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Radiostation Name") = "Modern Blues Radio" Then
                  commercialPlaying = True
                  End If
                  
                  If String.IsNullOrEmpty(hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Artist")) _
                  And hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Track") = "Hit List" _
                  And hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Radiostation Name") = "Hit List" Then
                  commercialPlaying = True
                  End If
                  
                  If hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Artist") = "Station" _
                  And hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Track") = "Hit List" _
                  And hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Radiostation Name") = "Hit List" Then
                  commercialPlaying = True
                  End If
                  
                  If hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Track") = "Pauls-IPhone.m4a" Then
                  intercomPlaying = True
                  End If
                  
                  If hs.DeviceStringByName("Sonos " & mostRecentRoomName & " Track") = "Lizs-IPhone.m4a" Then
                  intercomPlaying = True
                  End If
                  
                  If hs.DeviceValue(1903) = 100 Then
                  announcementPlaying = True
                  End If
                  
                  If hs.GetVar("Sonos_" & mostRecentRoomName & "_reducedvolumestatus") = False Then
                  If commercialPlaying = True Then
                  ReduceVolume(mostRecentRoomName)
                  End If
                  
                  Else If hs.GetVar("Sonos_" & mostRecentRoomName & "_reducedvolumestatus") = True Then
                  If commercialPlaying = False Then
                  If announcementPlaying = False Then
                  If intercomPlaying = False Then
                  RestoreVolume(mostRecentRoomName)
                  End if
                  End If
                  End If
                  
                  End If
                  
                  End Sub
                  
                  
                  
                  
                  
                  Sub ReduceVolume(mostRecentRoomName as String)
                  
                  hs.SaveVar("Sonos_" & mostRecentRoomName & "_originalvolumevalue", hs.DeviceValueByName("Sonos " & mostRecentRoomName & " Volume"))
                  Dim cc As HomeSeerAPI.CAPI.CAPIControl = hs.CAPIGetSingleControl(hs.GetDeviceRefByName("Sonos " & mostRecentRoomName & " Volume"), True, "Volume (value)%", False, False)
                  cc.ControlValue = Math.Round(hs.GetVar("Sonos_" & mostRecentRoomName & "_originalvolumevalue")/2)
                  Dim cr As HomeSeerAPI.CAPI.CAPIControlResponse = hs.CAPIControlHandler(cc)
                  hs.SaveVar("Sonos_" & mostRecentRoomName & "_reducedvolumestatus", True)
                  
                  
                  End Sub
                  
                  
                  
                  
                  
                  
                  Sub RestoreVolume(mostRecentRoomName as String)
                  
                  Dim cc As HomeSeerAPI.CAPI.CAPIControl = hs.CAPIGetSingleControl(hs.GetDeviceRefByName("Sonos " & mostRecentRoomName & " Volume"), True, "Volume (value)%", False, False)
                  cc.ControlValue = Convert.ToInt32(hs.GetVar("Sonos_" & mostRecentRoomName & "_originalvolumevalue"))
                  Dim cr As HomeSeerAPI.CAPI.CAPIControlResponse = hs.CAPIControlHandler(cc)
                  hs.SaveVar("Sonos_" & mostRecentRoomName & "_reducedvolumestatus", False)
                  
                  
                  End Sub

                  The script first checks to see which room was triggered, then checks to see if an Ad is playing. I also check if announcement is playing and if intercom is playing. Then I Reduce the volume or Restore the volume. Player original volume and player status is saved in global variables. It took quite a while to test when ads were playing because they come on infrequently. Works fairly well with one caveat... when returning from an announcement the new Track doesnt update quickly enough to Trigger appropriately. Havent figured that out yet.

                  Comment

                  Working...
                  X