cbdevnet / midimonster

Multi-protocol control & translation software (ArtNet, MIDI, OSC, sACN, ...)
https://midimonster.net/
BSD 2-Clause "Simplified" License
490 stars 48 forks source link

Support for HTTP request API? #72

Open qu4nt4r opened 4 years ago

qu4nt4r commented 4 years ago

Hi there, I am using a variety of esp32´s with WLED for different purposes. Not only (but mainly) to control all the LED lights with a haptical UI, I am looking for options to control them with a (CC) USB-MIDI controller. Though I got MIDIMonster to work here via sACN/ArtNet, controls keep pretty limited without any additional software. A pretty direct and comprehensive control with all the WLED configurations is still possible due to simple HTTP requests, as many users are utilizing them for all the macros. But as the haptical interface options are (still) also pretty limited (support for only one button), it would be great to get a MIDI-WLED bridge somehow (not only for me, there are others looking for such an option, too). My coding skills are barely existing, so I cant say how complicated it is to reach this; or if its even already possible. Appreciate a more expertise-based estimation about this... Greets KeLvin

cbdevnet commented 4 years ago

Hi @123vollhorst, thanks for the suggestion!

You could probably sling together basic HTTP API control using the Lua backend and some creative programming, but I agree that having it implemented as a proper backend would be useful!

Is the linked API documentation the only one you'd want to control or would you see value in keeping it more generic/configurable (but probably a bit harder to get started), for example by allowing to configure a channel/URL mapping per instance?

I think there are also ESP8266 firmware projects that allow you to control these pixel strips using OpenPixelControl, which is already implemented as a backend in MIDIMonster, but I understand that you'd like to keep the macro capabilities

qu4nt4r commented 4 years ago

Thanks for the fast reply. I just can speak for myself here and my perspective is more UI/UX centric, but from my experience there could be some valuable ways to go:

Configuring dedicated URLs per instance would be one thing, as would be a hierarchical trees or grouping. That brings me to one thing of great value: MQTT. As I also spent some time within the whole "DIY smart home" domain/community, MQTT is a pretty widespread protocol. And my current research for an easy MIDI-to-HomeAssistant bridge showed up only need for this and some frickelfrackel approaches, but no simple solution. I would assume sth similar counts for other software like OpenHAB.

Using a generic MIDI controller for all kind of home-electronics at least for me feels unique and helpful in many manners. Though I havent thought it all through hardware wise, one could easily assemble a wireless MIDI interface if MIDIMonster would run on embedded systems (ESPs and/or other Arduino compatible stuff). Attaching a USB MIDI keyboard via an FTDI adapter to a MCU and powering it with a thin powerbank seems pretty straight forward (But even without it should work via rtpMIDI I think, letting run MM on another platform/homeserver).

Regarding a dedicated home-light-control-interface without going all the mqtt-way, I am a big fan of diyHUE, as I am getting all my milight bulbs to work with the also esp based milight-hub (Like many other projects it also embraces REST API and UDP). But commercial light remotes are imo all crap. Why must it always "beep" and why is there no tactile element on a device that you use when its dark? A generic and cheap MIDI controller (like mine) can/could handle this much better.... At least in theory.

A far cry as a last thought (sorry you asked ;): Its also more a Arduino thing I havent dived into yet, but building a hardware (MIDI) controller with all these actors (buttons, rotary encoders, mini joysticks/pads) is also in my mind. I started to design a virtual WLED/light interface (aka a browsable menu) that Id like to attach to LED lights assembled or build into a custom tactile remote cube. There for sure should be existing solutions, but mapping their actions to sth. that MIDIMonster can handle is at least a prospering thought for an interface designer. :)

Thanks for your effort and keep on doing what your´e doing 👍 KeLvin

PS: Du bist doch auch aus DE wie ich bemerkt habe. Wenn du möchtest kann ich dir gerne ein kleines (W)LED-Experimentier-Set zukommen lassen. Bei mir stapelt sich inzwischen alles in meiner kleinen Lichtwerkstatt, da packe ich gerne ein kleines DEV-Care-Set zusammen. ;)

cbdevnet commented 4 years ago

An MQTT backend would be a cool thing to do, I agree - would need to investigate how these things take their input so I can match that with the backend, but definitely doable!

Running MIDIMonster on embedded systems is possible for the more full-featured ones (say, anything that runs a basic Linux), but there is a lower ceiling as MM is pretty heavy on floating-point math, and most of the real-low end controllers don't have hardware assisted floating point operations, making them impractical for the approach the MIDIMonster takes for translation (mathematically).

The easiest way to do "wireless" I/O would probably be either IR remotes (via lirc and/or the evdev backend) or an ESP firmware that sends out control data via Wifi (OSC comes to mind as a protocol for this, something like that would probably be useful even outside MM).

