tinynote

package module
v0.0.0-...-6d595f1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 28, 2021 License: MIT Imports: 8 Imported by: 0

README

Blues Wireless

The note-tinygo Go library for communicating with Blues Wireless Notecard via serial or I²C.

This library allows you to control a Notecard by coding in Go for the TinyGo platform. Your program may configure Notecard and send Notes to Notehub.io.

See also:

Installing

For all releases, we have compiled the notecard utility for different OS and architectures here. If you don't see your OS and architecture supported, please file an issue and we'll add it to new releases.

Dependencies

  • Install tinygo and the tinygo tools (here)

Example

// Example that uses the cellular Blues Wireless Notecard to send data to the notehub.io
// routing service, then routing it through to your own service in JSON on a REST endpoint.

package main

import (
    "fmt"
    "machine"
    "time"

    tinynote "github.com/blues/note-tinygo"
)

// Your Notehub project's ProductUID (so the notecard knows where to send its data)
const productUID = "net.ozzie.ray:test"

// Tinygo's main program
func main() {

    // Use default configuration of I2C
    machine.I2C0.Configure(machine.I2CConfig{})

    // Create a function for this machine type that performs I2C I/O
    i2cTxFn := func(addr uint16, wb []byte, rb []byte) (err error) {
        return machine.I2C0.Tx(addr, wb, rb)
    }

    // Open an I2C channel to the Notecard, supplying the I2C I/O function
    notecard, err := tinynote.OpenI2C(tinynote.DefaultI2CAddress, i2cTxFn)
    if err != nil {
        fmt.Printf("error opening notecard i2c port: %s\n", err)
        return
    }

    // Enable trace output so we can visualize requests/responses
    notecard.DebugOutput(true)

    // Configure the Notecard and set it to auto-provision to your project
    req := tinynote.NewRequest("hub.set")
    req["product"] = productUID // which notehub project we're using
    req["mode"] = "continuous"  // stay online continuously
    req["outbound"] = 60        // how often (mins) to auto-sync if pending data
    err = notecard.Request(req)
    if err != nil {
        fmt.Printf("%s: %s\n", req["req"], err)
    }

    // Enter a loop that sends data to the Notehub repeatedly. Data on the notecard
    // is stored within a user-defined JSON 'body', carried within an envelope called
    // a 'note' that is automatically tagged with time and location metadata.
    for i := 0; ; i++ {
        time.Sleep(time.Second * 10)

        req := tinynote.NewRequest("note.add") // 'add a note' transaction

        // Create 'body' by using Golang's standard container for a JSON data
        // structure, which is a map of fieldname-indexed data of any type.
        // This 'body' is completely user-defined, and would presumably contain
        // you sensor data.
        body := map[string]interface{}{}
        body["test1"] = i
        body["test2"] = float64(i) + float64(i)*0.2
        body["test3"] = fmt.Sprintf("0x%04x", i)
        body["test5"] = (i & 1) == 0
        body["test6"] = map[string]interface{}{"hello": "world"}

        req["body"] = body // add the user-defined body to the note
        req["sync"] = true // for this test, sync to notehub immediately

        // Send request to notecard and check the response for errors
        rsp, err := notecard.RequestResponse(req)
        if tinynote.IsError(err, rsp) {
            fmt.Printf("%s: %s\n", req["req"], tinynote.ErrorString(err, rsp))
        }

    }

}

Documentation

Index

Constants

View Source
const CardI2CMax = 253

CardI2CMax controls chunk size that's socially appropriate on the I2C bus. It must be 1-253 bytes as per spec (which allows space for the 2-byte header in a 255-byte read)

View Source
const CardRequestI2CSegmentDelayMs = 250

CardRequestI2CSegmentDelayMs (golint)

View Source
const CardRequestI2CSegmentMaxLen = 250

CardRequestI2CSegmentMaxLen (golint)

View Source
const CardRequestSerialSegmentDelayMs = 250

CardRequestSerialSegmentDelayMs (golint)

View Source
const CardRequestSerialSegmentMaxLen = 250

CardRequestSerialSegmentMaxLen (golint)

View Source
const DefaultI2CAddress = 0x17

DefaultI2CAddress is Our default I2C address

View Source
const ErrCardIo = "{io}"

ErrCardIo is the card I/O error suffix

View Source
const ErrTimeout = "{timeout}"

ErrTimeout is the card timeout error suffix

Variables

View Source
var InitialDebugMode = false

InitialDebugMode is the debug mode that the context is initialized with

View Source
var RequestSegmentDelayMs = -1

