[PLUGIN] RotaryEncoder II

Good catch, I get confused with all the B words. Thank you for calling me an idiot because I referred to the wrong Debian distribution name, that’s super helpful. So far this forum has been a master class in how not to be welcoming by moderators. You’ve gotten really good at triggering negative responses. Makes me feel all warm and fuzzy about the money I’ve given Volumio.

Stupid me, I was thinking that I was help full.
I will stop my support, since you speak in plural.

You mean like calling me a freeloader? :rofl: Yeah, thanks for that.

Here’s a report I was able to gather:

Starting Live Log...
process exited with code nullinfo: CoreCommandRouter::executeOnPlugin: volumiodiscovery , getThisDevice
info: Discovery: Getting this device information
info: CoreCommandRouter::volumioGetState
info: CorePlayQueue::getTrack 0
info: CoreCommandRouter::executeOnPlugin: network , getCachedIPAddresses
info: CALLMETHOD: system_controller system enableLiveLog true
info: CoreCommandRouter::executeOnPlugin: system , enableLiveLog
info: Launching a new LiveLog session
info: Killing previous LiveLog session
info: Live Log process terminated: null
info: CoreCommandRouter::executeOnPlugin: my_volumio , getMyVolumioStatus
info: CoreCommandRouter::executeOnPlugin: my_volumio , getMyVolumioToken
info: CoreCommandRouter::executeOnPlugin: system , getPrivacySettings
info: CALLMETHOD: system_controller my_volumio retreiveBackendEventStates undefined
info: CoreCommandRouter::executeOnPlugin: my_volumio , retreiveBackendEventStates
info: Received Get System Version
info: CoreCommandRouter::executeOnPlugin: system , getSystemVersion
info: Received Get System Info
info: CoreCommandRouter::executeOnPlugin: system , getSystemInfo
info: CoreCommandRouter::executeOnPlugin: volumiodiscovery , getThisDevice
info: Discovery: Getting this device information
info: CoreCommandRouter::volumioGetState
info: CorePlayQueue::getTrack 0
info: CoreCommandRouter::executeOnPlugin: network , getCachedIPAddresses
info: [ROTARYENCODER2] onStop: Stopping Plugin.
info: [ROTARYENCODER2] deactivateRotaries: 1,2,3
info: [ROTARYENCODER2] deactivateRotaries: 2,3
info: [ROTARYENCODER2] deactivateRotaries: 3
info: [ROTARYENCODER2] deactivateRotaries:
info: [ROTARYENCODER2] deactivateRotaries: end of recursion.
info: [ROTARYENCODER2] detachListener: [object Object]
error: [ROTARYENCODER2] detachListener: could not kill handler process [object Object]
info: [ROTARYENCODER2] onStop: Stopping Plugin.
info: [ROTARYENCODER2] deactivateRotaries: 1,2,3
info: [ROTARYENCODER2] deactivateRotaries: 2,3
info: [ROTARYENCODER2] deactivateRotaries: 3
info: [ROTARYENCODER2] deactivateRotaries:
info: [ROTARYENCODER2] deactivateRotaries: end of recursion.
info: [ROTARYENCODER2] detachListener: [object Object]
error: [ROTARYENCODER2] detachListener: could not kill handler process [object Object]
info: CoreCommandRouter::getUIConfigOnPlugin
info: [ROTARYENCODER2] getUIConfig: starting:
info: [ROTARYENCODER2] getUIConfig: i18nStrings{"ROTARYENCODER2":{"CONFIG":"Rotary Encoder II Plugin Configuration","SAVE":"Save","ENCODER0":"Rotary Encoder 1","D_ENCODER0":"Settings for the first rotary encoder.","ENCODER1":"Rotary Encoder 2","D_ENCODER1":"Settings for the second rotary encoder.","ENCODER2":"Rotary Encoder 3","D_ENCODER2":"Settings for the third rotary encoder.","ROTARYTYPE":"Periods per tick","D_ROTARYTYPE":"Periods per tick (Full: A and B full period, half: A and B half period, quarter: A or B half period","FULL":"Full-period mode","HALF":"Half-period mode","QUARTER":"Quarter-period mode","PINA":"Pin A GPIO","D_PINA":"GPIO pin that is connected to the first pin of the rotary.","PINB":"Pin B GPIO","D_PINB":"GPIO pin that is connected to the second pin of the rotary.","DIALACTION":"Dial Action","D_DIALACTION":"Action to be triggered by turning the rotary encocer. Option 'Emit Websocket Message' can be used to control other plugins using the Volumio Websock calls between Plugins. (see https://volumio.github.io/docs/API/WebSocket_APIs.html section 'CallMethod on Plugin' for details)","DOTS":"...","VOLUME":"Volume","SKIP":"Prev/Next title","SEEK":"Seek in title","SCROLL":"Scroll","EMIT":"Emit Websocket Message","SOCKCMDCCW":"Command CCW","SOCKDATACCW":"Data CCW","SOCKCMDCW":"Command CW","SOCKDATACW":"Data CW","SOCKCMD":"Command","SOCKDATA":"Data","D_SOCKCMD":"Command to send via Websocket","D_SOCKDATA":"Data to include with the Websocket Command","PINPUSH":"Pushbutton GPIO","D_PINPUSH":"GPIO pin that is connected to the pushbutton pin of the rotary. 0 or empty to disable.","PINPUSHDEBOUNCE":"Debounce-time (ms)","D_PINPUSHDEBOUNCE":"Debounce time for the button. If the button has hardware-debouncing, set to 0.","PUSHSTATE":"Button logic-level active low","D_PUSHSTATE":"Activate this, if pressing the button pulls the logic level on the GPIO low.","PINPUSHDELAY":"Delay for a long button press (ms)","D_PINPUSHDEDELAY":"Minimum duration of a button press, that will trigger the long push action in ms","PINDOUBLEPUSHDELAY":"Maximum interval for double press (ms)","D_PINDOUBLEPUSHDEDELAY":"Time interval in ms, within which a double press has to be detected.","PUSHACTION":"Short Press Action","D_PUSHACTION":"Action that gets triggered, when pushbutton is pressed briefly.","LONGPUSHACTION":"Long Press Action","D_LONGPUSHACTION":"Action that gets triggered, when pushbutton is pressed longer.","DOUBLEPUSHACTION":"Double Press Action","D_DOUBLEPUSHACTION":"Action that gets triggered, when pushbutton is pressed twice quickly.","SET_DEBUG":"Debug Settings","D_SET_DEBUG":"Settings for functional debugging.","PLAY":"Play","PAUSE":"Pause","PLAYPAUSE":"Play/Pause toggle","STOP":"Stop","REPEAT":"Repeat","RANDOM":"Random","CLEARQUEUE":"Clear Queue","MUTE":"Mute","UNMUTE":"Unmute","TOGGLEMUTE":"Toggle Mute","SHUTDOWN":"System Shutdown","REBOOT":"System Reboot","RESTARTAPP":"Restart Application","DUMPLOG":"Dump logfile","LOGGING":"Logging","D_LOGGING":"Switch the output of log messages on or off. Error messages are always logged.","TOAST_START_SUCCESS":"Plugin successfully started.","TOAST_STOP_SUCCESS":"Plugin successfully stopped.","TOAST_START_FAIL":"Plugin failed to start.","TOAST_STOP_FAIL":"Plugin failed to stop.","TOAST_GPIO_BLOCKED":"GPIO Pin unavailable","TOAST_MSG_OVERLAY_BLOCKING":"Blocked by another overlay.","TOAST_SAVE_SUCCESS":"Successfully saved","TOAST_MSG_SAVE":"Settings for Encoder ","TOAST_DEBUG_SAVE":"Debug Settings","TOAST_SAVE_FAIL":"Save failed","TOAST_WRONG_PARAMETER":"Error in parameters","TOAST_NEEDS_INTEGER":"GPIO Pins must be Integers.","TOAST_PINS_DIFFERENT":"GPIO Pins for A/B/Button must be different.","TOAST_PINS_BLOCKED":"Pins already used in another Encoder.","TOAST_NO_TYPE":"Please select 'Periods per tick'!"}}
info: [ROTARYENCODER2] getUIConfig: i18nStringsDefaults{"ROTARYENCODER2":{"CONFIG":"Rotary Encoder II Plugin Configuration","SAVE":"Save","ENCODER0":"Rotary Encoder 1","D_ENCODER0":"Settings for the first rotary encoder.","ENCODER1":"Rotary Encoder 2","D_ENCODER1":"Settings for the second rotary encoder.","ENCODER2":"Rotary Encoder 3","D_ENCODER2":"Settings for the third rotary encoder.","ROTARYTYPE":"Periods per tick","D_ROTARYTYPE":"Periods per tick (Full: A and B full period, half: A and B half period, quarter: A or B half period","FULL":"Full-period mode","HALF":"Half-period mode","QUARTER":"Quarter-period mode","PINA":"Pin A GPIO","D_PINA":"GPIO pin that is connected to the first pin of the rotary.","PINB":"Pin B GPIO","D_PINB":"GPIO pin that is connected to the second pin of the rotary.","DIALACTION":"Dial Action","D_DIALACTION":"Action to be triggered by turning the rotary encocer. Option 'Emit Websocket Message' can be used to control other plugins using the Volumio Websock calls between Plugins. (see https://volumio.github.io/docs/API/WebSocket_APIs.html section 'CallMethod on Plugin' for details)","DOTS":"...","VOLUME":"Volume","SKIP":"Prev/Next title","SEEK":"Seek in title","SCROLL":"Scroll","EMIT":"Emit Websocket Message","SOCKCMDCCW":"Command CCW","SOCKDATACCW":"Data CCW","SOCKCMDCW":"Command CW","SOCKDATACW":"Data CW","SOCKCMD":"Command","SOCKDATA":"Data","D_SOCKCMD":"Command to send via Websocket","D_SOCKDATA":"Data to include with the Websocket Command","PINPUSH":"Pushbutton GPIO","D_PINPUSH":"GPIO pin that is connected to the pushbutton pin of the rotary. 0 or empty to disable.","PINPUSHDEBOUNCE":"Debounce-time (ms)","D_PINPUSHDEBOUNCE":"Debounce time for the button. If the button has hardware-debouncing, set to 0.","PUSHSTATE":"Button logic-level active low","D_PUSHSTATE":"Activate this, if pressing the button pulls the logic level on the GPIO low.","PINPUSHDELAY":"Delay for a long button press (ms)","D_PINPUSHDEDELAY":"Minimum duration of a button press, that will trigger the long push action in ms","PINDOUBLEPUSHDELAY":"Maximum interval for double press (ms)","D_PINDOUBLEPUSHDEDELAY":"Time interval in ms, within which a double press has to be detected.","PUSHACTION":"Short Press Action","D_PUSHACTION":"Action that gets triggered, when pushbutton is pressed briefly.","LONGPUSHACTION":"Long Press Action","D_LONGPUSHACTION":"Action that gets triggered, when pushbutton is pressed longer.","DOUBLEPUSHACTION":"Double Press Action","D_DOUBLEPUSHACTION":"Action that gets triggered, when pushbutton is pressed twice quickly.","SET_DEBUG":"Debug Settings","D_SET_DEBUG":"Settings for functional debugging.","PLAY":"Play","PAUSE":"Pause","PLAYPAUSE":"Play/Pause toggle","STOP":"Stop","REPEAT":"Repeat","RANDOM":"Random","CLEARQUEUE":"Clear Queue","MUTE":"Mute","UNMUTE":"Unmute","TOGGLEMUTE":"Toggle Mute","SHUTDOWN":"System Shutdown","REBOOT":"System Reboot","RESTARTAPP":"Restart Application","DUMPLOG":"Dump logfile","LOGGING":"Logging","D_LOGGING":"Switch the output of log messages on or off. Error messages are always logged.","TOAST_START_SUCCESS":"Plugin successfully started.","TOAST_STOP_SUCCESS":"Plugin successfully stopped.","TOAST_START_FAIL":"Plugin failed to start.","TOAST_STOP_FAIL":"Plugin failed to stop.","TOAST_GPIO_BLOCKED":"GPIO Pin unavailable","TOAST_MSG_OVERLAY_BLOCKING":"Blocked by another overlay.","TOAST_SAVE_SUCCESS":"Successfully saved","TOAST_MSG_SAVE":"Settings for Encoder ","TOAST_DEBUG_SAVE":"Debug Settings","TOAST_SAVE_FAIL":"Save failed","TOAST_WRONG_PARAMETER":"Error in parameters","TOAST_NEEDS_INTEGER":"GPIO Pins must be Integers.","TOAST_PINS_DIFFERENT":"GPIO Pins for A/B/Button must be different.","TOAST_PINS_BLOCKED":"Pins already used in another Encoder.","TOAST_NO_TYPE":"Please select 'Periods per tick'!"}}
info: [ROTARYENCODER2] getUIConfig: language code: en dir: /data/plugins/system_hardware/rotaryencoder2
info: [ROTARYENCODER2] getI18nString("VOLUME"):Volume
info: [ROTARYENCODER2] getI18nString("SHUTDOWN"):System Shutdown
info: [ROTARYENCODER2] getI18nString("SHUTDOWN"):System Shutdown
info: [ROTARYENCODER2] getI18nString("SHUTDOWN"):System Shutdown
info: [ROTARYENCODER2] getI18nString("DOTS"):...
info: [ROTARYENCODER2] getI18nString("DOTS"):...
info: [ROTARYENCODER2] getI18nString("DOTS"):...
info: [ROTARYENCODER2] getI18nString("DOTS"):...
info: [ROTARYENCODER2] getI18nString("DOTS"):...
info: [ROTARYENCODER2] getI18nString("DOTS"):...
info: [ROTARYENCODER2] getI18nString("DOTS"):...
info: [ROTARYENCODER2] getI18nString("DOTS"):...
info: CALLMETHOD: system_hardware rotaryencoder2 updateEncoder [object Object]
info: CoreCommandRouter::executeOnPlugin: rotaryencoder2 , updateEncoder
info: [ROTARYENCODER2] updateEncoder: Rotary1 with:{"enabled0":true,"rotaryType0":{"value":1,"label":"1/1"},"pinA0":23,"pinB0":24,"dialAction0":{"value":1,"label":"Volume"},"socketCmdCCW0":"","socketDataCCW0":"","socketCmdCW0":"","socketDataCW0":"","pinPush0":17,"pinPushDebounce0":0,"pushState0":true,"pushAction0":{"value":11,"label":"System Shutdown"},"socketCmdPush0":"","socketDataPush0":"","longPushAction0":{"value":11,"label":"System Shutdown"},"socketCmdLongPush0":"","socketDataLongPush0":"","delayLongPush0":"1500","doublePushAction0":{"value":11,"label":"System Shutdown"},"socketCmdDoublePush0":"","socketDataDoublePush0":"","delayDoublePush0":"700"}
info: [ROTARYENCODER2] sanityCheckSettings: Rotary1 for:{"enabled0":true,"rotaryType0":{"value":1,"label":"1/1"},"pinA0":23,"pinB0":24,"dialAction0":{"value":1,"label":"Volume"},"socketCmdCCW0":"","socketDataCCW0":"","socketCmdCW0":"","socketDataCW0":"","pinPush0":17,"pinPushDebounce0":0,"pushState0":true,"pushAction0":{"value":11,"label":"System Shutdown"},"socketCmdPush0":"","socketDataPush0":"","longPushAction0":{"value":11,"label":"System Shutdown"},"socketCmdLongPush0":"","socketDataLongPush0":"","delayLongPush0":"1500","doublePushAction0":{"value":11,"label":"System Shutdown"},"socketCmdDoublePush0":"","socketDataDoublePush0":"","delayDoublePush0":"700"}
info: [ROTARYENCODER2] deactivateRotaries: 1,2,3
info: [ROTARYENCODER2] deactivateRotaries: 2,3
info: [ROTARYENCODER2] deactivateRotaries: 3
info: [ROTARYENCODER2] deactivateRotaries:
info: [ROTARYENCODER2] deactivateRotaries: end of recursion.
info: [ROTARYENCODER2] detachListener: [object Object]
error: [ROTARYENCODER2] detachListener: could not kill handler process [object Object]
info: CoreCommandRouter::volumioGetState
info: CorePlayQueue::getTrack 0

