From 25d67194826cddbd69d3beb1e4569455f93e42f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1ximo=20Cuadros?= Date: Mon, 24 Oct 2016 01:47:11 +0200 Subject: [PATCH] rpc: draft of a RPC service --- rpc/client.go | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++ rpc/server.go | 54 +++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 rpc/client.go create mode 100644 rpc/server.go diff --git a/rpc/client.go b/rpc/client.go new file mode 100644 index 0000000..de167b7 --- /dev/null +++ b/rpc/client.go @@ -0,0 +1,79 @@ +package rpc + +import ( + "encoding/gob" + "image/color" + "net/rpc" + + "github.com/mcuadros/go-rpi-rgb-led-matrix" +) + +func init() { + gob.Register(color.RGBA{}) +} + +// RGBLedMatrix matrix representation for ws281x +type Client struct { + network string + addr string + client *rpc.Client + leds []color.Color +} + +// NewRGBLedMatrix returns a new matrix using the given size and config +func NewClient(network, addr string) (rgbmatrix.Matrix, error) { + client, err := rpc.DialHTTP(network, addr) + if err != nil { + return nil, err + } + + return &Client{ + network: network, + addr: addr, + client: client, + leds: make([]color.Color, 2048), + }, nil +} + +// Geometry returns the width and the height of the matrix +func (c *Client) Geometry() (width, height int) { + var reply *GeometryReply + err := c.client.Call("RPCMatrix.Geometry", &GeometryArgs{}, &reply) + if err != nil { + panic(err) + } + + return reply.Width, reply.Height +} + +func (c *Client) Apply(leds []color.Color) error { + defer func() { c.leds = make([]color.Color, 2048) }() + + var reply *ApplyReply + return c.client.Call("RPCMatrix.Apply", &ApplyArgs{Colors: leds}, &reply) +} + +// Render update the display with the data from the LED buffer +func (c *Client) Render() error { + return c.Apply(c.leds) +} + +// At return an Color which allows access to the LED display data as +// if it were a sequence of 24-bit RGB values. +func (c *Client) At(position int) color.Color { + if c.leds[position] == nil { + return color.Black + } + + return c.leds[position] +} + +// Set set LED at position x,y to the provided 24-bit color value. +func (m *Client) Set(position int, c color.Color) { + m.leds[position] = color.RGBAModel.Convert(c) +} + +// Close finalizes the ws281x interface +func (c *Client) Close() error { + return c.Apply(make([]color.Color, 2048)) +} diff --git a/rpc/server.go b/rpc/server.go new file mode 100644 index 0000000..9840bd2 --- /dev/null +++ b/rpc/server.go @@ -0,0 +1,54 @@ +package rpc + +import ( + "fmt" + "image/color" + "log" + "net" + "net/http" + "net/rpc" + + "github.com/mcuadros/go-rpi-rgb-led-matrix" +) + +type RPCMatrix struct { + m rgbmatrix.Matrix +} + +type GeometryArgs struct{} +type GeometryReply struct{ Width, Height int } + +func (m *RPCMatrix) Geometry(_ *GeometryArgs, reply *GeometryReply) error { + w, h := m.m.Geometry() + reply.Width = w + reply.Height = h + + return nil +} + +type ApplyArgs struct{ Colors []color.Color } +type ApplyReply struct{} + +func (m *RPCMatrix) Apply(args *ApplyArgs, reply *ApplyReply) error { + return m.m.Apply(args.Colors) +} + +type CloseArgs struct{} +type CloseReply struct{} + +func (m *RPCMatrix) Close(_ *CloseArgs, _ *CloseReply) error { + return m.m.Close() +} + +func Serve(m rgbmatrix.Matrix) { + rpc.Register(&RPCMatrix{m}) + + rpc.HandleHTTP() + l, e := net.Listen("tcp", ":1234") + if e != nil { + log.Fatal("listen error:", e) + } + + fmt.Println(l) + http.Serve(l, nil) +}