Home Assistant direct control of Control4 AMP and Tuner (no plugin needed)

At the risk of sounding arrogant…:wink:

I’m far from a coder. I am a novice when it comes to coding, and when I look at code, my mind goes blank…it’s Chinese to me it’ll take me a lifetime to learn Chinese… that’s why I have Google translate…

frankly I’m surprised I got this far… :rofl:

My goal isn’t to understand how to code/how the code works…

My goal is to copy, paste, and hope for the best…

If it works as intended, that’s a plus…

I’m setting this up for a friend who has less patience than me… I almost have no hair left trying to figure out how to do this…

Do you think grok or ChatGPT would work to compile the code that I need?

In short: Any and all assistance would be most welcomed and appreciated…

Thank you,

Edit* this is what my init.py looks like…

Then the bulk of the code is in control4Amp.py. You can display that.

import socket
import random
import select

def send_udp_command(command, host, port):
    COUNTER = "0s2a" + str(random.randint(10, 99))
    COMMAND = COUNTER + " " + command + " \r\n"

    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(1)
        sock.setblocking(0)
        sock.sendto(bytes(COMMAND, "utf-8"), (host, port))
        data, _ = sock.recvfrom(1024)
        received = str(data, "utf-8")
    except socket.timeout:
        received = "Timeout occurred during data reception"
    except Exception as e:
        received = {e}
    finally:
        sock.close()

    return received




class control4AmpChannel(object):
# Represents a channel of a Control 4 Matrix Amp

    def __init__(self, host, port, channel):
        self._host = host
        self._port = port
        self._channel = channel
        self._source = 1
        self._volume = 0

    @property
    def host(self):
        return self._host

    @property
    def port(self):
        return self._port

    @property
    def channel(self):
        return self._channel

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self,value):
        self._source = value
        return send_udp_command("c4.amp.out 0" + str(self._channel) + " 0" + str(self._source), self._host, self._port)

    @source.deleter
    def source(self):
        del self._source

    @property
    def volume(self):
        return self._volume

    @volume.setter
    def volume(self,value):
        self._volume = value
        new_volume = int(float(self._volume) * 100) + 160
        new_volume = hex(new_volume)[2:]
        send_udp_command("c4.amp.chvol 0" + str(self._channel) + " " + new_volume, self._host, self._port)

    @volume.deleter
    def volume(self):
        del self._volume

    def turn_on(self):
        send_udp_command("c4.amp.psave 00 00", self._host, self._port)
        return send_udp_command("c4.amp.out 0" + str(self._channel) + " 0" + str(self._source), self._host, self._port)

    def turn_off(self):
        return send_udp_command("c4.amp.out 0" + str(self._channel) + " 00", self._host, self._port)

@Mr.Robot, I’m a little lost as to what the issue or issues are or what you’re trying to accomplish. Can you summarize where you’re at?

My sliders work, and the volume changes between zero and 100%. Mute is programmed to set the volume to zero. When you say your sliders are out of sync, where are you observing this? Are you talking about a single output or your master slider?

I don’t know much about music assistant, but from a quick read, it streams music to a device, so you would need a device connected to C4 to stream to. I didn’t see anything about outputting directly from home assistant. I use a Sonos Play connected to my C4.

This should work, but you’ll need to create a button for the mute. Not sure where the rest of the code is.

Add this under @volume.setter

@volume.mute
def mute(self,value):
    send_udp_command("c4.amp.mute 0" + str(self._channel) + " " + new_volume, self._host, self._port)

Thank you,:pray:t3:

More code is needed than what @bigmac posted, and I don’t understand my his mute code has + new_volume. The mute function in my media_player.py is coded to set the volume to zero because I didn’t know the command to mute when writing it.

If you want help, please summarize where you are at and what you’re trying to solve.

I’m just shooting in the dark as I have no idea where the remainder of the code is, but it’s your stuff, and now you know the mute command.

What other code is needed for it to work?

Also why is this not supported?

Thank you,

type: custom:mini-media-player
name: All Zones
entity: media_player.zone_1
hide:
  play_pause: true
  volume_level: false
  source: false
  mute: true
