cleanup
This commit is contained in:
parent
dc902565f3
commit
781ad51d9b
94
src/phone.ts
94
src/phone.ts
|
|
@ -5,10 +5,12 @@ import { sleep } from "bun"
|
|||
import { processStderr, processStdout } from "./utils/stdio"
|
||||
import Buzz from "./buzz"
|
||||
import { join } from "path"
|
||||
import { GPIO } from "./pins"
|
||||
import GPIO from "./pins"
|
||||
import { Agent } from "./agent"
|
||||
import { searchWeb } from "./agent/tools"
|
||||
|
||||
// TODO: Kill baresip process on exit
|
||||
|
||||
type CancelableTask = () => void
|
||||
|
||||
type PhoneContext = {
|
||||
|
|
@ -80,58 +82,58 @@ if (!agentId) {
|
|||
|
||||
await startPhone(agentId, apiKey)
|
||||
|
||||
// log.info("📞 GPIO inputs initialized")
|
||||
const startBaresip = async (hook: GPIO.InputPin) => {
|
||||
// const baresipConfig = join(import.meta.dir, "..", "baresip")
|
||||
// const baresip = new Baresip(["/usr/bin/baresip", "-v", "-f", baresipConfig])
|
||||
|
||||
// // const baresipConfig = join(import.meta.dir, "..", "baresip")
|
||||
// // const baresip = new Baresip(["/usr/bin/baresip", "-v", "-f", baresipConfig])
|
||||
// baresip.registrationSuccess.connect(async () => {
|
||||
// log.info("🐻 server connected")
|
||||
// const result = await gpio.get(pins.hook)
|
||||
// if (result.state === "low") {
|
||||
// phoneService.send({ type: "initialized" })
|
||||
// } else {
|
||||
// phoneService.send({ type: "pick_up" })
|
||||
// }
|
||||
// })
|
||||
|
||||
// // baresip.registrationSuccess.connect(async () => {
|
||||
// // log.info("🐻 server connected")
|
||||
// // const result = await gpio.get(pins.hook)
|
||||
// // if (result.state === "low") {
|
||||
// // phoneService.send({ type: "initialized" })
|
||||
// // } else {
|
||||
// // phoneService.send({ type: "pick_up" })
|
||||
// // }
|
||||
// // })
|
||||
// baresip.callReceived.connect(({ contact }) => {
|
||||
// log.info(`🐻 incoming call from ${contact}`)
|
||||
// phoneService.send({ type: "incoming_call", from: contact })
|
||||
// })
|
||||
|
||||
// // baresip.callReceived.connect(({ contact }) => {
|
||||
// // log.info(`🐻 incoming call from ${contact}`)
|
||||
// // phoneService.send({ type: "incoming_call", from: contact })
|
||||
// // })
|
||||
// baresip.callEstablished.connect(({ contact }) => {
|
||||
// log.info(`🐻 call established with ${contact}`)
|
||||
// phoneService.send({ type: "answered" })
|
||||
// })
|
||||
|
||||
// // baresip.callEstablished.connect(({ contact }) => {
|
||||
// // log.info(`🐻 call established with ${contact}`)
|
||||
// // phoneService.send({ type: "answered" })
|
||||
// // })
|
||||
// baresip.hungUp.connect(() => {
|
||||
// log.info("🐻 call hung up")
|
||||
// phoneService.send({ type: "remote_hang_up" })
|
||||
// })
|
||||
|
||||
// // baresip.hungUp.connect(() => {
|
||||
// // log.info("🐻 call hung up")
|
||||
// // phoneService.send({ type: "remote_hang_up" })
|
||||
// // })
|
||||
// baresip.connect().catch((error) => {
|
||||
// log.error("🐻 connection error:", error)
|
||||
// phoneService.send({ type: "error", message: error.message })
|
||||
// })
|
||||
|
||||
// // baresip.connect().catch((error) => {
|
||||
// // log.error("🐻 connection error:", error)
|
||||
// // phoneService.send({ type: "error", message: error.message })
|
||||
// // })
|
||||
// baresip.error.connect(async ({ message }) => {
|
||||
// log.error("🐻 error:", message)
|
||||
// phoneService.send({ type: "error", message })
|
||||
// for (let i = 0; i < 4; i++) {
|
||||
// await ring(500)
|
||||
// await sleep(250)
|
||||
// }
|
||||
// process.exit(1)
|
||||
// })
|
||||
|
||||
// // baresip.error.connect(async ({ message }) => {
|
||||
// // log.error("🐻 error:", message)
|
||||
// // phoneService.send({ type: "error", message })
|
||||
// // for (let i = 0; i < 4; i++) {
|
||||
// // await ring(500)
|
||||
// // await sleep(250)
|
||||
// // }
|
||||
// // process.exit(1)
|
||||
// // })
|
||||
|
||||
// const agent = new Agent({
|
||||
// agentId,
|
||||
// apiKey,
|
||||
// tools: {
|
||||
// search_web: (args: { query: string }) => searchWeb(args.query),
|
||||
// },
|
||||
// })
|
||||
// const agent = new Agent({
|
||||
// agentId,
|
||||
// apiKey,
|
||||
// tools: {
|
||||
// search_web: (args: { query: string }) => searchWeb(args.query),
|
||||
// },
|
||||
// })
|
||||
}
|
||||
|
||||
// handleAgentEvents(agent)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
import { readdir } from "node:fs/promises"
|
||||
import { gpiod, cstr } from "./ffi"
|
||||
import { Output } from "./output"
|
||||
import { Input } from "./input"
|
||||
import { ChipNotFoundError } from "./errors"
|
||||
import type { OutputOptions, InputOptions, ChipInfo } from "./types"
|
||||
|
||||
export class GPIO {
|
||||
#chipPath: string
|
||||
|
||||
constructor(options?: { chip?: string }) {
|
||||
this.#chipPath = options?.chip ?? "/dev/gpiochip0"
|
||||
}
|
||||
|
||||
output(pin: number, options?: OutputOptions): Output {
|
||||
return new Output(this.#chipPath, pin, options)
|
||||
}
|
||||
|
||||
input(pin: number, options?: InputOptions): Input {
|
||||
return new Input(this.#chipPath, pin, options)
|
||||
}
|
||||
|
||||
async listChips(): Promise<ChipInfo[]> {
|
||||
const chips: ChipInfo[] = []
|
||||
|
||||
try {
|
||||
const files = await readdir("/dev")
|
||||
const chipFiles = files.filter((f) => f.startsWith("gpiochip"))
|
||||
|
||||
for (const file of chipFiles) {
|
||||
const path = `/dev/${file}`
|
||||
|
||||
try {
|
||||
const chip = gpiod.gpiod_chip_open(cstr(path))
|
||||
if (!chip) continue
|
||||
|
||||
const info = gpiod.gpiod_chip_get_info(chip)
|
||||
if (!info) {
|
||||
gpiod.gpiod_chip_close(chip)
|
||||
continue
|
||||
}
|
||||
|
||||
const name = gpiod.gpiod_chip_info_get_name(info)
|
||||
const label = gpiod.gpiod_chip_info_get_label(info)
|
||||
const numLines = gpiod.gpiod_chip_info_get_num_lines(info)
|
||||
|
||||
chips.push({
|
||||
path,
|
||||
name: String(name || ""),
|
||||
label: String(label || ""),
|
||||
numLines: Number(numLines),
|
||||
})
|
||||
|
||||
gpiod.gpiod_chip_close(chip)
|
||||
} catch {
|
||||
continue
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// /dev might not be accessible, return empty array
|
||||
}
|
||||
|
||||
return chips
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +1,87 @@
|
|||
export { GPIO } from "./gpio"
|
||||
export {
|
||||
import { readdir } from "node:fs/promises"
|
||||
import { gpiod, cstr } from "./ffi"
|
||||
import { Output } from "./output"
|
||||
import { Input } from "./input"
|
||||
import type * as Type from "./types"
|
||||
import {
|
||||
GPIOError,
|
||||
PermissionError,
|
||||
PinInUseError,
|
||||
ChipNotFoundError,
|
||||
InvalidConfigError,
|
||||
} from "./errors"
|
||||
export type {
|
||||
InputOptions,
|
||||
OutputOptions,
|
||||
InputEvent,
|
||||
InputGroupEvent,
|
||||
ChipInfo,
|
||||
PullMode,
|
||||
EdgeMode,
|
||||
} from "./types"
|
||||
|
||||
class GPIO {
|
||||
#chipPath: string
|
||||
|
||||
constructor(options?: { chip?: string }) {
|
||||
this.#chipPath = options?.chip ?? "/dev/gpiochip0"
|
||||
}
|
||||
|
||||
output(pin: number, options?: Type.OutputOptions): Output {
|
||||
return new Output(this.#chipPath, pin, options)
|
||||
}
|
||||
|
||||
input(pin: number, options?: Type.InputOptions): Input {
|
||||
return new Input(this.#chipPath, pin, options)
|
||||
}
|
||||
|
||||
async listChips(): Promise<Type.ChipInfo[]> {
|
||||
const chips: Type.ChipInfo[] = []
|
||||
|
||||
try {
|
||||
const files = await readdir("/dev")
|
||||
const chipFiles = files.filter((f) => f.startsWith("gpiochip"))
|
||||
|
||||
for (const file of chipFiles) {
|
||||
const path = `/dev/${file}`
|
||||
|
||||
try {
|
||||
const chip = gpiod.gpiod_chip_open(cstr(path))
|
||||
if (!chip) continue
|
||||
|
||||
const info = gpiod.gpiod_chip_get_info(chip)
|
||||
if (!info) {
|
||||
gpiod.gpiod_chip_close(chip)
|
||||
continue
|
||||
}
|
||||
|
||||
const name = gpiod.gpiod_chip_info_get_name(info)
|
||||
const label = gpiod.gpiod_chip_info_get_label(info)
|
||||
const numLines = gpiod.gpiod_chip_info_get_num_lines(info)
|
||||
|
||||
chips.push({
|
||||
path,
|
||||
name: String(name || ""),
|
||||
label: String(label || ""),
|
||||
numLines: Number(numLines),
|
||||
})
|
||||
|
||||
gpiod.gpiod_chip_close(chip)
|
||||
} catch {
|
||||
continue
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// /dev might not be accessible, return empty array
|
||||
}
|
||||
|
||||
return chips
|
||||
}
|
||||
|
||||
static Error = GPIOError
|
||||
static PermissionError = PermissionError
|
||||
static PinInUseError = PinInUseError
|
||||
static ChipNotFoundError = ChipNotFoundError
|
||||
static InvalidConfigError = InvalidConfigError
|
||||
}
|
||||
|
||||
namespace GPIO {
|
||||
export type PullMode = Type.PullMode
|
||||
export type EdgeMode = Type.EdgeMode
|
||||
export type InputOptions = Type.InputOptions
|
||||
export type OutputOptions = Type.OutputOptions
|
||||
export type InputEvent = Type.InputEvent
|
||||
}
|
||||
|
||||
export default GPIO
|
||||
|
|
|
|||
|
|
@ -17,15 +17,9 @@ export type InputEvent = {
|
|||
timestamp: bigint // nanoseconds
|
||||
}
|
||||
|
||||
export type InputGroupEvent<T extends string = string> = InputEvent & {
|
||||
pin: T // name of the pin that fired
|
||||
}
|
||||
|
||||
export type ChipInfo = {
|
||||
path: string
|
||||
name: string
|
||||
label: string
|
||||
numLines: number
|
||||
}
|
||||
|
||||
export type PinConfig = Record<string, { offset: number; pull: PullMode }>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user