[PLUGIN] SerialAmpController - Control Amplifiers with Serial Interface from Volumio (e.g. ROTEL A12/A11/A14)

Works fine with 2.6.2. Thanks for this.

I cannot seem to find the plugin. I have enabled plugin test mode, but it seems missing from plugin manager. What am I doing wrong?

What is your device? Ɖpi, x86… Other ?

X86-64. Sorry, I wasn’t aware that information matters.

The plugin is only for RPI… Sorry

Oh. What a pity.

Hi all,

I was asked to synchronize the Buster and Bookworm versions. I did so in new version 2.7.0
I tried it on both my test systems and it seems to be working.
Would be nice, if you can upgrade to version 2.7.0 and give me short feedback if nothing breaks for you. I will then create the pull request for official version release.

Thanks
Tom

1 Like

Hi gellert,
sorry, I was travelling last week and could not come back yet. There is quite a big chance that the plugin is also running on other platforms - but since I am not running any other hardware beside my RPi players I could not test it and did not release it.
I can generate a beta version with the additional platform enabled or (if you are not afraid of Linux) you can log onto your system yourself via ssh and add x86-64 to the plugins package.json file.
I added amd64 as architecture in version 2.7.1 of the plugin - you can install it from the beta-channel. If you can confirm it works on x86, I can include it in the upcoming pull-request.

Would not see, why it shouldn’t - serialport.io supports x86 and net is included with node - I am not using any RPi specific hardware/plugins in this plugin.

T0MR0,

thank you very much! I can’t seem to find the plugin. However, I downloaded it from github.
I have to add support for my legacy Denon receiver before I can tell whether it works or not. To that end I want to use minicom, but i cannot get it working for the life of me. Do you have any pointers? If in one shell I type
cat /dev/ttyUSB0
and monitor the output, and in another shell I type
echo -e "PW?\r" > /dev/ttyUSB0
(query power status) I am getting a reply. But not through minicom? According to the amplifier docs, parameters should be 9600 baud, 8N1. I am not a young person anymore, so I have dealt with my fair share of serial connections. But this problem I cannot solve?!

Hi,
the modified plugin is in the Beta channel, you need to activate that under http://volumio.local/dev and set Plugin Test Mode to true.

Why do you want to use minicom at all? If it works with cat and echo, you are already good to go - minicom problem might be a matter of access to the port - it is not shipped with Volumio, so you probably installed it later, right? But you do not need to have it running.

If echo does the job, the plugin will, too.
If you can fill in the commands into the ampCommands.json file, it should already work - more or less. If it doesn’t, the logging should provide hints.

Instead of taking it from Github, I recommend installing from the Beta Channel and then log into Volumio via ssh and work with the ampCommands.json file in /data/configuration/system_hardware/serialampcontroller/. It will only get loaded at Plugin start, though.

I am not sure the plugin is able to communicate with the receiver.

This is part of the log:

info: CoreCommandRouter::volumioGetState
info: CorePlayQueue::getTrack 0
info: CALLMETHOD: system_controller serialampcontroller updateAmpSettings [object Object]
info: CoreCommandRouter::executeOnPlugin: serialampcontroller , updateAmpSettings
info: [SERIALAMPCONTROLLER] updateAmpSettings: Saving Amplifier Settings:{"amp_type":{"value":1,"label":"Denon - AVC-A11XV"},"volumio_input":{"value":4,"label":"DVD"},"min_volume":0,"max_volume":98,"startup_volume":55,"volume_steps":1,"map_to_100":false,"pause_when_muted":false,"pause_when_input_changed":false,"switch_input_at_play":false,"start_at_powerup":false}
info: [SERIALAMPCONTROLLER] setActiveAmp: {"vendor":"Denon","model":"AVC-A11XV","baudRate":9600,"parity":"none","dataBits":8,"stopBits":1,"rtscts":false,"xon":false,"xoff":false,"xany":false,"sources":["PHONO","CD","TUNER","DVD","VDP","TV","DBS","VCR-1","VCR-2","VCR-3","V.AUX","CDR/TAPE"],"sourceCmd":["SIPHONO","SICD","SITUNER","SIDVD","SIVDP","SITV","SIDBS","SIVCR-1","SIVCR-2","SIVCR-3","SIV.AUX","SICDR/TAPE"],"sourceRespPostfix":["SIPHONO","SICD","SITUNER","SIDVD","SIVDP","SITV","SIDBS","SIVCR-1","SIVCR-2","SIVCR-3","SIV.AUX","SICDR/TAPE"],"delimiter":"\r","commands":{"powerOn":"PWON","volUp":"MVUP","volDown":"MVDOWN","volValue":"MV##","muteOn":"MUON","muteOff":"MUOFF"},"responses":[{"rx":"PWON","cmd":["respPowerOn"]},{"rx":"PWSTANDBY","cmd":["respPowerOff"]},{"rx":"volume=([0-9]{2})","cmd":["respVolume"]},{"rx":"MUON","cmd":["respMuteOn"]},{"rx":"MUOFF","cmd":["respMuteOff"]},{"rx":"SI([a-z_12]*)","cmd":["respSource"]}],"statusRequests":{"reqPower":"PW?","reqSource":"SI?","reqVolume":"MV?","reqMute":"MU?"}}
info: [SERIALAMPCONTROLLER] setActiveAmp: can send these responses: respPowerOn,respPowerOff,respVolume,respMuteOn,respMuteOff,respSource.
info: CoreCommandRouter::getUIConfigOnPlugin
info: [SERIALAMPCONTROLLER] openSerialPort: connect to /dev/ttyUSB0 configured with: {"autoOpen":false,"lock":true,"baudRate":9600,"dataBits":8,"stopBits":1,"parity":"none","rtscts":false,"xon":false,"xoff":false,"xany":false}
info: [SERIALAMPCONTROLLER] openSerialPort: Connection established.
error: [SERIALAMPCONTROLLER] openSerialPort: Now trying to open port
info: [SERIALAMPCONTROLLER] alsavolume: Set volume "55"
info: [SERIALAMPCONTROLLER] alsavolume: set volume to integer value.
info: [SERIALAMPCONTROLLER] sendCommand: send volValue,55
info: [SERIALAMPCONTROLLER] sendCommand: now sending cmdString: MV55
info: [SERIALAMPCONTROLLER] openSerialPort: Port is now closed.
info: [SERIALAMPCONTROLLER] openSerialPort: closed serial Port
info: [SERIALAMPCONTROLLER] openSerialPort: Port is now open. Connecting Parser with delimiter:
info: [SERIALAMPCONTROLLER] getAmpStatus: sending status requests to Amp
(node:981) UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received undefined
    at new NodeError (internal/errors.js:322:7)
    at SerialPort.Writable.write (internal/streams/writable.js:285:13)
    at SerialPort.write (/data/plugins/system_controller/serialampcontroller/node_modules/@serialport/stream/lib/index.js:307:21)
    at serialampcontroller.sendStatusRequest (/data/plugins/system_controller/serialampcontroller/index.js:621:19)
    at serialampcontroller.getAmpStatus (/data/plugins/system_controller/serialampcontroller/index.js:113:14)
    at SerialPort. (/data/plugins/system_controller/serialampcontroller/index.js:370:26)
    at SerialPort.emit (events.js:412:35)
    at binding.open.then.opening (/data/plugins/system_controller/serialampcontroller/node_modules/@serialport/stream/lib/index.js:234:12)
(node:981) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 5)
info: CoreCommandRouter::volumioGetState

I have added this to ampCommands.json:

