Monoprice 6-zone Audio amp items, sitemap & rules

While I want you to get excited that it is coming, don’t get too excited. Getting my whole home audio system fully running is pretty far down my list. I’ve been focusing on improving the HomeKit service first (adding support for lots more accessory types, and being more reliable), but I need to get a big jump on it - right now it has an (Apple) limitation of 150 accessories, and I’m already at 130, with lots more smart devices coming soon. So I gotta get that fixed. And then I need basic connections with several more device types. Then I can circle back around to this.

Ah, but the important thing is you got it started! I haven’t had time to even consider writing a dedicated binding for it. The rules I originally wrote have worked just fine for 4+ years, improved by the folks here over time, but I’ve always thought this was a large enough interface to warrant its own binding, especially after @tony_alpskog mentioned that it works for about 5 different manufacturers’ models (and also because a binding should do a better job of refreshing/holding the amp zone states). Maybe we can all collaborate to get it to a point where it’s included in the OH2 snapshots, even if your focus will be elsewhere for the time being. So, thanks for kicking it off (the hard part, I think)!

I fixed the major communications issues. Once I get it running, it seems to work just fine now.

2 Likes

Thank you for the information you shared, I’m trying to get price of Factor X-66 but there is nothing on the site neither on Amazon. could you share where did you got pricing?

thank you!

@AlejandroG I bought mine directly from monoprice.com. The amp is the exact same as the Factor Electronics version. My comment was in regard to the manual. The Factor manual is better than the Monoprice manual.

One note with Monoprice, the prices will fluctuate quite a bit so you may want to watch pricing a bit before you buy.

1 Like

Thank you @swamiller for your fast response, probably from the coding stand point they are the same but the one you referred has some little but interesting differences I would like to explore while coding an improved UI for it. the problem is they don’t have prices, resellers or dealers so don’t know how to buy. I sent them an email we’ll see if they respond! again great thread! thank you again!

I’ve been using @bartus items, sitemaps and rules for the Monoprice 6-zone for a few years and it’s been great.I just upgrade to 2.5 and it is no longer working for me.

Should the “old” method still work? If so, any suggestions on what needs to be done for 2.5 compatibility?

I see that @ccutrer wrote a binding but I don’t see it available under 2.5 paperUI. Is this considered the “replacement” method and if so do I need to manually install this?

If someone can point me in the right direction it would be greatly appreciated.

Thank you!

There is a near infinity contained in the words “no longer working”. Do you see errors in the logs? Do you see indication that the necessary events are happening to trigger the Rules? Do you see evidence that the Rules are running?

I’m using an adapted version from @tony_alpskog for using a Globalcache LAN to Serial converter.

Nothing changed for me with OH 2.5 or 2.5.1. Everything still works.

I apologize for my post for help which was lacking details. TBH, I assumed it was a known issue upgrading and that I needed to change my method. Since others such as @swamiller indicated that they didn’t need to make changes when going to 2.5 or 2.51, I realized I needed to look into this deeper.

At first I had a lot of errors with my items, rules and sitemaps after upgrading to 2.5. I started commenting out things which I thought might cause problems, like my monoprice info. I don’t know if it was related but my problem with nothing showing on the sitemap/interfaces resolved itself. Sine then I put my old sitemaps, rules and items files back. I’m still not able to control my monoprice amp.

If I try to turn a zone on from my sitemap I get:>

    2020-01-14 20:04:14.747 [INFO ] [pse.smarthome.model.script.MonoPrice] - Zone 1 Power ON

    ==> /var/log/openhab2/events.log <==

    2020-01-14 20:04:14.758 [ome.event.ItemCommandEvent] - Item 'AudioMTX' received command ?11

    2020-01-14 20:04:14.766 [vent.ItemStateChangedEvent] - AudioMTX changed from <11PR01

     to ?11

    2020-01-14 20:04:15.068 [vent.ItemStateChangedEvent] - MonoPrice_Status changed from ?12 to ?11

    ==> /var/log/openhab2/openhab.log <==

    2020-01-14 20:04:15.406 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'MonoPrice Status on command change': No match found

If I try to change the status on the Monoprice device, I get nothing at all.

My guess is the problem is related to

Could not open serial port /dev/ttyUSB0: Serial port ‘/dev/ttyUSB0’ could not be found. Available ports are:

/dev/ttyACM0

I am just at a loss on how to troubleshoot.

