go-unifi icon indicating copy to clipboard operation
go-unifi copied to clipboard

Simple examples?

Open purpleidea opened this issue 1 year ago • 3 comments

Nice work! Before I dive deep into source reading, is there a page with some simple examples, say how to change the port PoE power mode, or do the auth plumbing?

I'd love to add some resources and functions to https://github.com/purpleidea/mgmt/ for your code. In particular, I'd love to know if there is a non-polling way (events) to get an event when the state of any of the properties changes.

Thanks!

purpleidea avatar Jan 11 '24 20:01 purpleidea

I'm able to connect and list things, but I'm not entirely wrapping my head around the correct way to change a property, for example, setting an individual switch port's PoeMode to "off" or back to "auto".

I keep getting "not found" when trying to make the change. Any tips or an example would be great!

Some sample code here that I wrote:

package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"net"
	"net/http"
	"net/http/cookiejar"
	"time"

	"github.com/paultyng/go-unifi/unifi"
)

func main() {
	fmt.Printf("hello\n")
	ctx := context.Background()
	user := "root"
	endpoint := "https://192.168.204.149/"
	password := "XXX"
	client := &unifi.Client{}
	setHTTPClient(client, true, "unifi")
	client.SetBaseURL(endpoint)
	if err := client.Login(ctx, user, password); err != nil {
		panic(err)
	}

	site := "default"
	//{
	//	networks, err := client.ListNetwork(ctx, site) // ([]unifi.Network, error)
	//	if err != nil {
	//		panic(err)
	//	}
	//	for i, x := range networks {
	//		fmt.Printf("NETWORK(%d): %+v\n", i, x)
	//	}
	//}

	//{
	//	devices, err := client.ListDevice(ctx, site) // ([]unifi.Device, error)
	//	if err != nil {
	//		panic(err)
	//	}

	//	for i, x := range devices {
	//		fmt.Printf("DEVICE(%d): %+v\n", i, x)
	//	}
	//}

	mac := "d8:b3:70:60:54:3f" // sw2
	portNumber := 23
	poeMode := "off"
	//poeMode := "auto"

	fmt.Printf("getting device...\n")
	device, err := client.GetDeviceByMAC(ctx, site, mac) // (*unifi.Device, error)
	if err != nil {
		panic(err)
	}

	//{
	//	portProfiles, err := client.ListPortProfile(ctx, site) // ([]unifi.PortProfile, error)
	//	if err != nil {
	//		panic(err)
	//	}

	//	for i, x := range portProfiles {
	//		fmt.Printf("PORTPROFILE(%d): %#v\n", i, x)
	//	}
	//}

	fmt.Printf("PRE: %+v\n", device.PortOverrides)

	found := false
	changed := false
	for _, port := range device.PortOverrides {
		if port.PortIDX != portNumber {
			continue
		}
		fmt.Printf("found port %+v\n", portNumber)
		found = true

		if port.PoeMode != poeMode {
			port.PoeMode = poeMode // set it
			changed = true
			port.OpMode = "switch"
			port.PortProfileID = "5e66e7dd2e521b052aef68b2"

		}
	}

	if !found && poeMode == "off" {
		fmt.Printf("didn't find port %+v\n", portNumber)
		port := unifi.DevicePortOverrides{
			PortIDX: portNumber,
		}
		port.PoeMode = poeMode // set it
		changed = true
		port.OpMode = "switch"
		port.PortProfileID = "5e66e7dd2e521b052aef68b2"

		device.PortOverrides = append(device.PortOverrides, port)
	}

	//XXX unifi.DevicePortOverrides
	//portOverrides := device.PortOverrides // []unifi.DevicePortOverrides XXX ???

	if !changed {
		fmt.Printf("no need to update device...\n")
		return
	}

	//pp, err := client.UpdatePortProfile(ctx, site, d *unifi.PortProfile) // (*unifi.PortProfile, error)

	fmt.Printf("updating device...\n")
	newDevice, err := client.UpdateDevice(ctx, site, device) // (*unifi.Device, error)
	if err != nil {
		// XXX: this returns "not found" // *unifi.NotFoundError
		fmt.Printf("err(%T): %+v\n", err, err)
		panic(err)
	}

	fmt.Printf("POST: %+v\n", newDevice.PortOverrides)




//func (c *lazyClient) UpdatePortProfile(ctx context.Context, site string, d *unifi.PortProfile) (*unifi.PortProfile, error) {

	fmt.Printf("done!\n")
}

func setHTTPClient(c *unifi.Client, insecure bool, subsystem string) {
	httpClient := &http.Client{}
	httpClient.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		DialContext: (&net.Dialer{
			Timeout:   30 * time.Second,
			KeepAlive: 30 * time.Second,
			DualStack: true,
		}).DialContext,
		MaxIdleConns:          100,
		IdleConnTimeout:       90 * time.Second,
		TLSHandshakeTimeout:   10 * time.Second,
		ExpectContinueTimeout: 1 * time.Second,

		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: insecure,
		},
	}

	//httpClient.Transport = logging.NewSubsystemLoggingHTTPTransport(subsystem, httpClient.Transport)

	jar, _ := cookiejar.New(nil)
	httpClient.Jar = jar

	c.SetHTTPClient(httpClient)
}

purpleidea avatar Apr 20 '24 04:04 purpleidea

/cc @myoung34 @dnesting

purpleidea avatar Apr 20 '24 04:04 purpleidea