{
    "amps": [
        {
            "vendor": "Denon",
            "model":"AVC-A11XV",
            "baudRate": 9600,
            "parity": "none",
            "dataBits": 8,
            "stopBits": 1,
            "rtscts": false,
            "xon": false,
            "xoff": false,
            "xany": false,
            "sources":  ["PHONO","CD","TUNER","DVD","VDP","TV","DBS","VCR-1","VCR-2","VCR-3","V.AUX","CDR/TAPE"],
            "sourceCmd": ["SIPHONO","SICD","SITUNER","SIDVD","SIVDP","SITV","SIDBS","SIVCR-1","SIVCR-2","SIVCR-3","SIV.AUX","SICDR/TAPE"],
            "sourceRespPostfix": ["SIPHONO","SICD","SITUNER","SIDVD","SIVDP","SITV","SIDBS","SIVCR-1","SIVCR-2","SIVCR-3","SIV.AUX","SICDR/TAPE"],
            "delimiter": "\r",
            "commands": {
                    "powerOn": "PWON",
                    "volUp":  "MVUP",
                    "volDown": "MVDOWN",
                    "volValue": "MV##",
                    "muteOn": "MUON",
                    "muteOff": "MUOFF"
                },
           "responses": [
                {"rx": "PWON", "cmd": ["respPowerOn"]},
                {"rx": "PWSTANDBY", "cmd": ["respPowerOff"]},
                {"rx": "volume=([0-9]{2})", "cmd": ["respVolume"]},
                {"rx": "MUON", "cmd": ["respMuteOn"]},
                {"rx": "MUOFF", "cmd": ["respMuteOff"]},
                {"rx": "SI([a-z_12]*)", "cmd": ["respSource"]}
            ],
            "statusRequests": {
                    "reqPower":"PW?",
                    "reqSource":"SI?",
                    "reqVolume":"MV?",
                    "reqMute":"MU?"
                }
        },
        {
            "vendor": "Rotel",
            "model":"A12",
------------------ snip ----------

Hi Tom,
I’ve updated the plugin to version 2.7.1 on both systems, Buster and Bookworm, on the Raspberry Pi 4. After the update, I haven’t noticed any issues — everything works as before with my Rotel RA1592 amplifier over the IP protocol. In 2–3 weeks, I’ll be able to test it on my relative’s Cambridge CXA81 amplifier over the serial protocol when I visit them.
Thank you, Tom, for all your great work!

1 Like

Hi,
the protocol shows, that basically it is starting to work, but it seems all messed up.
Did you download the Plugin from the Beta-Channel now? Which version are you on?
I do not want to waste time hunting ghosts - there is a promise rejection warning in the log file - that hints to an old version, where I did have a lot of inconsistencies.
Please try to use the latest version from the plugin store.

Hi T0MR0,

I understand. However, I can’t find it. Have you released it for Buster as well?

I gave up trying to find it in the plugin store, and downloaded it from GitHub - 7h0mas-R/volumio-plugins-sources: Volumio plugins source code for Volumio 3 serialampcontroller_dev. I am pretty certain I have enabled plugin test mode, but not main test mode. I am rather confident it is not an oversight of mine.

I am not good at coding, so many things in ampCommands.json I do not understand. One problem is this: when i send a command to turn on the amplifier, it replies with not only that it is turned on, but also which zones are turned on. How do I make the plugin ignore these additional messages?

Hi,
as far as I remember, the string-matching is implemented with Regular Expressions.
In this line
let match = data.match(new RegExp(response.rx,'i'));
the plugin tries to match data (the response from the amp) against a regular expression that is inside the ampCommands.json.
If you can find a regular expression, that matches the response of your amp and ignores the info about the zones, you need to put that RegEx into the configuration file.
Line 113 in the ampCommands.json contains an example of a RegEx, that matches every message starting with volume= followed by exactly 2 digits - in this special case, it additionally returns the two digits, indicated by the ().
There are tons of pages over the web, which explain RegEx - I personally used regular-expressions.info to learn about it.

The beta versions of plugins can be found when you press the ā€œDetailsā€ button (see screenshot). For both Buster and Bookworm the latest version is 2.7.1 (see screenshot).

Good luck.