Input_select question

After some long hours, I’m able to control my Control4 Amp and Tuner with HASS (without the need of the Control4 controller itself) and some examples. I do it as a custom component and works nicely. For the sake of ease during testing I created and input_select (in configuration.yaml) which calls and automation to pass values (numeric) that are included in the string sent to the C4 amp for changing the input. Here’s where I’m having an issue, and hopefully someone can help (I’m not a programmer, but able to make sense of most things).

I’d like to display the formal names for the amp inputs (ie Tuner 1, Tuner 2, Volumio, and Bluetooth) instead of 1,2 3, and 4 which are actual values that must pass into the string for it to function. Any suggestions?

Can you post the automation you currently have that works?

Sure, this is the portion of code in question. I got most of it from SmartishHome.com, but was able to make a power switch, and add output as well, but I decided to break it out into different zones (rooms) for the sake of ease on my family. Coming from Control4 has been quite a learning curve (since it comes pretty much standard out of the box). Hopefully the formatting shows correctly.

Thanks for any insight/help.

configuration.yaml

input_select:

radio_stations:
name: Radio Station
icon: mdi:radio
options:
- 103.5
- 105.5
- 106.3
- 107.3
amp_input:
name: Audio Input
icon: mdi:arrow-right-bold
options:
- 1
- 2
- 3
- 4


automations.yaml

- id: C4 AMP Input

alias: Amp Input
trigger:
platform: state
entity_id: input_select.amp_input
action:
service: control4_services.handle_amp_input_select


/custom_components/control4_services.py

import logging

import socket
import random

_LOGGER = logging.getLogger(name)

DOMAIN = ‘control4_services’

def send_udp_command(command, host, port):
COUNTER = “0s2a” + str(random.randint(10, 99))
COMMAND = COUNTER + " " + command + " \r\n"
_LOGGER.warn(“Sending command: %s”, COMMAND)
HOST = host
PORT = port

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto( bytes(COMMAND, "utf-8"), (HOST, PORT))
received = str(sock.recv(1024), "utf-8")
_LOGGER.warn("Command sent. Response: %s", str(received))

def setup(hass, config):

def handle_tuner_channel_select(call):
    """Select input source."""
    _LOGGER.warn("Changing tuner channel...")
    amp_input = hass.states.get("input_select.amp_input").state[:1]
    tuner_station = hass.states.get("input_select.radio_stations").state
    tuner_station = float(tuner_station.partition(" ")[0]) * 100
    tuner_station = hex(int(tuner_station))[2:]
    # tafreq2 = Tuner 1 | tbfreq2 = Tuner 2
    send_udp_command("c4.mt.tafreq2 00 " + str(tuner_station), "192.168.5.14", 8750)
    _LOGGER.warn("Changed tuner channel...")
        
def handle_amp_volume_select(call):
    _LOGGER.warn("Changing amp volume...")
    volume_select = hass.states.get("input_number.amp_volume").state
    volume_select = int(float(volume_select) * 60) + 160
    volume_select = hex(volume_select)[2:]
    send_udp_command("c4.amp.chvol 01 " + volume_select, "192.168.5.11", 8750)
    _LOGGER.warn("Volume set...")
    
def handle_amp_input_select(call):
    _LOGGER.warn("Changing amp input...")
    amp_input = hass.states.get("input_select.amp_input").state[:1]
    amp_input = hex(int(amp_input))[2:]
    send_udp_command("c4.amp.out 01 0" + amp_input, "192.168.5.11", 8750)
    _LOGGER.warn("Amp input changed...")
    

hass.services.register(DOMAIN, 'handle_tuner_channel_select', handle_tuner_channel_select)
hass.services.register(DOMAIN, 'handle_amp_volume_select', handle_amp_volume_select)
hass.services.register(DOMAIN, 'handle_amp_input_select', handle_amp_input_select)

# Return boolean to indicate that initialization was successfull.
return True

It helps immensly if you select the sections of code, and use the code format.

I can’t get to that website. Is that where the custom component came from?

I’m sorry, but I pushed the code format then pasted it…was that wrong?

Anyways, yes, the custom component did come from that site (I was able to build it from a web cache), and the site went down last year sometime. I can send you the actual file I built if you like… I’m not bashing Control 4, but the limitations and cost drove me away (like switches costing $150 each). In the period of 2 weeks I’ve pretty much rebuilt my entire system (all new switches, sensors and door locks are on order). I’m just super glad that I’m able to reuse the amp and tuner. But after finding references to control4 and openhab I followed the breadcrumbs and found the web cache and have gone from there.

Paste it, then select and push format.

Sorry, then it’s my fault. Thanks for schooling me.

No worries. There’s no other way to learn :wink:

Ideally I’d love to refine all the code for controlling Control 4 directly and share it with everyone so people know they aren’t locked in to it.

I can’t find any web caches of that page. Use https://hastebin.com/ to paste the py file. When you save it will generate a webpath.

You won’t… I found bits and pieces after searching for hours then reconstructed…

This is not the original file, I’ve modified it.

https://hastebin.com/cuyizajoju.py

Since there is nothing to feed as a template in your automation, the workaround would be to create a second input select and hide the first.

input_select:
  control4_input:
    options:
      - Tuner 1
      - Tuner 2
      - Volumio
      - Bluetooth

automation:
- alias: 'Tuner Example'
  hide_entity: true
  initial_state: true
  trigger:
    - platform: state
      entity_id: input_select.control4_input
  action:
    service: input_select.select_option
    entity_id: input_select.amp_input
    data_template: 
      option: >-
		{% if is_state('input_select.control4_input', 'Tuner 1') %}1
		{% elif is_state('input_select.control4_input', 'Tuner 2') %}2
		{% elif is_state('input_select.control4_input', 'Volumio') %}3
		{% elif is_state('input_select.control4_input', 'Bluetooth') %}4
		{% else %}1 ### whatever you want to be default
        {%- endif %}

So would the automation section go in the automation file, or all in the configuration file?

Sounds like you already have it referenced elsewhere, so the former. You won’t need to copy ‘input_select:’ and ‘automation:’.

Never thought to do it like this… I assumed I’d have to make the change in the py file, but was having issues with variables… like I said, I’m not a programmer, but can do a little here and there and get myself in trouble. I’m working to test it, but it’s giving me errors and I’m not sure if it’s due to formatting, so give me a few to try and get it working, but thank you very much. Soon as I have this working, I want to share it with everyone (not sure how to do that yet).

I’m over my head with this error. I fixed the formatting, but this is the error I get…

Error while executing automation automation.tuner_example. Invalid data for call_service at pos 1: extra keys not allowed @ data[‘source’]

whoops!!

sorry, it needs to be option.

No reason to be sorry, you’re way smarter than I am with code…

But, I do understand what the code is doing (which is not bad).