speaker_group:
  platform: media_player
  show_group_count: true
  entities:
    - entity_id: media_player.zone_1
      name: Zone 1
    - entity_id: media_player.zone_2
      name: Zone 2
    - entity_id: media_player.zone_3
      name: Zone 3
    - entity_id: media_player.zone_4
      name: Zone 4
    - entity_id: media_player.zone_5
      name: Zone 5
    - entity_id: media_player.zone_6
      name: Zone 6
    - entity_id: media_player.zone_7
      name: Zone 7
    - entity_id: media_player.zone_8
      name: Zone 8
group: true
toggle_power: true
volume_stateless: false
source: icon

To tell you why this is not supported, I’d need to know what “this” is.

I assume “this” means wanting the C4 custom component to be able to join all channels together. The mini media player group function joins different devices, like multiple Sonos amps, using the Sonos media players’ join function. This was never contemplated when I wrote the C4 component.

I’d have to wrap my head around adding a join function to the C4 media player, as I don’t know of a native “join channels” command. It’s more than I can take on right now.

I handle this type of situation with scripts. I have a script to turn off all channels, and a few scripts to turn on multiple channels for specific situations. e.g., “turn on outside” turns on all three levels of my deck speakers. “turn on bedroom” turns on both the bedroom and bedroom bathroom speakers.

Hi Folks,

Anyone else not working after updating to Core 2024.10.3?

I get these warnings anytime I try to change inputs, and get no audio out no matter what source I choose:

This error originated from a custom integration.

Logger: custom_components.control4-media-player.media_player
Source: custom_components/control4-media-player/media_player.py:149
integration: control4-media-player
First occurred: 3:38:35 PM (34 occurrences)
Last logged: 3:42:17 PM

Source set to Home Assistant
Source set to Gym Bridge
Source set to Bridge
Source set to Server

image

It’s working for me on 2024.10.3

Thanks @Hansen8601! I ended up power cycling the amplifier, and it is working again…very strange. I was listening to it right before the upgrade. I will have to keep an eye on that.

Hello,

I’m looking at what you did and really, I also need help. I look around at “adding a package/addon manually”, but couldn’t find anything in HASS documentation clearly stating how to do it. Can you share the link to that documentation? so far, everything I found and tried failed!

Also, I do not have the Tuner (by the way, is the tuner a distinct device?), but I have a Control4 16 channels Amp with 8 possible sources. So, I’m working on creating the init file for my amp, but there is a few things that still puzzle me. I have 8 rooms, each with two speakers, so I get that I’ll need to have 8 sections like the “Garage” in your example.

The thing I’m not sure to understand is how do I define my 8 sources? I admit that today not all of the inputs are connected to a real source, but at least if I can define them as source 1, source 2 etc, would be a great start. I’ll probably place an Apple TV v3 as one source for Air Play, maybe one other will be the HASS server for it’s imbedded internet radio and local media playback (I’ll populate the Media folder eventually), and others as I continue to growth the system I guess! But so far, my investigation tell me that I may need to define them in the configuration.yaml file, which should be at the root of the config directory structure. I’m all unsure what to do with the automations.yaml file in your repository.

Also, can it be rename to something else than c4_services by changing the directory name and all references in the files? For example, I would prefer c4_16channel_amp as it will be clear to what it refers to. I also have a C4 IO expander, which I’m not really sure can be integrated, but if I succeed with it eventually, that may be very cool to have the two as separate service type.

We bought the house with the control4 already, the HC250 controller died a few weeks ago, so I’m all in to replace it all with HASS. I really like it so far, I can do what I want without a call to a C4 dealer at $95CAD/hour. That 16 Chanel amp, we almost never used it as the C4 interface was so difficult to use, and buggy sometimes, that it stayed off most of the time. If HASS can bring it to life, that would be very great. I was very happy when I found this thread and the possibility ahead of me!

Thank you