Another possibility (that I have personally done, too) is to use a programmable Point-of-Sales keyboard (they're pretty cheap on eBay), connect that via USB to either a "real" computer or something like a Raspberry Pi / NanoPi and use the evdev backend to use the input as MM channels.

Thanks for your appreciation, it's encouragement from the community that makes developing open source tools fun for me :)

-- Beware, German below -- Hey cooles Angebot - klar gerne, das waere sehr cool! Dann kann ich gleich am "lebenden objekt" experimentieren ;) Kannst mir ja mal eine E-Mail an cbdev@midimonster.net schreiben ;)

phedders commented 3 years ago

I've been looking at writing an mqtt gateway in lua... got stuck with libraries and will probably get stuck with receiving because of the non-threading model. mqttylua library itself looks quite straightforward.

For now I have a lua script that uses os.execute("mqc...") where shell mqc is a wrapper for mosquitto_sub so I can do ..cc1 > mqtttoggle.cmnd/tasmota/power or ..cc1 > mqttonoff.cmnd/light/power

Toggle will send a toggle whenever value is 1 onoff will translate 1 to on and 0 to off

It works very well - so I can clean it up and submit as an example? But a native mqtt would be nice, and as yet I dont have mqtt ingress (ie I dont subscribe to anything)

cbdevnet commented 3 years ago

Hey @phedders,

very cool solution! Maybe you could create an article on the knowledgebase, as it seems that it requires a bit more setup effort :) https://github.com/control8r/midimonster-knowledge-base/tree/master/source/usecases

A native MQTT backend is on the list, but I'm currently a bit short on time I can allocate to the MIDIMonster :)

phedders commented 3 years ago

Yes I need to push a few more hacks up to you :)

I've actually now gone a slightly different tack for merging control of http and mqtt. Node-red.

Simply put NR is also amazing and through the node-red-control-osc module I can use midimonster as a device processor and gateway to NR - do the processing and control I need in NR merging control from a web dashboard, mqtt signals and whatever else. Very happy with it.

[osc nodered] bind = 17881 destination = 10.88.8.4 17880 /mini/fader = f 0.0 1.0 /mini/led = f 0.0 1.0 /mini/button = i 0.0 1.0 ... mini.ch0.cc{48..56} > nodered./mini/fader{1..9} nodered./mini/fader{1..9} > minilayers.faders.{0..8}

minilayers is my souped up layer module - allows for a bitmasked layer system - so with four toggling layer buttons I could have 2^4 layers - 5 would give 32 layers etc.

current_layer = 0 controls={} for i=0,8 do controls[i]=0; end

function handler(v) ic=input_channel() first=ic:gsub("%..","") last=ic:gsub('^.-%.',"") pre=ic:gsub('^(.-).([0-9]+)$','%1') suf=ic:gsub('^.-.([0-9]+)$','%1') --print("PRE: "..pre.." SUF: "..suf) lastn=tonumber(last) if(first == "control") then -- Set the current_layer based on the control input channel if (lastn==0) then controls[0]=v output("controlq."..last,math.floor(controls[lastn]/4)) output("controlh."..last,math.floor(controls[lastn]/2)) output("control."..last,math.floor(controls[lastn])) else if (v == 1) then controls[lastn]=1-controls[lastn] output("controlq."..last,math.floor(controls[lastn]/4)) output("controlh."..last,math.floor(controls[lastn]/2)) output("control."..last,math.floor(controls[lastn])) end end current_layer = 0 for i=0,8 do current_layer=math.floor(current_layer+controls[i]2^i) end print("CL.."..current_layer) else -- Handler functions for the input channels -- Calculate the channel offset and just output the value the input channel provides output(pre.."."..math.floor((current_layer 8) + tonumber(suf)), v) --print("Output on "..pre.."."..math.floor((current_layer 8)+suf).." v:"..v) end end

Needs tidying up before I submit it but if anyone needs ideas....

phedders commented 3 years ago

PS the reason I stopped working on mqtt in the lua plugin was because getting the threading right got really painful... or very wasteful. Going via OSC to NR, which I already run just makes sense, for me.

cbdevnet commented 3 years ago

@phedders, @qu4nt4r: I just merged a functional MQTT backend I have been working on for some time to master :) HTTP is also in the pipeline, but will take some more time.

phedders commented 3 years ago

On Mon, 2021-06-21 at 12:06 -0700, cbdev wrote:

@phedders, @qu4nt4r: I just merged a functional MQTT backend I have been working on for some time to master :)

AAhh sooo nice - thankyou :D

HTTP is also in the pipeline, but will take some more time. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.