树莓派4-使用systemctl设置开机自启oled播放服务ip地址与logo

news2024/11/24 0:30:57

一、目标:

开机自启oled显示服务ip与端口,并播放logo

二、过程:

1、出现luma库不存在问题,修改.service文件,增加用户与用户组。在本地测试过程中可以使用python script.py执行python脚本,所以将.service文件中的用户与用户组也设置为命令行相同的用户与用户组:

重启设备发现没有自启,systemctl status bootShowIP.servicejournalctl -u bootShowIP.service获取失败日志,得知luma库不存在ModulNotFoundError: No module named 'luma'

在这里插入图片描述

通过pip show luma可以得知luma已经安装:

在这里插入图片描述

且,在命令行可以通过./run.sh的方式执行python脚本,所以自启执行失败应该与用户和用户组有关:

在这里插入图片描述

修改.service文件中用户与用户组

在这里插入图片描述

2、在python脚本当中使用socket库获取ip地址失败,通过journalctl -u bootShowIP.service可以查看得知问题,并修改为使用subprocess库来获取网卡ip地址:

查看日志,发现socket获取网卡ip失败:

出现问题查看日志

使用subprocess获取网卡ip:

在这里插入图片描述

三、实现效果:

在这里插入图片描述

四、所有源代码:

1、文件夹目录结构

在这里插入图片描述

2、font文件夹是字体文件夹:

在这里插入图片描述

3、logo文件夹是屏幕播放logo图片文件夹,其中空白区域用于叠加ip与端口:

在这里插入图片描述

以上图片获取方式:

1、画一张图;
2、编辑图片,曝光最大,另存为002.jpg;
3、重复步骤2,另存为003.jpg;
4、重复以上步骤直到图片全白;
5、结束。

效果:

请添加图片描述

4、.service文件,需要拷贝到/usr/lib/systemd/system/目录下

[Unit]  
Description=My Python Script  
After=network.target  
  
[Service]  
ExecStart=/home/pi/Desktop/oled/final-show-logo/run.sh -fg
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
KillMode=process
User=pi
Group=pi
  
[Install]  
WantedBy=multi-user.target

在这里插入图片描述

5、run.sh脚本用于启动,不再修改.service文件

#!/bin/sh
#sleep 10
#export PYTHONPATH="$PYTHONPATH:/home/pi/.local/lib/python3.7/site-packages"
python  /home/pi/Desktop/oled/final-show-logo/oled_showpic.py

6、python脚本

import os
import glob
import time
# import socket 
import subprocess  
import fcntl  
import struct  
from PIL import Image, ImageDraw, ImageFont  
import luma.oled as oled  
from luma.core.interface.serial import i2c    
from luma.oled.device import ssd1306  
  
WIDTH=128
HEIGHT=64   

LOCAL_PATH = "/home/pi/Desktop/oled/final-show-logo" #修改为脚本放置的目录
 
'''
#使用socket获取ip地址失败
def get_ip_address(ifname):    
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  
    return socket.inet_ntoa(fcntl.ioctl(  
        s.fileno(),  
        0x8915,  # SIOCGIFADDR  
        struct.pack('256s', ifname[:15].encode('utf-8'))  # 将字符串编码为字节对象  
    )[20:24])
    return "10.11.96.77"
'''
  
def get_ip_address(interface='eth0'):  
    result = subprocess.run(['ip', '-f', 'inet', '-o', 'addr', 'show', interface], stdout=subprocess.PIPE, stderr=subprocess.PIPE)  
    output = result.stdout.decode()  
    if 'inet ' in output:  
        ip_info = output.split('inet ')[1].split('/')[0]  
        return ip_info  
    else:  
        return "x192.168.137.18"  #默认返回的ip地址

def search_dir_pic(dir_name, suffix):
    # 设置文件夹路径  
    # folder_path = os.path.join(os.getcwd(), dir_name)
    folder_path = os.path.join(LOCAL_PATH, dir_name)
    print("图片路径")
    print(folder_path)
      
    # 使用glob模块匹配以数字命名的文件  
    number_files = glob.glob(os.path.join(folder_path, '[0-9]*.'+suffix)) 
    
    print('图片文件名')
    print(number_files)
    
    return sorted(number_files)
 
def load_device():
    # 创建I2C接口对象  
    serial = i2c(port=1, address=0x3C)  # 地址可能因显示屏型号而异  
      
    # 创建OLED设备对象  
    device = ssd1306(serial, WIDTH, HEIGHT) 
    
    return device
    
