From 7a3f194cd550cc0f3f1f2df69bf613915abb8998 Mon Sep 17 00:00:00 2001 From: alexander-the-alright Date: Wed, 6 Jul 2022 23:09:58 -0400 Subject: [PATCH] added config file for list purposes --- src/led.go | 23 ++++-- src/led2.go | 223 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/led2list | 4 + src/ledlist | 8 +- 4 files changed, 249 insertions(+), 9 deletions(-) create mode 100644 src/led2.go create mode 100644 src/led2list diff --git a/src/led.go b/src/led.go index a6f046a..6cb00ce 100644 --- a/src/led.go +++ b/src/led.go @@ -1,10 +1,10 @@ // ============================================================================= // Auth: Alex Celani // File: led.go -// Revn: 07-04-2022 2.0 +// Revn: 07-05-2022 3.0 // Func: receive data as an endpoint, send response back to middleman // -// TODO: +// TODO: implement rainbow // ============================================================================= // CHANGE LOG // ----------------------------------------------------------------------------- @@ -28,6 +28,7 @@ // added support for white, cyan, yellow, and magenta // finished comments for tell() and ask() and even simple // parsing stuff in handleClient() +//*07-05-2022: added support for kill messages // // ============================================================================= @@ -163,8 +164,9 @@ func tell( comm []string ) string { default: // user asks for else, bail out response = "status unknown" } - case "kill": // user wants to stop running - os.Exit( 2 ) // FIXME + // user wants to stop running + case "kill", "quit", "end", "die", "stop": + response = "kill" default: // user enters incorrect command response = "command unknown" } @@ -201,8 +203,6 @@ func handleClient( conn net.Conn ) { os.Exit( 2 ) // if not, exit } - // TODO differentiate ask commands from tell commands - // initiate response variable var resp string @@ -230,6 +230,10 @@ func handleClient( conn net.Conn ) { if *verbose { // XXX identical verbose print fmt.Println( "sent: ", resp ) // print response } + + if resp == "kill" { // if user sent back kill + os.Exit( 1 ) // end process + } } } @@ -258,7 +262,7 @@ func main() { lg = flag.Int( "lg", 9, "GPIO pin for green LED" ) lb = flag.Int( "lb", 25, "GPIO pin for blue LED" ) verbose = flag.Bool( "v", false, "verbose printing" ) - ip = flag.String( "ip", ":1202", "ip and port of self" ) + ip = flag.String( "ip", ":1212", "ip and port of self" ) flag.Parse() // initialize pins to GPIO 11, 9, and 25 @@ -280,6 +284,11 @@ func main() { pinG.Output() pinB.Output() + // Initialize output to "off" + pinR.High() + pinG.High() + pinB.High() + // "resolve" ip & host according to TCP rules tcpAddr, err := net.ResolveTCPAddr( "tcp", *ip ) check( err ) // check error diff --git a/src/led2.go b/src/led2.go new file mode 100644 index 0000000..fcd1d9f --- /dev/null +++ b/src/led2.go @@ -0,0 +1,223 @@ +// ============================================================================= +// Auth: Alex Celani +// File: led2.go +// Revn: 07-05-2022 1.0 +// Func: receive data as an endpoint, send response back to middleman +// +// TODO: +// ============================================================================= +// CHANGE LOG +// ----------------------------------------------------------------------------- +//*07-05-2022: copied from led.go +// +// ============================================================================= + +package main + +import ( + "net" // ResolveTCPAddr, conn.Write,Read,Close + // ListenTCP, listener.Accept + "os" // Args, Stderr, Exit + "fmt" // Fprintf, Println + "strings" // ToLower + "github.com/stianeikeland/go-rpio" // talk to RasPi pins + "flag" // Parse, String, Int, Bool + "io/ioutil" // ReadFile +) + + +// quick error checking +func check( err error ) { + // if user checks an error, it better be nil + if err != nil { + // put error in string, print in stderr + fmt.Fprintf( os.Stderr, "Fatal error: %s", err.Error() ) + os.Exit( 2 ) // quit + } +} + + +// quick function to return LED fields +func ask( comm []string ) string { + + // declare response variable + var response string + + // XXX this could be done with a map instead + // what is the first word? + switch comm[0] { + case "status": // if user asks for status, get status + response = status + case "list": // if user wants a list of fields + // open file containing fields + // XXX considering using this file to populate future map + file, err := ioutil.ReadFile( os.Args[0] + "list" ) + check( err ) // check error + // cast entire file to string and make returnable + response = string( file ) + default: // if user asks for something unknown + response = "field unknown" + } + + // return + return response + +} + + +// quick function to change LED colors +func tell( comm []string ) string { + + // declare response variable + var response string + + // XXX this could be done with a map instead + // what is the first word? + switch comm[0] { + case "status": // if user trying to change status + status = comm[1] // preemptively set status + response = status + switch comm[1] { + case "on": // if trying to turn led on + pinR.High() + case "off": // leave leds off, set response to off + pinR.Low() + default: // user asks for else, bail out + response = "status unknown" + } + // user wants to stop running + case "kill", "quit", "end", "die", "stop": + response = "kill" + default: // user enters incorrect command + response = "command unknown" + } + + return response + +} + + +// function to handle incoming connections +func handleClient( conn net.Conn ) { + defer conn.Close() // barring any error, still close connection + + var buf [512]byte // declare large byte array, store messages + + // iterate forever to always read over connection + for { + // read n bytes from connection into buffer + n, err := conn.Read( buf[0:] ) + if err != nil { // erroring on read will simply leave the + return // function so it can start again later + } + + if *verbose { + // print recv'd message + // string() only works on byte SLICES so [:] is required + fmt.Println( "recv: ", string( buf[:n] ) ) + } + + // split command into words for ease of parsing + command := strings.Split( string( buf[:n] ), " " ) + + if command[1] != "led2" { // confirm message belongs here + os.Exit( 2 ) // if not, exit + } + + // TODO differentiate ask commands from tell commands + + // initiate response variable + var resp string + + switch command[0] { // is user getting or setting? + case "ask": // if getting + // get, store response in variable to be sent back + resp = ask( command[2:] ) + case "tell": // if setting + // set, store response in variable to be sent back + resp = tell( command[2:] ) + default: // if neither, bail out + resp = "command form unknown" + } + + if *verbose { // XXX verbose print + fmt.Println( "answer: ", resp ) // print response + } + + // write that response back to original client + _, err = conn.Write( []byte( resp ) ) + if err != nil { // erroring on write will simply leave the + return // function so it can start again later + } + + if *verbose { // XXX identical verbose print + fmt.Println( "sent: ", resp ) // print response + } + + if resp == "kill" { // if user sent back kill + os.Exit( 1 ) // end process + } + } +} + + +//var params = make( map[string]string ) +//var states = make( map[string]string ) +var pinR rpio.Pin // declare red led pin +var status string = "off" // declare status variable + +var ( // declare flag variables + led *int + verbose *bool + ip *string +) + + +func main() { + + // declare command line input variables + led = flag.Int( "led", 24, "GPIO pin for red LED" ) + verbose = flag.Bool( "v", false, "verbose printing" ) + ip = flag.String( "ip", ":1203", "ip and port of self" ) + flag.Parse() + + // initialize pins to GPIO 24 + pinR = rpio.Pin( *led ) + + if err := rpio.Open(); err != nil { + // on error, print error and exit + fmt.Println(err) + os.Exit(1) + } + + // Unmap gpio memory when done + defer rpio.Close() + + // Set pins to output mode + pinR.Output() + + // Initialize output to "off" + pinR.High() + + // "resolve" ip & host according to TCP rules + tcpAddr, err := net.ResolveTCPAddr( "tcp", *ip ) + check( err ) // check error + + // bind and "listen" to ip and port, according to tcp rules + listener, err := net.ListenTCP( "tcp", tcpAddr ) + check( err ) // check error + + // iterate forever + // TODO i mean i can totally make this more user friendly + for { + // accept a connection that makes its way to bound port + conn, err := listener.Accept() + if err != nil { // if connection fails... + continue // don't quit program, not fatal error + } + + // asynchronous function to handle connection to client + go handleClient( conn ) + } +} + diff --git a/src/led2list b/src/led2list new file mode 100644 index 0000000..95efcc0 --- /dev/null +++ b/src/led2list @@ -0,0 +1,4 @@ +status ^v + on + off + list v diff --git a/src/ledlist b/src/ledlist index 125c56c..811d730 100644 --- a/src/ledlist +++ b/src/ledlist @@ -1,7 +1,11 @@ color ^v - red - green blue + cyan + green + magenta + red + white + yellow status ^v on off