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 }