def draw_on_pic(image):
  
    # 创建一个可以在给定图像上绘制的对象  
    draw = ImageDraw.Draw(image)   
    # font = './font/ARIALI.TTF' 
    font = LOCAL_PATH + '/font/ARIALI.TTF'
    font_size = int(min(WIDTH, HEIGHT)/5)
    font = ImageFont.truetype(font, font_size)
    # 使用函数获取eth0的IP地址  
    ip_address = get_ip_address('eth0')  
    port = 80
    print("local eth0 addr "+ip_address)
    text = 'IP address:\n'+ip_address+'\nPort:\n'+str(port)
    # 定义文本内容和位置  
    x_position = 0  # x坐标  
    y_position = 0  # y坐标  
      
    # 在图片上写字,设置文本颜色为黑色  
    draw.text((x_position, y_position), text, fill=0, font=font)  
    
    # image.save('your_image_with_text.jpg')
    
    return image

# 定义一个函数来将灰度图像转换为二值图像  
def convert_to_binary(image, threshold=128):  
    return image.point(lambda x: 0 if x < threshold else 255, '1')   

def load_pic(pic_name):
    # 加载图片并调整大小  
    print('ready show pic '+pic_name)
    
    image = Image.open(pic_name)
    image = image.resize((WIDTH, HEIGHT)).convert('L')
    image = convert_to_binary(image) # 转换为二值图像(黑白) 
    image = draw_on_pic(image)

    return image
 
def show(image):
    # 将图片数据发送到OLED  
    device.display(image)
    time.sleep(1/5)
    
if __name__=='__main__':
    
    global device
    device = load_device()
    
    pic_group = search_dir_pic('logo', 'jpg')
    
    while True:
        for pic_file in pic_group:
            image = load_pic(pic_file)
            show(image)
            

7、辅助脚本,获取用户和用户组

whoami

echo $USER

echo $LOGNAME

8、在其他设备上部署需要修改

1:修改.service文件中的run.sh路径的位置;
2:修改python脚本中的当前路径LOCAL_PATH位置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1644214.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习周记(第三十七周:语义分割)2024.4.29~2024.5.5

目录 摘要 ABSTRACT 1 DeepLabV3 1.1 空间金字塔池化&#xff08;ASPP&#xff09; 1.2 解码器&#xff08;Decoder&#xff09; 1.3 Xception 2 相关代码 摘要 DeepLabV3 是由Google Brain团队开发的深度学习模型&#xff0c;专注于语义分割任务。它采用深度卷积神经网…

【c++算法篇】双指针(上)

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;算法笔记仓 朋友们大家好啊&#xff0c;本篇文章我们来到算法的双指针部分 目录 1.移动零2.复写零3.快乐数4.盛水最多的容器 1.移动零 题目链接&#xff1a;283.移动零 题目描述&#xff1a; 算法…

深究muduo网络库的Buffer类!!!

最近在学习了muduo库的Buffer类&#xff0c;因为这个编程思想&#xff0c;今后在各个需要缓冲区的项目编程中都可以用到&#xff0c;所以今天来总结一下&#xff01; Buffer的数据结构 muduo的Buffer的定义如下&#xff0c;其内部是 一个 std::vector&#xff0c;且还存在两个…

9.3.k8s的控制器资源(deployment部署控制器)

目录 一、deployment部署控制器概念 二、deployment资源的清单编写 三、小结 功能 使用场景 原理 四、deployment实现升级和回滚 1.编辑deployment资源清单&#xff08;v1版本&#xff09; 2.创建service资源用于访问 ​编辑 3.修改deploy清单中pod镜像版本为V2 4…

Vmware虚拟机瘦身及Samba服务不可用问题解决

虚拟机磁盘空间膨胀是一个令人头疼的问题&#xff0c;特别是对许多搞开发的小伙伴。无论是做后台服务、嵌入式还是Android开发&#xff0c;都面临着这个难题。首先&#xff0c;操作系统本身就已占用不少空间&#xff0c;更新安装包&#xff0c;再下载一些开源软件&#xff0c;剩…

【管理篇】确定自己的管理风格

目录标题 常见的四类领导力风格不同领导力风格适应的场景领导力风格总结 常见的四类领导力风格 四类领导力风格&#xff0c;简单概况如下&#xff1a; 指令式管理&#xff1a;重事不重人&#xff0c;关注目标和结果&#xff0c;喜欢发号施令但不亲力亲为。支持式管理&#xf…

Windows编译SeetaFace6

1. 概述 SeetaFace6包含人脸识别的基本能力&#xff1a;人脸检测、关键点定位、人脸识别&#xff0c;同时增加了活体检测、质量评估、年龄性别估计&#xff0c;并且顺应实际应用需求&#xff0c;开放口罩检测以及口罩佩戴场景下的人脸识别模型。 发布时间 人脸识别算法版本 G…

易语言IDE界面美化支持库

易语言IDE界面美化支持库 下载下来可以看到&#xff0c;是一个压缩包。 那么&#xff0c;怎么安装到易语言中呢&#xff1f; 解压之后&#xff0c;得到这两个文件。 直接将clr和lib丢到易语言安装目录中&#xff0c;这样子就安装完成了。 打开易语言&#xff0c;在支持库配置…

