Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[firmata] Handling loss of connection with the TCPAdaptor #758

Open
abishekmuthian opened this issue Jun 27, 2020 · 1 comment
Open

[firmata] Handling loss of connection with the TCPAdaptor #758

abishekmuthian opened this issue Jun 27, 2020 · 1 comment

Comments

@abishekmuthian
Copy link

I'm using ESP8266(server) and so TCPAdaptor(firmata) along with MQTTAdapter.

I tried different methodologies to handle connection loss,

  1. Checking at regular intervals for connections, but connections are returned even if the actual WiFi connection is lost (switching off the ESP8266).

  2. Trying to connect with adaptor at regular intervals, but returns "client is already connected" even when connection
    is lost.

I found setAutoReconnect for MQTTAdaptor, which I assume handles connection loss for the same. But what is the recommended strategy to handle connection loss of TCPAdaptor?

@dustinblackman
Copy link

dustinblackman commented Oct 26, 2021

I'm still working through learning the library, but my understanding is there's no real connection management for TCPAdapters. Attempting to do it manually you find yourself stuck as Disconnect() doesn't properly cleanup the old connection, preventing you from being able to reconnect yourself.

I've put together this really bad hack that uses the ESP8266 onboard LED as a healthcheck, and when it fails it'll disconnect and clear out the existing private connection fields on the adapter struct, and then connect again. Once I get more familiar I'll find time to PR a fix so you won't require the need for reflection/unsafe.

Example:

package main

import (
	"log"
	"reflect"
	"time"
	"unsafe"

	"gobot.io/x/gobot"
	"gobot.io/x/gobot/drivers/gpio"
	"gobot.io/x/gobot/platforms/firmata"
)

func main() {
	firmataAdaptor := firmata.NewTCPAdaptor("192.168.1.3:3030")
	led := gpio.NewLedDriver(firmataAdaptor, "2")

	work := func() {
		gobot.Every(5*time.Second, func() {
			err := led.Toggle()
			if err != nil {
				log.Print("Failed to toggle leg, will attempt reconnecting")
				log.Print(err)

				firmataAdaptor.Disconnect()

				sp, connErr := firmataAdaptor.PortOpener(firmataAdaptor.Port())
				if connErr != nil {
					log.Print("Failed to reconnect to esp directly, will panic")
					panic(connErr)
				}

				connField := reflect.ValueOf(firmataAdaptor).Elem().FieldByName("conn")
				reflect.NewAt(connField.Type(), unsafe.Pointer(connField.UnsafeAddr())).
					Elem().
					Set(reflect.ValueOf(sp))

				err = firmataAdaptor.Connect()
				if err != nil {
					log.Print("Could not reconnect to esp")
					log.Print(err)
					return
				}

				log.Print("Successfully reconnected")
			}
		})
	}

	robot := gobot.NewRobot("bot",
		[]gobot.Connection{firmataAdaptor},
		[]gobot.Device{led},
		work,
	)

	robot.Start()
}

@gen2thomas gen2thomas changed the title Handling loss of connection with the TCPAdaptor [frimata] Handling loss of connection with the TCPAdaptor Nov 1, 2024
@gen2thomas gen2thomas changed the title [frimata] Handling loss of connection with the TCPAdaptor [firmata] Handling loss of connection with the TCPAdaptor Nov 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants