米尔电子
直播中

jf_50393217

4年用户 200经验值
擅长:可编程逻辑 嵌入式技术
私信 关注
[技术]

【米尔-全志T113-i开发板试用】7、实现web点灯功能

IMG_7196

实现web点灯功能其实也不难,我们先来写一下服务端的代码

1、在Gin上添加点灯的接口

1.1 实现点灯接口

通过Gin的文档,我们可以抄一个简单的参数解析代码,然后修改成我们需要的代码。

// 调用路径参考 /setLedValue?name=green&value=1
r.GET("/setLedValue", func(c *gin.Context) {
		name := c.Query("name")
		value := c.Query("value")
		setLedValue(name, value)
		c.JSON(http.StatusOK, gin.H{"status": "ok"})
	})

这样就定义了一个超级简单的接口,通过传递name和value参数,然后调用设置led的函数,就完成这个功能了。

1.2 实现点灯函数

我们可以通过直接使用sysfs来完成点灯功能,这里我就偷懒一下,直接使用米尔T113板子上的两个已经配置好的led-green和led-blue。点灯函数如下

func setLedValue(name, value string) {
	// Open the file for the specified LED
	f, err := os.OpenFile("/sys/class/leds/"+Default.Leds[name].Path+"/brightness", os.O_APPEND|os.O_WRONLY, os.ModeAppend)
	if err != nil {
		fmt.Println("open file error :", err)
		return
	}
	defer f.Close()
	// Write the new brightness value to the file
	_, err = f.WriteString(value)
	if err != nil {
		fmt.Println(err)
		return
	}
}

在这里,为了能不修改代码,又可以快速配置板载 led灯,添加了toml文件配置led灯的功能。配置文件如下

hostname = ["milkv.local", "milkvt113.local"]

[leds.green]
    port = 0
    path = "led-green"
    value = "1"

[leds.blue]
    port = 0
    path = "led-blue"
    value = "1"

这个配置文件可以修改mDNS的域名(可以设置多个域名),以及led的设置,例如这里就添加了两个led,并设置了对应路径和默认状态。

读取配置文件的代码如下

package main

import (
	"fmt"
	"os"

	"github.com/BurntSushi/toml"
)

var Default config

type (
	config struct {
		Hostname []string
		Leds     map[string]led
	}
	led struct {
		Port  int64
		Path  string
		Value string
	}
)

func getConfigs() {
	f := "configs.toml"

	_, err := toml.DecodeFile(f, &Default)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

测试

可以正常调用

image.png

LED也正常点亮了

image.png

完善代码

代码还有需要完善的地方,首先点灯函数没有对参数的有效性进行检查。我们可以将对应代码进行修改。

func setLedValue(name, value string) string {
	if value == "1" || value == "0" {
		for n := range Default.Leds {
			if n == name {
				// Open the file for the specified LED
				f, err := os.OpenFile("/sys/class/leds/"+Default.Leds[name].Path+"/brightness", os.O_APPEND|os.O_WRONLY, os.ModeAppend)
				if err != nil {
					fmt.Println("open file error :", err)
					return err.Error()
				}
				defer f.Close()
				// Write the new brightness value to the file
				_, err = f.WriteString(value)
				if err != nil {
					fmt.Println(err)
					return err.Error()
				}
				return "Led " + name + " set to " + value
			}
		}
		return "Led " + name + " not found"
	} else {
		fmt.Println("value must be 0 or 1, got", value)
		return "Value must be 0 or 1"
	}
}

后端接口的代码也需要修改一下

// 调用路径参考 /setLedValue?name=green&value=1
	r.GET("/setLedValue", func(c *gin.Context) {
		name := c.Query("name")
		value := c.Query("value")
		c.JSON(http.StatusOK, gin.H{"status": setLedValue(name, value)})
	})

然后启动的时候,在成功加载了配置文件后,对led的默认状态进行设置。

func main() {
	getConfigs()
	// 设置LED灯的默认状态
	for n := range Default.Leds {
		setLedValue(n, Default.Leds[n].Value)
	}
	go runDNS()
	getInfo()
	r := setupRouter()
	// Listen and Server in 0.0.0.0:8080
	r.Run(":80")
}

这样就好很多了,接下来,我们再来编写web端的界面代码,顺便学习一下Vue的组件书写方式。

创建设备组件和LED灯按钮组件

我们先创建一个Led组件,在component目录下新建一个Led.vue文件。这个文件里需要先添加两个隐藏的button,因为Tailwind CSS会自动优化未使用的主题。有空我再找找别的办法来解决这个问题。

<template>
    <h1 class="m-1 p-1"> LED : {{ name }} <span class="float-right"><button class="rounded-md p-1 px-10 text-white"
                :class="[status === 'on' ? 'bg-' + name + '-600' : 'bg-gray-700']" @click="setLedStatus">{{ status
                }}</button></span>
    </h1>
    <button class="hidden bg-green-600" />
    <button class="hidden bg-blue-600" />
</template>

<script setup lang="ts">
import axios from 'axios'
import { ref } from 'vue'

const status = ref('on')
const props = defineProps<{
    name?: string
    value?: string
}>()

if (props.value === 'off') {
    status.value = 'off'
}
function setLedStatus() {
    axios.get('/setLedValue?name=' + props.name + '&value=' + (status.value === "on" ? "1" : "0")).then((res) => {
        console.log(res.data)
        let str = res.data.status.toString()
        if (str.includes("set to")) {
            if (str.slice(-1) === "1") { status.value = "off" } else {
                status.value = "on"
            }
        }
    })
}
</script>

然后在devices.vue文件里,添加相关的组件。

<template>
    <div class="m-4 p-2 rounded-md bg-slate-200 text-gray-800 w-9/12 text-sm">
        <Led name="green" value="off" />
        <Led name="blue" value="off" />
    </div>
</template>

<script setup lang="ts">
//import axios from 'axios'
import { onMounted, ref } from 'vue'
import Led from "../components/Led.vue"

const BoardList = ref(0)
BoardList.value = 0

onMounted(() => {
})
</script>

image.png

然后我们就可以在页面上,直接控制LED的亮和灭啦。

更多回帖

发帖
×
20
完善资料,
赚取积分