swift微调多模态大语言模型

微调训练数据集指定方式的问题请教 Issue #813 modelscope/swift GitHubQwen1.5微调训练脚本中&#xff0c;我用到了--dataset new_data.jsonl 这个选项&#xff0c; 可以训练成功&#xff0c;但我看文档有提到--custom_train_dataset_path这个选项&#xff0c;这两个有什么…

C 认识指针

目录 一、取地址操作符&#xff08;&&#xff09; 二、解引用操作符&#xff08;*&#xff09; 三、指针变量 1、 指针变量的大小 2、 指针变量类型的意义 2.1 指针的解引用 2.2 指针 - 整数 2.3 调试解决疑惑 认识指针&#xff0c;指针比较害羞内敛&#xff0c;我们…

局域网唤醒平台:UpSnap

简介&#xff1a;UpSnap是一个简单的唤醒局域网网络应用程序。UpSnap为每个用户、每个设备提供了唯一的访问权限。虽然管理员拥有所有权限&#xff0c;但他们可以为用户分配特定的权限&#xff0c;如显示/隐藏设备、访问设备编辑、删除和打开/关闭设备电源。 历史攻略&#xf…

Nginx(参数设置总结)

文章目录 Nginx&#xff08;工作机制&参数设置&#xff09;1.Master&Worker工作机制1.示意图2.解释3.Nginx争抢机制4.accept_mutex解决惊群现象5.多进程结构不用多线程结构的好处6.IO多路复用&#xff0c;实现高并发7.优势 2.参数配置1.work_processes1.基本介绍2.work…

智慧旅游引领未来风尚,科技助力旅行更精彩:科技的力量推动旅游业创新发展,为旅行者带来更加便捷、高效和智能的旅行服务

目录 一、引言 二、智慧旅游的概念与特点 &#xff08;一&#xff09;智慧旅游的概念 &#xff08;二&#xff09;智慧旅游的特点 三、科技推动旅游业创新发展 &#xff08;一&#xff09;大数据技术的应用 &#xff08;二&#xff09;人工智能技术的应用 &#xff08;…

Android Binder机制

一.简介 Binder是什么&#xff1f; Android系统中&#xff0c;涉及到多进程间的通信底层都是依赖于Binder IPC机制。 例如当进程A中的Activity要向进程B中的Service通信&#xff0c;这便需要依赖于Binder IPC。不仅于 此&#xff0c;整个Android系统架构中&#xff0c;大量采…

企业计算机服务器中了rmallox勒索病毒怎么处理,rmallox勒索病毒解密恢复

网络在为企业提供便利的同时&#xff0c;也为企业的数据安全带来严重威胁。随着网络技术的不断发展&#xff0c;越来越多的企业利用网络开展各项工作业务&#xff0c;网络数据安全问题&#xff0c;一直成为企业关心的主要话题&#xff0c;但网络威胁随着网络技术的不断成熟&…

18_Scala面向对象编程trait

文章目录 trait1.定义trait2.向类中混入特质2.1没有父类2.2有父类 3.动态混入3.1动态混入查询功能到公司业务中 4.父类&#xff0c;子类&#xff0c;特质初始化优先级5.Scala功能执行顺序6.常用API trait –特质的学习需要类比Java中的接口&#xff0c;源码编译之后就是interf…

【DPU系列之】Bluefield 2 DPU卡的功能图,ConnectX网卡、ARM OS、Host OS的关系?(通过PCIe Switch连接)

核心要点&#xff1a; CX系列网卡与ARM中间有一个PCIe Swtich的硬件单元链接。 简要记录。 可以看到图中两个灰色框&#xff0c;上端是Host主机&#xff0c;下端是BlueField DPU卡。图中是BF2的图&#xff0c;是BF2用的是DDR4。DPU上的Connect系列网卡以及ARM系统之间有一个…

解决Maven本地仓库存在依赖包还需要远程下载的问题

背景 公司有自己maven私服&#xff0c;正在在私服可以使用的情况&#xff0c;打包是没问题的。但是这次是由于公司大楼整体因电路检修而停电&#xff0c;所有服务器关机&#xff0c;包括maven私服服务器。然后当天确有一个包需要打&#xff0c;这个时候发现死活打不了&#xf…

学习3:scrapy请求对象、模拟登录、POST请求、管道的使用、crawlspider爬虫类

请求对象 请求对象参数 scrapy.Request(url[],callback,method"GET",headers,body,cookies,meta,dont_filterFalse)callback 表示当前的url响应交给那个函数去处理method 指定请求方式headers 接受一个字典&#xff0c;其中不包括cookiesbody 接收json字符串&#…

vs 2022 Xamarin 生成 Android apk

再保存&#xff0c;如果没有生成apk就重启软件 再试一次