Hi @Jamon, for this to work, just place the integration in the right directory in HA per the instructions. You define your zones within configuration.yaml like follows:, naming your channels, increasing your channel (zone) number all the way to 8. This creates a media player for each zone with the name you specify and the source names. I hope this helps.

media_player:  
  - platform: control4-mediaplayer
    name: Great Room
    host: "<AMP_IP_Address>"
    channel: 1
    on_volume: 15
    source_list:
      - "HC800-1"
      - "HC800-2"
      - "Server"
      - "N/A"
      - "Home Assistant"
      - "Bridge"
      - "Gym Bridge"
      - "Aux Audio"
  - platform: control4-mediaplayer
    name: Study
    host: "<AMP_IP_Address>"
    channel: 2
    on_volume: 10
    source_list:
      - "HC800-1"
      - "HC800-2"
      - "Server"
      - "N/A"
      - "Home Assistant"
      - "Bridge"
      - "Gym Bridge"
      - "Aux Audio"

@OtisPresley at first I was really confused about your answer here. I was still looking at the first post/code from @bigmac and your answer did not fit at all with the code I was looking at. Then I decided to read further into the post until I saw the one from @Hansen8601, and suddenly I saw the light!!!

I did a quick test, adding one zone and dummy entries, and I saw the integration coming into the default view. I will postpone the rest of the work tomorrow as I’m getting tired tonight, but really, I think I can make it work easily. I’ll further test it in the next few days, but really, I’m just amazed by how simple that was in the end.

Thank you all for the great work!

Hello

I played with this again and I’m making great progress’s.

I added all my zones in the configuration file and I just validated in front of the amp that when I turn a zone on/off the amp is showing sign of receiving commands. I saw on the display that a number appeared in front of the Dx name. Very encouraging.

But I also went in the settings for the zone 1 and saw the input value was not showing anything even if an input was selected in Home Assistant. Just a “-” was visible instead of an input value that should have read as "Stereo 1” for example. Not sure if I missed anything here.

That said, this evening I had fun creating myself a custom card for that integration with a few scripts to turn it all off, plus volume up/down. I’m having a blast with Home Assistant for the last 2-3 weeks. I never had such fun with the Control4 system in the first 4 years since we moved into this house.

I’m glad you’re enjoying the integration. Control of the c4 from Home Assistant is one of my most used integrations. I love coming home, and HA automatically turns on the music before I walk into the house.

When you say you see “-”, I don’t know if you mean on the amp or somewhere in HA. The integration won’t send any text to the amp; it will only switch inputs. A real test would be switching the input from 1 to 2 in HA and verifying the amp switches what’s playing.

Hello

I’m just getting started with HA, but so far enjoying what it can do and how easy it is to customize it.

Yes when I talked about the “-”, I was referring to the amp display. Changing the inputs in HA did not changed anything on the amp. I did another test after my post and couldn’t see anything in the HA log either for the source changes, while I could see the zone logs (on/off for example) showing. Maybe I do have something misconfigure in my files.

Oh I finally got it working. I’m not so sure what I did wrong but I have multiple options:

  • when I was initially testing, I may have been monitoring the wrong output on the amplifier as the order is not the same as how they are listed in HA
  • in any case I deleted the pycache directory and restarted the HA server
  • in the HA log I was only looking at the UI log, when I found the raw log entries I clearly saw the source selection command behind send

So a huge thanks to all the peoples who contributed to this integration. When the Control4 tech came here a few weeks ago and told me I should upgrade to a new controller because the HC250 was dead, buuuutttt he told me that maybe the control4 amp may not be compatible, that was a big turn off for me. Not only their amp never worked well for my with their controller (the UI was terrible to use in the mobile app), but in addition to a new controller over 2k I may have to upgrade the amp too. Wow how well minded I was to get their system out the door. I’m so happy to have a friend who told me to try Home Assistant, and with his help and the support of this community, my home automation, while not up to the state it was yet, is progressing very fast and in ways that was not even thinkable with the over priced Control4 system.

Next steps for me:

  • complete the lights automation. We have some Control4 light switches that I may or not be able to integrate with Zigbee.
  • the home theatre needs to be put on its feet too.

Thank you all again