New Plugin: Mopidy Raspberry GPIO

I know Mopidy-GPIOTTS exists, but we wanted a cleaner, more flexible plugin for supplying GPIO input to Mopidy. Instead, I’ve created this mess- https://github.com/pimoroni/mopidy-raspberry-gpio

I’m interested in any feedback, but I’d like to also ask a question of Mopidy devs- is it possible to have a config option defined in the “schema” but not be required in mopidy.conf?

I ask because I’d like the user to be able to configure the plugin using lines like bcm5 = play_pause,active_low,30, but don’t want to have an empty line for every single GPIO pin to avoid config warnings.

Yes. In the schema definition set optional=True. mopidy.config — Config API — Mopidy 3.4.2 documentation

@kingosticks as near as I can tell optional=True only makes the existence of a value optional, and doesn’t allow the user to exclude that config value from mopidy.conf altogether. This ran counter to my expectations, but a glance through the code revealed why it might be the case. The optional=True value only affects the return value from a schema type and doesn’t affect whether that config value can be optionally omitted.

The parsing happens here:

Effectively this does two things:

  1. Checks through every value in the config file and raises errors for any that do not match configuraiton values that Mopidy (or its plugins) know about. It will also try to match mistyped config values to existing ones- neat!

  2. Checks through every config value that Mopidy expects and - if it has not been found in step 1 - produces a `‘config key not found’ warning. It appears that any warnings of this type cause the extension to be disabled- presumably because there’s no internal case for handling default config values.

In my case I have code like the following:

    def get_config_schema(self):
        schema = super(Extension, self).get_config_schema()
        for pin in range(28):
            schema["bcm{:d}".format(pin)] = PinConfig()
        return schema

This effectively tells the config parser to allow options bcm0 through bcm27 and treat their values as a PinConfig type. The upshot of this is that my mopidy.config entries have to look like this so it doesn’t break:

[raspberry-gpio]
enabled = true
bcm0 =
bcm1 =
bcm2 =
bcm3 =
bcm4 = play_pause,active_low,30
bcm5 = volume_up,active_low,30
bcm6 = volume_down,active_low,30
bcm7 =
bcm8 =
bcm9 =
bcm10 =
bcm11 =
bcm12 =
bcm13 =
bcm14 =
bcm15 =
bcm16 =
bcm17 =
bcm18 =
bcm19 =
bcm20 =
bcm21 =
bcm22 =
bcm23 =
bcm24 =
bcm25 =
bcm26 =
bcm27 =

I might be missing something, but I’d usually expect known-good-defaults to be baked-in to the plugin using config.get(key, default) so that settings can be omitted from the config file unless they’re strictly necessary.

Step 2. might be expanded to check if the type is optional and allow the ommission of the key from mopidy.conf:

for key in self.keys():
    if isinstance(self[key], types.Deprecated):
        result.pop(key, None)
    elif key not in result and key not in errors and not is_optional(self[key]):
        result[key] = None
        errors[key] = 'config key not found.'

Where is_optional, by whatever mechanism deemed sensible, returns True is this key is of an optional type.

If the fields are defined in ext.conf and made optional the user does not have to set them in their mopidy.conf. Known defaults should be baked into ext.conf.

Ah this appears to be one of those cases where I’ve been too “smart” for my own good and read the code instead of the documentation! I’ll give it a try, thanks!

Hello! I’m trying to set up this gpio service you’ve created. I follow your instructions, installing the service, and editing the mopidy config file. But that’s where the problem starts.

At boot I get an error, something like “mopidy: error: 14: invalid line [raspberry-gpio]”

I noticed in the mopidy config file, I’m using musicbox v0.7RC7, it says not to use dashes because it’ll leak the startup script, which appears to be what’s happening to me.

I noticed in init.py that the name is called out as raspberry-gpio, so I’m hoping to change it there to raspberrygpio. Am I on the right track?

Any help would be appreciated, thanks

That extension isn’t compatible with pimusicbox as it requires Mopidy 2.2 and the version of Mopidy in pimusicbox is much older than that. Sorry.

Thank you for the quick reply! At least I know I’m not crazy then.

I wonder if updating to 2.2 would break things?
Or I may have to try one of those scripts that watch the gpio pins and call moc commands.

Yes it will break things. They can be fixed if you want to get into it all but I can’t help with that.

No no that’s fine, I appreciate the responses, it’s helped me get unstuck and move on.

I tried the upgrade before seeing your response, it definitely broke things. I downgraded and it fixed the parts I care about, I didn’t check everything and I don’t care to haha.

I got gpio pins working by modifying this code:
https://pastebin.com/NFNpvjEH

And running it at startup. Thanks again!