That error means the serial devices either doesn’t exist or it’s permissions are such that the OH user cannot read/write to it. Assuming the error is coming from the amp, that means oh can’t communicate with the amp. You need to figure on why the device isn’t there. A first step is to restart the machine.

1 Like

And that would be the last step since it worked. While the machine/Pine64 rebooted after the upgrade, I guess it needed another one since communication with the USB/serial was lost.

I greatly appreciate the help. One nice thing to come out of this issue is that I now know of some enhancements to what I was using before.

Edit: I guess I didn’t realize that whenever I do an update that I will need to update as the serial interface drops and I then get a ton of errors.

Thank you!

Sorry to revive this topic, but I am having issues with my new monoprice 6 zone amp and was hoping someone could point me in the right direction. My hunch is the amp version is a little different, hence my problems, but I can’t figure out which parts I might need to adjust. I’m running OH 2.5.3 on a fresh install of openhabian. I’ve rebooted countless times and ensured openhab is in the dialout group to no avail.

I am using the items, rules, and sitemap from the first post. When I adjust from the sitemap I get the “No match found” error that was mentioned before. When I adjust from the amp, though, the AudioMTX item gets updated like so:

2020-04-18 12:44:33.943 [vent.ItemStateChangedEvent] - AudioMTX changed from ?1PR1+ to ?1VO14+
2020-04-18 12:44:34.487 [vent.ItemStateChangedEvent] - AudioMTX changed from ?1VO14+ to ?1VO15+
2020-04-18 12:44:34.939 [vent.ItemStateChangedEvent] - AudioMTX changed from ?1VO15+ to ?1VO16+
2020-04-18 12:44:35.143 [vent.ItemStateChangedEvent] - AudioMTX changed from ?1VO16+ to ?1VO17+

So the communication seems to be there, but it doesn’t do anything else. I also installed the binding referenced above and everything said ONLINE, but I couldn’t control anything. This is why I think openHAB and the amp are talking to one another, but the amp is saying something other than expected.

I am using the Monoprice 31028 (manual here pages 22-24), and I think maybe this was written for 10761.

At this point I’m just hoping someone can confirm that is the issue, then maybe I can figure out how to adapt the code to what I need.

Any help appreciated!

Edited to added more details.

Ah, I think I’ve cracked it! Will update with some code for the 31028 when I update everything.

Thanks everyone for all the work you’ve put into this.

1 Like

Post it back here when you do, so others can find it by coming to this post in the years to come :slight_smile:

It isn’t perfect, but it works well enough for my purposes. Changes I had to make:

  1. Since the 30128 doesn’t have the master/slave function the zone numbers are all just single digits.
  2. Some of the acronyms change when you are sending commands to the unit (BL for balance in the original code, BA in mine)
  3. “+” added to the end of commands sent to the unit, and < changed to !.
  4. Zone status updates only send five variables (3ZS VO8 PO1 MU0 IS0+ - zone number, volume, power, mute, and input select). Sometimes after it received a command it would append that commend to the beginning of the status update (?3VO8+#3ZS VO8 PO1 MU0 IS0+), which messed up getting the proper zone number. Had to play around with the regex to to make this work consistently.
  5. The unit only has two inputs, either the line for the zone or a bus shared by all zones.
  6. You can adjust balance, treble, and bass, but these values aren’t sent as part of the zone status. (I assume the other unit reports all at once?) You can query these individually, though. My adjusted code can adjust these values, but won’t change it if it is changed through the remote or is reset for some reason.

I’m sure there were other adjustments I made, but they are escaping me right now. And this is all a hobby for me, so I am sure I’ve missed something somewhere along the line. It all seems to work, though!

ITEMS

Group gZonePowerSwitch (all)
Group gZoneVolume (all)
Group gZoneMuteSwitch (all)
Group gZoneSource (all)
Group gZoneTone (all)
Group gZoneBalance (all)
Group gMonoPriceStatus (all)

String AudioMTX “Audio Matrix” { serial="/dev/ttyUSB0@9600" }
String AudioMTX_Receive “Audio Matrix Receive”
Switch MonoPrice_Refresh “Refresh String”
String MonoPrice_Receive_String “Received Response”
String MonoPrice_Status “MonoPrice Status [%s]”
String MonoPrice_Status_G1 “MP G1 (Zone) [%s]” (gMonoPriceStatus)
Number MonoPrice_Status_G2 “MP G2 (Volume Status) [%.0f]” (gMonoPriceStatus)
String MonoPrice_Status_G3 “MP G3 (Pwr Status) [%s]” (gMonoPriceStatus)
String MonoPrice_Status_G4 “MP G4 (Mute Status) [%s]” (gMonoPriceStatus)
Number MonoPrice_Status_G5 “MP G5 (Src Status) [%.0f]” (gMonoPriceStatus)
String MonoPrice_Z1 “Zone 1 Status [%s]”
String MonoPrice_Z2 “Zone 2 Status [%s]”
String MonoPrice_Z3 “Zone 3 Status [%s]”
String MonoPrice_Z4 “Zone 4 Status [%s]”
String MonoPrice_Z5 “Zone 5 Status [%s]”
String MonoPrice_Z6 “Zone 6 Status [%s]”
Switch MonoPrice_Z1_Power “Zone 1 Power [%s]” (gZonePowerSwitch) [ “Switchable” ]
Switch MonoPrice_Z2_Power “Zone 2 Power [%s]” (gZonePowerSwitch) [ “Switchable” ]
Switch MonoPrice_Z3_Power “Zone 3 Power [%s]” (gZonePowerSwitch) [ “Switchable” ]
Switch MonoPrice_Z4_Power “Zone 4 Power [%s]” (gZonePowerSwitch) [ “Switchable” ]
Switch MonoPrice_Z5_Power “Zone 5 Power [%s]” (gZonePowerSwitch) [ “Switchable” ]
Switch MonoPrice_Z6_Power “Zone 6 Power [%s]” (gZonePowerSwitch) [ “Switchable” ]
Switch MonoPrice_Z1_Mute “Zone 1 Mute [%s]” (gZoneMuteSwitch) [ “Switchable” ]
Switch MonoPrice_Z2_Mute “Zone 2 Mute [%s]” (gZoneMuteSwitch) [ “Switchable” ]
Switch MonoPrice_Z3_Mute “Zone 3 Mute [%s]” (gZoneMuteSwitch) [ “Switchable” ]
Switch MonoPrice_Z4_Mute “Zone 4 Mute [%s]” (gZoneMuteSwitch) [ “Switchable” ]
Switch MonoPrice_Z5_Mute “Zone 5 Mute [%s]” (gZoneMuteSwitch) [ “Switchable” ]
Switch MonoPrice_Z6_Mute “Zone 6 Mute [%s]” (gZoneMuteSwitch) [ “Switchable” ]
Dimmer MonoPrice_Z1_Volume “Zone 1 Volume [%02d %%]” (gZoneVolume) [ “Switchable” ]
Dimmer MonoPrice_Z2_Volume “Zone 2 Volume [%02d %%]” (gZoneVolume) [ “Switchable” ]
Dimmer MonoPrice_Z3_Volume “Zone 3 Volume [%02d %%]” (gZoneVolume) [ “Switchable” ]
Dimmer MonoPrice_Z4_Volume “Zone 4 Volume [%02d %%]” (gZoneVolume) [ “Switchable” ]
Dimmer MonoPrice_Z5_Volume “Zone 5 Volume [%02d %%]” (gZoneVolume) [ “Switchable” ]
Dimmer MonoPrice_Z6_Volume “Zone 6 Volume [%02d %%]” (gZoneVolume) [ “Switchable” ]
Number MonoPrice_Z1_Source “Zone 1 Source [%.0f]” (gZoneSource)
Number MonoPrice_Z2_Source “Zone 2 Source [%.0f]” (gZoneSource)
Number MonoPrice_Z3_Source “Zone 3 Source [%.0f]” (gZoneSource)
Number MonoPrice_Z4_Source “Zone 4 Source [%.0f]” (gZoneSource)
Number MonoPrice_Z5_Source “Zone 5 Source [%.0f]” (gZoneSource)
Number MonoPrice_Z6_Source “Zone 6 Source [%.0f]” (gZoneSource)
Dimmer MonoPrice_Z1_Treble “Zone 1 Treble [%02d %%]” (gZoneTone) [ “Switchable” ]
Dimmer MonoPrice_Z2_Treble “Zone 2 Treble [%02d %%]” (gZoneTone) [ “Switchable” ]
Dimmer MonoPrice_Z3_Treble “Zone 3 Treble [%02d %%]” (gZoneTone) [ “Switchable” ]
Dimmer MonoPrice_Z4_Treble “Zone 4 Treble [%02d %%]” (gZoneTone) [ “Switchable” ]
Dimmer MonoPrice_Z5_Treble “Zone 5 Treble [%02d %%]” (gZoneTone) [ “Switchable” ]
Dimmer MonoPrice_Z6_Treble “Zone 6 Treble [%02d %%]” (gZoneTone) [ “Switchable” ]
Dimmer MonoPrice_Z1_Bass “Zone 1 Bass [%02d %%]” (gZoneTone) [ “Switchable” ]
Dimmer MonoPrice_Z2_Bass “Zone 2 Bass [%02d %%]” (gZoneTone) [ “Switchable” ]
Dimmer MonoPrice_Z3_Bass “Zone 3 Bass [%02d %%]” (gZoneTone) [ “Switchable” ]
Dimmer MonoPrice_Z4_Bass “Zone 4 Bass [%02d %%]” (gZoneTone) [ “Switchable” ]
Dimmer MonoPrice_Z5_Bass “Zone 5 Bass [%02d %%]” (gZoneTone) [ “Switchable” ]
Dimmer MonoPrice_Z6_Bass “Zone 6 Bass [%02d %%]” (gZoneTone) [ “Switchable” ]
Dimmer MonoPrice_Z1_Balance “Zone 1 Balance [%02d %%]” (gZoneBalance) [ “Switchable” ]
Dimmer MonoPrice_Z2_Balance “Zone 2 Balance [%02d %%]” (gZoneBalance) [ “Switchable” ]
Dimmer MonoPrice_Z3_Balance “Zone 3 Balance [%02d %%]” (gZoneBalance) [ “Switchable” ]
Dimmer MonoPrice_Z4_Balance “Zone 4 Balance [%02d %%]” (gZoneBalance) [ “Switchable” ]
Dimmer MonoPrice_Z5_Balance “Zone 5 Balance [%02d %%]” (gZoneBalance) [ “Switchable” ]
Dimmer MonoPrice_Z6_Balance “Zone 6 Balance [%02d %%]” (gZoneBalance) [ “Switchable” ]

RULES

import java.util.regex.Matcher
import java.util.regex.Pattern

var String zone

rule “MonoPrice Status on command change”
when
Item MonoPrice_Status changed or
System started
then
var String MonoPrice_ResponseExpr = “.*#(\d+)ZS VO(\d+) PO(\d+) MU(\d+) IS(\d+)\+”
var Pattern pattern = null
var Matcher matcher = null
pattern = Pattern::compile(MonoPrice_ResponseExpr)
matcher = pattern.matcher(AudioMTX.toString)
matcher.find()
Thread::sleep(300)
for(var int i = 1; i <= gMonoPriceStatus.members.size; i=i+1){
postUpdate(“MonoPrice_Status_G”+i, matcher.group(i))
}
end

rule “Volume (G2) Update”
when
Item MonoPrice_Status_G2 received update
then
val Number vol = ((MonoPrice_Status_G2.state as DecimalType) / 38 * 100).intValue
val int num = Integer::parseInt(MonoPrice_Status_G1.state.toString)
postUpdate(“MonoPrice_Z”+num+"_Volume", vol.toString)
logInfo(“MonoPrice”, "Volume updated to zone " + num + " Volume level " + vol)
end

rule “Power (G3) Update”
when
Item MonoPrice_Status_G3 received update
then
if(MonoPrice_Status_G3.state == “1”){
val in num = Integer::parseInt(MonoPrice_Status_G1.state.toString)
postUpdate(“MonoPrice_Z” + num + “_Power”, “ON”)
}
else {
val int num = Integer::parseInt(MonoPrice_Status_G1.state.toString)
postUpdate(“MonoPrice_Z” + num + “_Power”, “OFF”)
}
end

rule “Mute (G4) Update”
when
Item MonoPrice_Status_G4 received update
then
if(MonoPrice_Status_G4.state == “1”){
val int num = Integer::parseInt(MonoPrice_Status_G1.state.toString)
postUpdate(“MonoPrice_Z”+num+"_Mute", “ON”)
}
else {
val int num = Integer::parseInt(MonoPrice_Status_G1.state.toString)
postUpdate(“MonoPrice_Z”+num+"_Mute", “OFF”)
}
end

rule “Source (G5) Update”
when
Item MonoPrice_Status_G5 received update
then
val sor = MonoPrice_Status_G5.state
val int num = Integer::parseInt(MonoPrice_Status_G1.state.toString)
postUpdate(“MonoPrice_Z”+num+"_Source", sor.toString)
logInfo(“MonoPrice”, "Source updated to zone "+ num + " Source Number " + sor)
end

rule “Refresh Switch” //used during system startup, cycle through each zone
when
Item MonoPrice_Refresh received command ON or
System started
then
for(var int i=1; i <= 6; i = i+1){
AudioMTX.sendCommand("?"+i+“ZS+\r”)
Thread::sleep(600)
MonoPrice_Status.postUpdate(AudioMTX.state.toString.trim)
}
logInfo(“Monoprice”, “Monoprice Amp items refreshed”)
end

rule “MonoPrice Zone Power”
when
Item MonoPrice_Z1_Power received command or
Item MonoPrice_Z2_Power received command or
Item MonoPrice_Z3_Power received command or
Item MonoPrice_Z4_Power received command or
Item MonoPrice_Z5_Power received command or
Item MonoPrice_Z6_Power received command
then
Thread::sleep(100)
val power = triggeringItem as SwitchItem
switch power {
case MonoPrice_Z1_Power: zone =“1”
case MonoPrice_Z2_Power: zone =“2”
case MonoPrice_Z3_Power: zone =“3”
case MonoPrice_Z4_Power: zone =“4”
case MonoPrice_Z5_Power: zone =“5”
case MonoPrice_Z6_Power: zone =“6”
}
if(receivedCommand==ON){
AudioMTX.sendCommand("!" + zone + “PR1+\r”)
logInfo(“MonoPrice”, “Zone “+ zone + " Power ON”)
}
else if(receivedCommand==OFF){
AudioMTX.sendCommand(”!" + zone + “PR0+\r”)
logInfo(“MonoPrice”, “Zone " + zone + " Power OFF”)
}
AudioMTX.sendCommand("?" + zone + “ZS+\r”)
Thread::sleep(300)
MonoPrice_Status.postUpdate(AudioMTX.state.toString.trim)
end

rule “MonoPrice Zone Volume”
when
Item MonoPrice_Z1_Volume received command or
Item MonoPrice_Z2_Volume received command or
Item MonoPrice_Z3_Volume received command or
Item MonoPrice_Z4_Volume received command or
Item MonoPrice_Z5_Volume received command or
Item MonoPrice_Z6_Volume received command
then
Thread::sleep(100)
val volume = triggeringItem as DimmerItem
var Number volume_z
switch volume {
case MonoPrice_Z1_Volume: zone =“1”
case MonoPrice_Z2_Volume: zone =“2”
case MonoPrice_Z3_Volume: zone =“3”
case MonoPrice_Z4_Volume: zone =“4”
case MonoPrice_Z5_Volume: zone =“5”
case MonoPrice_Z6_Volume: zone =“6”
}
if(receivedCommand instanceof PercentType) {
volume_z = receivedCommand
volume_z = (volume_z * 38 / 100).intValue
} else {
if(receivedCommand==INCREASE)
{
volume_z = volume_z + 1
}
if(receivedCommand==DECREASE)
{
volume_z = volume_z - 1
}
}
if (volume_z>9) {AudioMTX.sendCommand("!" + zone + “VO” + volume_z.toString + “+\r”) }
else {AudioMTX.sendCommand("!" + zone + “VO0” + volume_z.toString + “+\r”) }
volume.postUpdate((volume_z / 38 * 100).intValue)
AudioMTX.sendCommand("?" + zone + “ZS+\r”)
Thread::sleep(300)
MonoPrice_Status.postUpdate(AudioMTX.state.toString.trim)
end

rule “MonoPrice Zone Mute”
when
Item MonoPrice_Z1_Mute received command or
Item MonoPrice_Z2_Mute received command or
Item MonoPrice_Z3_Mute received command or
Item MonoPrice_Z4_Mute received command or
Item MonoPrice_Z5_Mute received command or
Item MonoPrice_Z6_Mute received command
then
Thread::sleep(100)
val mute = triggeringItem as SwitchItem
switch mute {
case MonoPrice_Z1_Mute: zone =“1”
case MonoPrice_Z2_Mute: zone =“2”
case MonoPrice_Z3_Mute: zone =“3”
case MonoPrice_Z4_Mute: zone =“4”
case MonoPrice_Z5_Mute: zone =“5”
case MonoPrice_Z6_Mute: zone =“6”
}
if(receivedCommand==ON){
AudioMTX.sendCommand("!" + zone + “MU1+\r”)
logInfo(“MonoPrice”, “Zone “+ zone + " Mute ON”)
}
else if(receivedCommand==OFF){
AudioMTX.sendCommand(”!" + zone + “MU0+\r”)
logInfo(“MonoPrice”, “Zone " + zone + " Mute OFF”)
}
AudioMTX.sendCommand("?" + zone + “+\r”)
Thread::sleep(300)
MonoPrice_Status.postUpdate(AudioMTX.state.toString.trim)
end

rule “MonoPrice Zone Source”
when
Item MonoPrice_Z1_Source received command or
Item MonoPrice_Z2_Source received command or
Item MonoPrice_Z3_Source received command or
Item MonoPrice_Z4_Source received command or
Item MonoPrice_Z5_Source received command or
Item MonoPrice_Z6_Source received command
then
Thread::sleep(100)
val source = triggeringItem as NumberItem
switch source {
case MonoPrice_Z1_Source: zone =“1”
case MonoPrice_Z2_Source: zone =“2”
}
AudioMTX.sendCommand("!" + zone + “IS” + source.state.toString + “+\r”)
AudioMTX.sendCommand("?" + zone + “+\r”)
Thread::sleep(300)
MonoPrice_Status.postUpdate(AudioMTX.state.toString.trim)
end

rule “MonoPrice Zone Tone”
when
Item MonoPrice_Z1_Treble received command or
Item MonoPrice_Z2_Treble received command or
Item MonoPrice_Z3_Treble received command or
Item MonoPrice_Z4_Treble received command or
Item MonoPrice_Z5_Treble received command or
Item MonoPrice_Z6_Treble received command or
Item MonoPrice_Z1_Bass received command or
Item MonoPrice_Z2_Bass received command or
Item MonoPrice_Z3_Bass received command or
Item MonoPrice_Z4_Bass received command or
Item MonoPrice_Z5_Bass received command or
Item MonoPrice_Z6_Bass received command
then
var Number toneslider_z
var String tone_z
Thread::sleep(100)
val tone = triggeringItem as DimmerItem
switch tone {
case MonoPrice_Z1_Treble: {
zone =“1”
tone_z = “1TR”
}
case MonoPrice_Z2_Treble: {
zone =“2”
tone_z = “2TR”
}
case MonoPrice_Z3_Treble: {
zone =“3”
tone_z = “3TR”
}
case MonoPrice_Z4_Treble: {
zone =“4”
tone_z = “4TR”
}
case MonoPrice_Z5_Treble: {
zone =“5”
tone_z = “5TR”
}
case MonoPrice_Z6_Treble: {
zone =“6”
tone_z = “6TR”
}
case MonoPrice_Z1_Bass: {
zone =“1”
tone_z = “1BS”
}
case MonoPrice_Z2_Bass: {
zone =“2”
tone_z = “2BS”
}
case MonoPrice_Z3_Bass: {
zone =“3”
tone_z = “3BS”
}
case MonoPrice_Z4_Bass: {
zone =“4”
tone_z = “4BS”
}
case MonoPrice_Z5_Bass:{
zone =“5”
tone_z = “5BS”
}
case MonoPrice_Z6_Bass: {
zone =“6”
tone_z = “6BS”
}
}
if(receivedCommand instanceof PercentType) {
toneslider_z = receivedCommand
toneslider_z = (toneslider_z * 14 / 100).intValue
} else {
if(receivedCommand==INCREASE)
{
toneslider_z = toneslider_z + 1
}
if(receivedCommand==DECREASE)
{
toneslider_z = toneslider_z - 1
}
}
AudioMTX.sendCommand("!" + tone_z + toneslider_z.toString + “+\r”)
tone.postUpdate((toneslider_z / 14 * 100).intValue)
AudioMTX.sendCommand("!" + zone + “TR+\r”)
Thread::sleep(300)
MonoPrice_Status.postUpdate(AudioMTX.state.toString.trim)
end

rule “MonoPrice Zone Balance”
when
Item MonoPrice_Z1_Balance received command or
Item MonoPrice_Z2_Balance received command or
Item MonoPrice_Z3_Balance received command or
Item MonoPrice_Z4_Balance received command or
Item MonoPrice_Z5_Balance received command or
Item MonoPrice_Z6_Balance received command
then
var Number balance_z
val balance = triggeringItem as DimmerItem
Thread::sleep(100)
switch balance {
case MonoPrice_Z1_Balance: zone =“1”
case MonoPrice_Z2_Balance: zone =“2”
case MonoPrice_Z3_Balance: zone =“3”
case MonoPrice_Z4_Balance: zone =“4”
case MonoPrice_Z5_Balance: zone =“5”
case MonoPrice_Z6_Balance: zone =“6”
}

    if(receivedCommand instanceof PercentType) {                    
            balance_z = receivedCommand
            balance_z = (balance_z * 63 / 100).intValue             
    } else {
                    if(receivedCommand==INCREASE)                  
                    {
                            balance_z = balance_z + 1
                    }
                    if(receivedCommand==DECREASE)
                    {
                            balance_z = balance_z - 1
                    }
            }
    AudioMTX.sendCommand("!" + zone + "BA" + balance_z.toString + "+\r")
    balance.postUpdate((balance_z / 63 * 100).intValue)                              
    AudioMTX.sendCommand("?" + zone + "BA+\r")                                            
    Thread::sleep(300)
    MonoPrice_Status.postUpdate(AudioMTX.state.toString.trim)
end

SITEMAP

sitemap default label=“Default”
            {
            Frame label=“MonoPrice” {
            Switch item=MonoPrice_Refresh
            //Text item=AudioMTX_Receive
            //Text item=MonoPrice_Status
            Text item=MonoPrice_Z1_Power
            Switch item=MonoPrice_Z1_Power
            Selection item=MonoPrice_Z1_Source label=“Zone 1 Source” mappings=[0=Bus,1=Input] visibility=[MonoPrice_Z1_Power==ON]
            Slider item=MonoPrice_Z1_Volume visibility=[MonoPrice_Z1_Power==ON]
            Switch item=MonoPrice_Z1_Mute visibility=[MonoPrice_Z1_Power==ON]
            Slider item=MonoPrice_Z1_Treble visibility=[MonoPrice_Z1_Power==ON]
            Slider item=MonoPrice_Z1_Bass visibility=[MonoPrice_Z1_Power==ON]
            Slider item=MonoPrice_Z1_Balance visibility=[MonoPrice_Z1_Power==ON]
            Text item=MonoPrice_Z2_Power
            Switch item=MonoPrice_Z2_Power
            Selection item=MonoPrice_Z2_Source label=“Zone 2 Source” mappings=[0=Bus,1=Input] visibility=[MonoPrice_Z2_Power==ON]
            Slider item=MonoPrice_Z2_Volume visibility=[MonoPrice_Z2_Power==ON]
            Switch item=MonoPrice_Z2_Mute visibility=[MonoPrice_Z2_Power==ON]
            Slider item=MonoPrice_Z2_Treble visibility=[MonoPrice_Z2_Power==ON]
            Slider item=MonoPrice_Z2_Bass visibility=[MonoPrice_Z2_Power==ON]
            Slider item=MonoPrice_Z2_Balance visibility=[MonoPrice_Z2_Power==ON]
            Text item=MonoPrice_Z3_Power
            Switch item=MonoPrice_Z3_Power
            Selection item=MonoPrice_Z3_Source label=“Zone 3 Source” mappings=[0=Bus,1=Input] visibility=[MonoPrice_Z3_Power==ON]
            Slider item=MonoPrice_Z3_Volume visibility=[MonoPrice_Z3_Power==ON]
            Switch item=MonoPrice_Z3_Mute visibility=[MonoPrice_Z3_Power==ON]
            Slider item=MonoPrice_Z3_Treble visibility=[MonoPrice_Z3_Power==ON]
            Slider item=MonoPrice_Z3_Bass visibility=[MonoPrice_Z3_Power==ON]
            Slider item=MonoPrice_Z3_Balance visibility=[MonoPrice_Z3_Power==ON]
            Text item=MonoPrice_Z4_Power
            Switch item=MonoPrice_Z4_Power
            Selection item=MonoPrice_Z4_Source label=“Zone 4 Source” mappings=[0=Bus,1=Input] visibility=[MonoPrice_Z4_Power==ON]
            Slider item=MonoPrice_Z4_Volume visibility=[MonoPrice_Z4_Power==ON]
            Switch item=MonoPrice_Z4_Mute visibility=[MonoPrice_Z4_Power==ON]
            Slider item=MonoPrice_Z4_Treble visibility=[MonoPrice_Z4_Power==ON]
            Slider item=MonoPrice_Z4_Bass visibility=[MonoPrice_Z4_Power==ON]
            Slider item=MonoPrice_Z4_Balance visibility=[MonoPrice_Z4_Power==ON]
            Text item=MonoPrice_Z5_Power
            Switch item=MonoPrice_Z5_Power
            Selection item=MonoPrice_Z5_Source label=“Zone 5 Source” mappings=[0=Bus,1=Input] visibility=[MonoPrice_Z5_Power==ON]
            Slider item=MonoPrice_Z5_Volume visibility=[MonoPrice_Z5_Power==ON]
            Switch item=MonoPrice_Z5_Mute visibility=[MonoPrice_Z5_Power==ON]
            Slider item=MonoPrice_Z5_Treble visibility=[MonoPrice_Z5_Power==ON]
            Slider item=MonoPrice_Z5_Bass visibility=[MonoPrice_Z5_Power==ON]
            Slider item=MonoPrice_Z5_Balance visibility=[MonoPrice_Z5_Power==ON]
            Text item=MonoPrice_Z6_Power
            Switch item=MonoPrice_Z6_Power
            Selection item=MonoPrice_Z6_Source label=“Zone 6 Source” mappings=[0=Bus,1=Input] visibility=[MonoPrice_Z6_Power==ON]
            Slider item=MonoPrice_Z6_Volume visibility=[MonoPrice_Z6_Power==ON]
            Switch item=MonoPrice_Z6_Mute visibility=[MonoPrice_Z6_Power==ON]
            Slider item=MonoPrice_Z6_Treble visibility=[MonoPrice_Z6_Power==ON]
            Slider item=MonoPrice_Z6_Bass visibility=[MonoPrice_Z6_Power==ON]
            Slider item=MonoPrice_Z6_Balance visibility=[MonoPrice_Z6_Power==ON]
            }
            }
1 Like

I wrote a native binding for the 10761. It is not merged into the mainline yet… But you can get the jar here if you want to test it out: https://github.com/openhab/openhab-addons/pull/7371

1 Like

Excellent work @mlobstein - thank you!

I’ve incorporated the binding into my own setup, and it’s working very well (much faster than the original rules). I’ve retired the old rules file and modified my items to access the thing channels now. For anyone moving over to this binding, here is my configuration for reference:

ITEMS:

SITEMAP:

	Switch item=MonoPrice_Z12_Power
	Selection item=MonoPrice_Z12_Source visibility=[MonoPrice_Z12_Power==ON] icon="receiver"
	Slider item=MonoPrice_Z12_Volume visibility=[MonoPrice_Z12_Power==ON] icon="soundvolume"
	Switch item=MonoPrice_Z12_Mute visibility=[MonoPrice_Z12_Power==ON]	
	Setpoint item=MonoPrice_Z12_Balance visibility=[MonoPrice_Z12_Power==ON] minValue=-7 maxValue=7
	Setpoint item=MonoPrice_Z12_Bass visibility=[MonoPrice_Z12_Power==ON] minValue=-7 maxValue=7
	Setpoint item=MonoPrice_Z12_Treble visibility=[MonoPrice_Z12_Power==ON] minValue=-7 maxValue=7	

Enjoy, and thanks again for your hard work @mlobstein !

1 Like

Congrats on the new binding!

3 Likes

I have done some new modifications to the Monoprice binding code. I have added support for the Monoprice 31028 as well as Xantech 4x4 and 8x8 amplifiers which use a similar protocol. I have tested the changes with the originally supported Monoprice 10761/Dayton DAX66 and there seem to be no issues. But since I do not have any of the other amplifier models, I need some feedback that there are no issues before I would do a PR to merge the changes into the main distribution.

The test jar containing these changes can be found here: https://github.com/mlobstein/mlobstein-beta-test/raw/master/org.openhab.binding.monopriceaudio-3.2.0-SNAPSHOT.jar

Please report any issues or successes.

I found some good information about the other amps’ communication protocols here:

and