RequestSegmentDelayMs (golint)

View Source
var RequestSegmentMaxLen = -1

RequestSegmentMaxLen (golint)

View Source
var SerialTimeoutMs = 10000

SerialTimeoutMs is the response timeout for Notecard serial communications.

Functions

func ErrorClean

func ErrorClean(err error) error

ErrorClean removes all error keywords from an error string

func ErrorContains

func ErrorContains(err error, errKeyword string) bool

ErrorContains tests to see if an error contains an error keyword that we might expect

func ErrorJSON

func ErrorJSON(message string, err error) (rspJSON []byte)

ErrorJSON returns a JSON object with nothing but an error code, and with an optional message

func ErrorString

func ErrorString(err error, rsp map[string]interface{}) string

ErrorString returns the error within a response

func IsError

func IsError(err error, rsp map[string]interface{}) bool

IsError tests to see if a response contains an error

func JSONToObject

func JSONToObject(objectJSON []byte) (object map[string]interface{}, err error)

JSONToObject unmarshals the specified JSON and returns it as a map[string]interface{}

func NewBody

func NewBody() (body map[string]interface{})

NewBody creates a new body. Note that this method is provided merely as syntactic sugar, as of the form body := note.NewBody()

func NewCommand

func NewCommand(reqType string) (cmd map[string]interface{})

NewCommand creates a new command that requires no response from the notecard.

func NewRequest

func NewRequest(reqType string) (req map[string]interface{})

NewRequest creates a new request that is guaranteed to get a response from the Notecard. Note that this method is provided merely as syntactic sugar, as of the form req := tinynote.NewRequest("note.add")

func ObjectToJSON

func ObjectToJSON(object map[string]interface{}) (objectJSON []byte, err error)

ObjectToJSON converts an object to JSON

Types

type Context

type Context struct {

	// True to emit trace output
	Debug bool

	// Disable generation of User Agent object
	DisableUA bool

	// Class functions
	CloseFn       func(context *Context)
	ResetFn       func(context *Context) (err error)
	TransactionFn func(context *Context, noResponse bool, reqJSON []byte) (rspJSON []byte, err error)
	// contains filtered or unexported fields
}

Context for the port that is open

func OpenI2C

func OpenI2C(addr uint16, i2cTxFn I2CTxFn) (context *Context, err error)

OpenI2C opens the card on I2C

func OpenUART

func OpenUART(uartReadFn UARTReadFn, uartWriteFn UARTWriteFn) (context *Context, err error)

OpenUART opens the card on the specified uart

func (*Context) Close

func (context *Context) Close()

Close the port

func (*Context) DebugOutput

func (context *Context) DebugOutput(enabled bool) (wasEnabled bool)

DebugOutput enables/disables debug output

func (*Context) Identify

func (context *Context) Identify() (name string)

Identify the type of this Notecard connection

func (*Context) Request

func (context *Context) Request(req map[string]interface{}) (err error)

Request performs a card transaction with a JSON structure and doesn't return a response (This is for semantic compatibility with other languages.)

func (*Context) RequestResponse

func (context *Context) RequestResponse(req map[string]interface{}) (rsp map[string]interface{}, err error)

RequestResponse performs a card transaction with a JSON structure and doesn't return a response (This is for semantic compatibility with other languages.)

func (*Context) Reset

func (context *Context) Reset() (err error)

Reset the port

func (*Context) Response

func (context *Context) Response() (rsp map[string]interface{}, err error)

Response is used in rare cases where there is a transaction that returns multiple responses

func (*Context) Transaction

func (context *Context) Transaction(req map[string]interface{}) (rsp map[string]interface{}, err error)

Transaction performs a card transaction with a JSON structure

func (*Context) TransactionJSON

func (context *Context) TransactionJSON(reqJSON []byte) (rspJSON []byte, err error)

TransactionJSON performs a card transaction using raw JSON []bytes

func (*Context) UserAgent

func (context *Context) UserAgent() (ua map[string]interface{})

UserAgent is for Someday when the machine package supports finding the characteristics of the machine, this is the place where we'd provide it.

type I2CTxFn

type I2CTxFn func(i2cAddress uint16, writebuf []byte, readbuf []byte) (err error)

I2CTxFn is the function to write and read from the I2C Port

type UARTReadFn

type UARTReadFn func(data []byte) (n int, err error)

UARTReadFn is the function to read from the UART port

type UARTWriteFn

type UARTWriteFn func(data []byte) (n int, err error)

UARTWriteFn is the function to write to the UART port

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL