From 24ecc9870e0b8f512237a4cb6d5fa612f5a1162f Mon Sep 17 00:00:00 2001 From: James Coleman Date: Sat, 7 Sep 2024 21:29:34 -0500 Subject: [PATCH] Set default config on configuration error to allow listing midi connections before configuration. Also fix MQTT configurations. --- README.md | 87 ++++++++++++++++++++++++++++++++++++++++++++++++--- config.go | 3 +- main.go | 2 +- midiRouter.go | 35 ++++++++++++--------- 4 files changed, 106 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 8eca4df..221a357 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ On MacOS, there is an IAC Driver that can be enabled in Audio MIDI Setup. midi_routers: - name: service_notifications device: IAC Driver Bus 1 - debug_listener: true + log_level: 1 ``` ### Example note trigger configuration @@ -120,7 +120,7 @@ midi_routers: midi_routers: - name: service_notifications device: IAC Driver Bus 1 - debug_listener: true + log_level: 1 note_triggers: - channel: 0 note: 0 @@ -136,7 +136,7 @@ midi_routers: midi_routers: - name: service_notifications device: IAC Driver Bus 1 - debug_listener: true + log_level: 1 request_triggers: - channel: 0 note: 0 @@ -152,7 +152,7 @@ midi_routers: midi_routers: - name: service_notifications device: IAC Driver Bus 1 - debug_listener: true + log_level: 2 note_triggers: - channel: 0 note: 0 @@ -174,5 +174,82 @@ midi_routers: headers: Content-Type: - multipart/form-data; boundary=---------------------------888832887744 - debug_request: true +``` + +### Example mqtt config + +```yaml +--- +midi_routers: + - name: Wing Midi Signals + device: WING Port 4 + mqtt: + host: 10.0.0.2 + port: 1883 + client_id: midi_mqtt_bridge + user: mqtt + password: password + topic: midi/behringer_wing + log_level: 3 + note_triggers: + - channel: 0 + note: 1 + match_all_velocities: true + mqtt_topic: osc/behringer_wing/send/$ctl/user/2/2/enc/val + mqtt_payload: + - "1" + - channel: 0 + note: 2 + match_all_velocities: true + mqtt_topic: osc/behringer_wing/send/$ctl/user/2/2/enc/val + mqtt_payload: + - "2" + - channel: 0 + note: 3 + match_all_velocities: true + mqtt_topic: osc/behringer_wing/send/$ctl/user/2/2/enc/val + mqtt_payload: + - "3" + - channel: 0 + note: 4 + match_all_velocities: true + mqtt_topic: osc/behringer_wing/send/$ctl/user/2/2/enc/val + mqtt_payload: + - "4" + - channel: 0 + note: 5 + match_all_velocities: true + mqtt_topic: osc/behringer_wing/send/$ctl/user/2/2/enc/val + mqtt_payload: + - "5" + - channel: 0 + note: 6 + match_all_velocities: true + mqtt_topic: osc/behringer_wing/send/$ctl/user/2/2/enc/val + mqtt_payload: + - "6" + - channel: 0 + note: 7 + match_all_velocities: true + mqtt_topic: osc/behringer_wing/send/$ctl/user/2/2/enc/val + mqtt_payload: + - "7" + - channel: 0 + note: 8 + match_all_velocities: true + mqtt_topic: osc/behringer_wing/send/$ctl/user/2/2/enc/val + mqtt_payload: + - "8" + - channel: 0 + match_all_notes: true + match_all_velocities: true + mqtt_topic: osc/behringer_wing/send/$ctl/user/2/2/bu/val + mqtt_payload: + - "1" + - channel: 0 + match_all_notes: true + match_all_velocities: true + mqtt_topic: osc/behringer_wing/send/$ctl/user/2/2/bu/val + mqtt_payload: + - "0" ``` diff --git a/config.go b/config.go index 56495d3..7c9f824 100644 --- a/config.go +++ b/config.go @@ -48,7 +48,7 @@ func (a *App) ReadConfig() { } else if _, err := os.Stat(etcConfig); err == nil { configFile = etcConfig } else { - log.Fatal("Unable to find a configuration file.") + log.Println("Unable to find a configuration file.") } // Load the configuration file. @@ -68,6 +68,7 @@ func (a *App) ReadConfig() { fig.Dirs(filePath), ) if err != nil { + app.config = config log.Printf("Error parsing configuration: %s\n", err) return } diff --git a/main.go b/main.go index 9fffe56..e32cdc8 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,7 @@ import ( const ( serviceName = "midi-request-trigger" serviceDescription = "Takes trigger MIDI messages by HTTP or MQTT requests and trigger HTTP or MQTT requests by MIDI messages" - serviceVersion = "0.2" + serviceVersion = "0.2.1" ) // App is the global application structure for communicating between servers and storing information. diff --git a/midiRouter.go b/midiRouter.go index 61da0e2..5e77a94 100644 --- a/midiRouter.go +++ b/midiRouter.go @@ -70,12 +70,14 @@ type MQTTPayload struct { // Triggers that occur from MIDI messages received. type NoteTrigger struct { - // If set, every note played will be matched. - MatchAllNotes bool `fig:"match_all_notes"` // Channel to match. Channel uint8 `fig:"channel"` + // If we should match all channel values. + MatchAllChannels bool `fig:"match_all_channels"` // Note to match. Note uint8 `fig:"note"` + // If we should match all note values. + MatchAllNotes bool `fig:"match_all_notes"` // Velocity to match. Velocity uint8 `fig:"velocity"` // If we should match all velocity values. @@ -83,7 +85,7 @@ type NoteTrigger struct { // Custom MQTT message. Do not set to ignore MQTT. MqttTopic string `fig:"mqtt_topic"` // Nil payload will generate a payload with midi info. - MqttPayload []interface{} `fig:"mqtt_payload"` + MqttPayload interface{} `fig:"mqtt_payload"` // If the HTTP request should includ midi info. MidiInfoInRequest bool `fig:"midi_info_in_request"` // Should SSL requests require a valid certificate. @@ -133,17 +135,17 @@ type MidiRouter struct { // How much logging. // 0 - Errors - // 1 - MQTT and OSC receive logging. - // 2 - MQTT and OSC send logging. + // 1 - MQTT, HTTP, and MIDI receive logging. + // 2 - MQTT, HTTP, and MIDI send logging. // 3 - Debug - LogLevel LogLevel `yaml:"log_level" json:"log_level"` + LogLevel LogLevel `fig:"log_level"` // Connection to MIDI device. MidiOut drivers.Out `fig:"-"` // Function to stop listening to MIDI device. ListenerStop func() `fig:"-"` // The client connection to MQTT. - MqttClient mqtt.Client `yaml:"-" json:"-"` + MqttClient mqtt.Client `fig:"-"` } // Logging function to allow log levels. @@ -156,7 +158,7 @@ func (r *MidiRouter) Log(level LogLevel, format string, args ...interface{}) { // When a MIDI message occurs, send the HTTP request. func (r *MidiRouter) sendRequest(channel, note, velocity uint8) { // If MQTT firehose not disabled, send to general cmd topic. - if r.MQTT.Host != "" && r.MQTT.Port != 0 && !r.MQTT.DisableMidiFirehose { + if r.MqttClient != nil && !r.MQTT.DisableMidiFirehose { payload := MQTTPayload{ Channel: channel, Note: note, @@ -168,7 +170,7 @@ func (r *MidiRouter) sendRequest(channel, note, velocity uint8) { } else { topic := r.MQTT.Topic + "/cmd" r.MqttClient.Publish(topic, 0, true, data) - r.Log(SendLog, "-> [MQTT] %s", topic) + r.Log(SendLog, "-> [MQTT] %s: %s", topic, string(data)) } } @@ -177,14 +179,19 @@ func (r *MidiRouter) sendRequest(channel, note, velocity uint8) { // If match all notes, process this request. // If not, check if channel, note, and velocity matches. // The velocity may be defined to accept all. - if trig.MatchAllNotes || (trig.Channel == channel && trig.Note == note && (trig.Velocity == velocity || trig.MatchAllVelocities)) { + if (trig.Channel == channel || trig.MatchAllChannels) && (trig.Note == note || trig.MatchAllNotes) && (trig.Velocity == velocity || trig.MatchAllVelocities) { // For all logging, we want to print the message so setup a common string to print. logInfo := fmt.Sprintf("note %s(%d) on channel %v with velocity %v", midi.Note(note), note, channel, velocity) - if trig.MqttTopic != "" { + if trig.MqttTopic != "" && r.MqttClient != nil { if trig.MqttPayload != nil { - r.MqttClient.Publish(trig.MqttTopic, 0, true, trig.MqttPayload) - r.Log(SendLog, "-> [MQTT] %s", trig.MqttTopic) + data, err := json.Marshal(trig.MqttPayload) + if err != nil { + r.Log(ErrorLog, "Json Encode: %s", err) + } else { + r.MqttClient.Publish(trig.MqttTopic, 0, true, data) + r.Log(SendLog, "-> [MQTT] %s: %s", trig.MqttTopic, string(data)) + } } else { payload := MQTTPayload{ Channel: channel, @@ -196,7 +203,7 @@ func (r *MidiRouter) sendRequest(channel, note, velocity uint8) { r.Log(ErrorLog, "Json Encode: %s", err) } else { r.MqttClient.Publish(trig.MqttTopic, 0, true, data) - r.Log(SendLog, "-> [MQTT] %s", trig.MqttTopic) + r.Log(SendLog, "-> [MQTT] %s: %s", trig.MqttTopic, string(data)) } } }