@T0MR0

Just tested the plugin V1.0.20 on a rPi5, but it’s working as expected.

image

---------------------------------------------------
STATUS 0:
info: VolumeController::SetAlsaVolume+
info: CoreStateMachine::pushState
info: CoreCommandRouter::executeOnPlugin: volumiodiscovery , saveDeviceInfo
info: CoreCommandRouter::volumioPushState
info: MRS: Pushing multiroomSync output update for this device
info: MRS: Pushing multiroomSync output
SPOTIFY: RECEIVED VOLUMIO VOLUME 64
SPOTIFY: SPOTIFY VOLUME 62
SPOTIFY: VOLUMIO VOLUME 64
SPOTIFY: DELTA VOLUME ENOUGH: true
info: Setting Spotify Volume from Volumio: 64
'SoftMaster',0
info: VolumeController::SetAlsaVolume+
info: CoreStateMachine::pushState
info: CoreCommandRouter::executeOnPlugin: volumiodiscovery , saveDeviceInfo
info: CoreCommandRouter::volumioPushState
info: MRS: Pushing multiroomSync output update for this device
info: MRS: Pushing multiroomSync output
SPOTIFY: RECEIVED VOLUMIO VOLUME 65
SPOTIFY: SPOTIFY VOLUME 64
SPOTIFY: VOLUMIO VOLUME 65
SPOTIFY: DELTA VOLUME ENOUGH: false
'SoftMaster',0
info: VolumeController::SetAlsaVolume+
info: CoreStateMachine::pushState
info: CoreCommandRouter::executeOnPlugin: volumiodiscovery , saveDeviceInfo
info: CoreCommandRouter::volumioPushState
info: MRS: Pushing multiroomSync output update for this device
info: MRS: Pushing multiroomSync output
SPOTIFY: RECEIVED VOLUMIO VOLUME 66
SPOTIFY: SPOTIFY VOLUME 64
SPOTIFY: VOLUMIO VOLUME 66
SPOTIFY: DELTA VOLUME ENOUGH: true
info: Setting Spotify Volume from Volumio: 66
'SoftMaster',0
---------------------------------------------------
STATUS 0:
info: VolumeController::SetAlsaVolume+
info: CoreStateMachine::pushState
info: CoreCommandRouter::executeOnPlugin: volumiodiscovery , saveDeviceInfo
info: CoreCommandRouter::volumioPushState
info: MRS: Pushing multiroomSync output update for this device
info: MRS: Pushing multiroomSync output
SPOTIFY: RECEIVED VOLUMIO VOLUME 67
SPOTIFY: SPOTIFY VOLUME 66
SPOTIFY: VOLUMIO VOLUME 67
SPOTIFY: DELTA VOLUME ENOUGH: false
'SoftMaster',0
info: VolumeController::SetAlsaVolume+
info: CoreStateMachine::pushState
info: CoreCommandRouter::executeOnPlugin: volumiodiscovery , saveDeviceInfo
info: CoreCommandRouter::volumioPushState
info: MRS: Pushing multiroomSync output update for this device
info: MRS: Pushing multiroomSync output
SPOTIFY: RECEIVED VOLUMIO VOLUME 68
SPOTIFY: SPOTIFY VOLUME 66
SPOTIFY: VOLUMIO VOLUME 68
SPOTIFY: DELTA VOLUME ENOUGH: true
info: Setting Spotify Volume from Volumio: 68
'SoftMaster',0
---------------------------------------------------

