github.com/dim13/unifi@v0.0.0-20230308161331-9b04946f5e93/cmd/log-roaming/main.go (about)

     1  // Copyright (c) 2014 The unifi Authors. All rights reserved.
     2  // Use of this source code is governed by ISC-style license
     3  // that can be found in the LICENSE file.
     4  
     5  // Example command log-roaming
     6  // log stations of a given site as they roam
     7  package main
     8  
     9  import (
    10  	"flag"
    11  	"log"
    12  	"log/syslog"
    13  	"os"
    14  	"time"
    15  
    16  	"github.com/dim13/unifi"
    17  )
    18  
    19  type roaming struct {
    20  	Name    string
    21  	IP      string
    22  	Ap      string
    23  	Channel int
    24  	Essid   string
    25  }
    26  
    27  type roamMap map[string]roaming
    28  
    29  var stamap roamMap
    30  
    31  var (
    32  	host    = flag.String("host", "unifi", "Controller hostname")
    33  	user    = flag.String("user", "admin", "Controller username")
    34  	pass    = flag.String("pass", "unifi", "Controller password")
    35  	version = flag.Int("version", 5, "Controller base version")
    36  	port    = flag.String("port", "8443", "Controller port")
    37  	siteid  = flag.String("siteid", "default", "Sitename or description")
    38  	delay   = flag.Duration("delay", 5*time.Second, "delay")
    39  )
    40  
    41  func main() {
    42  	flag.Parse()
    43  	u, err := unifi.Login(*user, *pass, *host, *port, *siteid, *version)
    44  	if err != nil {
    45  		log.Fatal(err)
    46  	}
    47  
    48  	defer u.Logout()
    49  
    50  	site, err := u.Site(*siteid)
    51  	if err != nil {
    52  		log.Fatal(err)
    53  	}
    54  
    55  	apsmap, err := u.UAPMap(site)
    56  	if err != nil {
    57  		log.Fatal(err)
    58  	}
    59  
    60  	elog := log.New(os.Stderr, "", log.Ltime)
    61  	slog, err := syslog.NewLogger(syslog.LOG_NOTICE|syslog.LOG_DAEMON, 0)
    62  	if err != nil {
    63  		log.Fatal(err)
    64  	}
    65  	logger := []*log.Logger{elog, slog}
    66  
    67  	ticker := time.NewTicker(*delay)
    68  	defer ticker.Stop()
    69  	for range ticker.C {
    70  		newmap := make(roamMap)
    71  		sta, err := u.Sta(site)
    72  		if err != nil {
    73  			continue
    74  		}
    75  		for _, s := range sta {
    76  			newmap[s.Mac] = roaming{
    77  				Name:    s.Name(),
    78  				IP:      s.IP,
    79  				Ap:      apsmap[s.ApMac].Name,
    80  				Channel: s.Channel,
    81  				Essid:   s.ESSID,
    82  			}
    83  		}
    84  		for k, v := range newmap {
    85  			if z, ok := stamap[k]; !ok {
    86  				elog.SetPrefix(" → ")
    87  				for _, l := range logger {
    88  					l.Printf("%s appears on %s/%d %s/%s\n",
    89  						v.Name, v.Ap, v.Channel, v.Essid, v.IP)
    90  				}
    91  			} else if z != v {
    92  				elog.SetPrefix(" ↔ ")
    93  				for _, l := range logger {
    94  					l.Printf("%s roams from %s/%d %s/%s to %s/%d %s/%s\n",
    95  						v.Name,
    96  						z.Ap, z.Channel, z.Essid, z.IP,
    97  						v.Ap, v.Channel, v.Essid, v.IP)
    98  				}
    99  			}
   100  			delete(stamap, k)
   101  		}
   102  		for _, v := range stamap {
   103  			elog.SetPrefix(" ← ")
   104  			for _, l := range logger {
   105  				l.Printf("%s vanishes from %s/%d %s/%s\n",
   106  					v.Name, v.Ap, v.Channel, v.Essid, v.IP)
   107  			}
   108  		}
   109  		stamap = newmap
   110  	}
   111  }