I had not yet tried 1.0.20. I just enabled the Plugins Test Mode, but because I can’t uninstall the 1.0.15 plugin (all attempts to do so the usual ways fail), I’ll need to remove it manually and start over

Wait till tomorrow;

If no patience, run: (tested on a clean install)
sudo apt-get update && sudo apt-get install gpiod python3-libgpiod

Thank you, I’ll wait for the new build. I did install gpiod and python3-libgpiod but those things did not seem to resolve the issue I’m having with this plugin, even after I updated to 1.0.20. The specific thing I’m seeing that might be the issue is:

export_store: invalid GPIO 17

(GPIO 17 is the pin I’m trying to assign to a button)

Also I still can’t uninstall the plugin using the Uninstall button. I have to remove the directory from the file system and the entry from the json file manually to get it deleted

1 Like

I think it would be good, to promote v 1.0.20 to stable - 1.0.15 still had some issues and there have been no reports about 1.0.20 not working.
There seems to be no documented way to trigger promotion…

I checked and no PR with 1.0.20 code was sent on github…; It is required to release…

Sorry, thought I had created one already. Obviously not - so I did some more improvements of how bad settings are handled, tested them and created a pull for 1.0.22 now

1 Like

New to Volumio.
I ordered an encoder off Ebay and the volume worked but not the button. (It was intermittent).
Using GPIO 23,24 and 25.
I have more experience programming Arduino/ESP32 devices and in that code, you can set a pull up enabled in the code. (You normally need to code in debouncing).
It was clear my issue was lack of pull up resistor.

The encoder board I used had pull up resistors for the encoder but R1 for the switch was not installed.

I have a few spare surface component and soldered in 10k resistor in the R1 space, and it now works fine.

I found a note that says: When a Pi is first powered up, the first eight GPIOs have pull-ups enabled, and the rest have pull-downs enabled. After it has finished booting, you can change that if you wish, in your software.

Is it best to assume that the internal GPIO pull up/down are disabled and we should rely on external pull up resistors?

With a rotary encoder you always need to use resistors. if not the rotary will behave irratic.

I spent quite some time to put recommendations for encoder hardware into the documentation.

I had not previously found a working link to GitHub. Thanks - it is helpful.

I am using one of the types recommended - KY-040, however it is a basic encoder, a minimalistic circuit.

Looking at the diagrams on GitHub I can see you used an external Pull up resistor for the switch.
There was a space for the resistor but it was not fitted and fortunately I had a surface one to use.
With the resistor now in place it works great - it’s a very useful plugin.

Thanks again.

2 Likes

Here’s a working drawing, with the use of the plugin:

i tried config plugin on volumio 3 but it dont accept. It show error parametter. please support me

Hi, without any information, it is hard to help you. Please scroll to the first post of this thread and follow the instructions, how to ask for support! Thank you!

1 Like

The plugin does not work on Volumio 3.703. The system responds that the plugin is outdated.