python cv2 获取矩形,居中,旋转

下面的代码可以让一个图片中的任意位置,角度的矩形,旋转到正确的位置,并且居中显示。
import cv2
import numpy as np
import matplotlib.pyplot as plt
from pynput import keyboard,mouse

def plt_show(image):
plt.imshow(image)
plt.axis('off')
plt.show()

def show(image):
cv2.imshow("raw", image)
cv2.waitKey(0)

def move_right():
print("moving right")

def move_left():
print("moving left")

def move_up():
print("moving up")

def move_down():
print("moving down")

def save_picture(angel,image):
cv2.imwrite("%s/%s.jpg" % ('image', angel),image.shape[0],image.shape[1])

def handlToGray(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, TRE = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY) # 图像二值化
return TRE
#图像转动一定角度
def rotate_bound(image, angle):
# grab the dimensions of the image and then determine the
# center
(h, w) = image.shape[:2]
(cX, cY) = (w // 2, h // 2)

# grab the rotation matrix (applying the negative of the
# angle to rotate clockwise), then grab the sine and cosine
# (i.e., the rotation components of the matrix)
M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)
cos = np.abs(M[0, 0])
sin = np.abs(M[0, 1])

# compute the new bounding dimensions of the image
nW = int((h * sin) + (w * cos))
nH = int((h * cos) + (w * sin))

# adjust the rotation matrix to take into account translation
M[0, 2] += (nW / 2) - cX
M[1, 2] += (nH / 2) - cY

# perform the actual rotation and return the image
return cv2.warpAffine(image, M, (nW, nH))
#图像按照给定的x,y 值进行平移
def moving_bound(image,x,y):
(h, w) = image.shape[:2]
M = np.float32([[1,0,-x],[0,1,-y]])
return cv2.warpAffine(image, M, (w, h))
#找到矩形的旋转角度
def find_rect(image):
gray = handlToGray(image)
contours, hierarchy = cv2.findContours(gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
rect = cv2.minAreaRect(contours[0])
return rect


#获取矩形的偏移坐标
def getoffset(image):
(h, w) = image.shape[:2]
cx = int(w / 2)
cy = int(h / 2)
x_left = 0;
x_right = 0;
y_up = 0;
y_down = 0;

x_total = 0;
y_total = 0;

# 获取左边边框
for i in range(cx, 0, -1):
mx = image[cy][i] # 先取高度,再取宽度
if (mx == 0):
x_left = i
break
# 获取右边边框
for i in range(cx, w, 1):
mx = image[cy][i]
if (mx == 0):
x_right = i
break
x_total = x_right - x_left

# 获取上边框
for i in range(cy, 0, -1):
my = image[i][cx]
if (my == 0):
y_up = i
break
# 获取下边框
for i in range(cy, h, 1):
mx = image[i][cx]
if (mx == 0):
y_down = i
break
y_total = y_down - y_up

x_offset = (x_left + x_total / 2) - cx
y_offset = (y_up + y_total / 2) - cy

return x_offset, y_offset, x_total, y_total



def on_press(key):
pass

def on_release(key):
if key == keyboard.Key.esc: # Stop listener
return False
elif key == keyboard.Key.right:
move_right()
elif key == keyboard.Key.left:
move_left()
elif key == keyboard.Key.up:
move_up()
elif key == keyboard.Key.down:
move_down()



def on_move(x, y):
pass

def on_click(x, y, button, pressed):
pass

def on_scroll(x, y, dx, dy):
pass

def main():

image = cv2.imread("image/raw2.jpg")
rect = find_rect(image)
angle = rect[2] #角度
im = rotate_bound(image, -angle)
rect = find_rect(im)
print(rect)
x,y = rect[0]
width, height = rect[1]
box = cv2.boxPoints(rect)
(h, w) = im.shape[:2]
cx = int(w / 2)
cy = int(h / 2)
im = moving_bound(im,x-cx,y-cy)
if width < height:
im = rotate_bound(im, 90)
TRE = handlToGray(im)
plt_show(TRE)

main()

# Collect events until released
keyboard_listener = keyboard.Listener(on_press=on_press, on_release=on_release)
mouse_listener = mouse.Listener(on_click=on_click, on_move=on_move, on_scroll=on_scroll)
lst = [keyboard_listener, mouse_listener]

for t in lst: t.start()
for t in lst: t.join()




少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)

—前言—-

        据网上文章说有20万人抗战在疫情第一线。这些人都是战士。我觉得一天给他们一万人民币的补贴也不为过。20万人,一天就是20亿,按照90天计算,就是1800亿人民币,2019年中国一般财政预算收入为19万亿,两千亿的补贴似乎不算多。

—正文—-

        这是一个大鱼吃小鱼的经典游戏,面向8-10岁学生,用时约2小时。大概是几年前了,我们带着小孩去儿童医院看病,那里有一台机器可以免费玩几个小游戏,其中就有这个大鱼吃小鱼的游戏。小孩玩得不亦乐乎。一直都想去做一做大鱼吃小鱼的游戏,但一直都忙着没空。现在还是疫情关键时期,足不出户,开学时间还遥遥无期。

        在家里的多数时间,我们都在学习。英语是我们的薄弱项,我带着小孩,从一年级上册开始读到四年级,读课本,读好几遍,这样至少会读了,当然还有很多单词默写不出来。如今,小学六年,竟然不教国际音标。人们崇尚手足舞蹈的自然拼读,号称上了多少节课,就能读出所有单词的,其实不过是一个笑话而已。因此这个假期,我教会了小孩英语国际音标。

        每天语文朗读打卡,对课本算是预习过了。数学课本内容和课本练习基本上都做完了。过年的时候做了几个二级考试的练习题。估计是这段时间在家里时间太久了,小孩吵着要玩Scratch,做了吃鱼和大鱼吃小鱼,感觉小孩的编程水平有了不少进步。

        开始的时候小孩使用了好多小鱼的角色,没能完成功能。后来经过我的指点,知道如何获取另外一个角色的大小以后,顺利的完成了作品。完成作品后,照例让老二上来玩一玩,验证一下。开始的时候她很紧张,还尖叫着,很刺激的样子,看到大鱼来了,还有点害怕,让我们帮他挪动鼠标躲开大鱼,两个小朋友都玩得很起劲。

        这一个作品比上一个吃鱼的作品要复杂一些,主要难点是如何在一个角色中获取另外一个角色的参数-大小。比较用户操作的鱼和出来的小鱼的大小,就可以判断可以不可以吃掉这条鱼。还用到角色造型图片大小、克隆体角色大小的功能,还是需要一些技巧的。

        功能说明:

1)各种大小不一的鱼不停的从右边往左边游动。鼠标控制一条鱼,名字叫做多丽。为了让人能判断鱼的大小,需要确保每条鱼的造型在100%大小时,看上去差不多大。同时右边出来的鱼大小的幅度间隔为10,即从10到200之间取10的整数倍。

2)多丽只能吃尺寸比自己小的鱼。吃到一条比自己小的鱼时,会长大一点;如果碰到比自己还大的鱼,会变小一点。侦测中有一个指令能够获取到其他角色的参数-大小。这样就能够对比出来的鱼和多丽的大小了。

3)右边出来的鱼有个最大值,如果多丽长大到比最大的鱼还大,那就变成“天下无敌”了,游戏成功,结束。

4)如果多丽减少到比右边出来的最小的鱼还要小,那就无法再次长大,游戏失败,结束。

5)背景、吃到小鱼、吃到大鱼、都有对应的音效。成功、失败是会播放一段乐曲,并切换到对应的背景上。

程序共享:https://scratch.mit.edu/projects/368568076/

点击原文,也可以进入这个共享的程序。

视频演示:

 

 

一、鱼-造型设置
少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)
主界面,两个角色。很少吧。千万别用一个角色代表一种鱼,那样会让程序变得比较复杂。
出来的鱼造的造型,这里有个技巧。使用一个角色,多个造型,后面使用克隆,出现不同的鱼。但要确保每个造型的鱼的大小大概一致。系统中添加的鱼100%的时候,有大有小,不一致,需要调整。
少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)
二、游戏胜利和失败的背景
简单做一个就行。
少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)
三、多丽的动画制作
简单制作一个,复制默认的造型,将鱼鳍改一下大小和方向,嘴巴闭合,尾巴稍微修改一下。
少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)
四、多丽-跟随鼠标移动
少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)
五、多丽-更换造型-动画
少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)
六、多丽-播放泡泡声效
少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)
七、多丽吃到小鱼,增加大小
鱼碰到多丽时,会判断大小,然后发出指令:加减,加为吃到小鱼,增加身体大小;减为碰到大鱼,减少身体大小。
少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)
吃到小鱼,增加,大小和鱼的大小相关。通过这个关键的侦测指令,能够获取另外一个角色或舞台的参数,如大小。
增加到200以后,就无敌了,成功闯关。
八、多丽-碰到大鱼,减少大小
少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)
减少到10以下,就失败了,再也无法变大,因为右边出来的鱼最小的是10.
九、鱼-克隆
少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)
十、克隆启动-飞出,这里取了一个1-20的随机数,然后放大十倍。
少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)
十一、克隆体启动,判断碰撞和大小。
碰到多丽,读取多丽的大小,然后如果当前的鱼比多丽小,就让多丽增加大小,这条小鱼被吃掉了。
否则这条鱼还继续存在,让多丽减少大小。这里有个技巧,延迟了3秒,这三秒钟不会再次碰撞到这条大鱼。否则会多次擦身,碰撞多次大鱼。
少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)
十二、接收到结束,停止其他脚本,鱼就不飞出来了。 
少儿编程Scratch第37讲:大鱼吃小鱼(8-10岁)
大家可以试试。
共享地址:https://scratch.mit.edu/projects/368568076/
 

少儿编程Scratch第36讲:吃鱼(8-9岁)

—前言—-
        疑似病例显著减少,现存确诊案例还有好几万,但也进入下降通道了。胜利就在眼前。马路上的汽车逐渐多了起来,下周基本上都要去上班了。
        疫情结束以后,我们真该在武汉市中心立一座高高的碑,哪怕是无名碑也行,纪念因为这次疫情而逝去的人们,记住全国的帮扶,记住多少前线战士的英勇。
—正文—-        
        本作品面向8-10岁学生,用时约2小时。这个作品几乎是小孩自己独立完成的作品,后面我给他加了几个功能,让作品更为完善一些。本质上说,依然是”炒冷饭”,和我们最开始学的“星球大战”类似,主要是碰撞。不过学会了如何设置生命值,如何使用变量了,对运动和碰撞已经算是比较熟练了。 
        功能说明:
1)各种小鱼不停的从右边往左边游动;鲨鱼跟随鼠标移动。
2)鲨鱼吃到一条小鱼,则得一分;如果漏掉了,小鱼逃过鲨鱼,到达左边舞台边缘,就扣掉一分;
3)鲨鱼有3条命。河豚从下方随机飞出,碰到鲨鱼,鲨鱼减少一条命。3条命都用完以后,游戏结束,切换背景。
4)鲨鱼被河豚击中以后,开始累积吃鱼金币,吃20条小鱼,自动增加一条命。最多有3条命。
5)吃鱼、小鱼逃走、碰到河豚,都有声音效果。碰到河豚以后,鲨鱼受伤,流血,血不断增多,掉落到海底,消失。
程序共享:https://scratch.mit.edu/projects/368348599
来段视频:

 

少儿编程Scratch第36讲:吃鱼(8-9岁)

 

一:角色设置

少儿编程Scratch第36讲:吃鱼(8-9岁)

三个角色,鲨鱼,小鱼,河豚炸弹。

二、变量设置

少儿编程Scratch第36讲:吃鱼(8-9岁)

生命值用来计算碰到河豚以后吃到多少条小鱼,吃满20条小鱼以后,生命值增加1。

分数:总分

生命值:最多三条命。

三、鲨鱼失血效果

少儿编程Scratch第36讲:吃鱼(8-9岁)

复制了四个鲨鱼造型,画上一滩血,逐渐增大,后面通过造型切换,制造流血增多的效果。

少儿编程Scratch第36讲:吃鱼(8-9岁)

碰到河豚后的流血牺牲效果。

四、小鱼-好多种类的鱼

少儿编程Scratch第36讲:吃鱼(8-9岁)

普通的小鱼,这里添加了很多小鱼的造型。通过切换造型,就可以出来不同的鱼了。克隆+造型,很有用。否则要使用很多角色,会导致代码太多。

五、河豚

少儿编程Scratch第36讲:吃鱼(8-9岁)

河豚上画了一个红线,表示这是危险品,不能碰。

六、鲨鱼-初始化,碰到河豚

初始化,切换到第一个背景。如果碰到河豚,生命值减少一,续命金币清零,记住碰到了,因为要通知其他角色要停止运动了。

碰到河豚以后,两秒滑行到下方。这是小孩自己想出来的效果。

少儿编程Scratch第36讲:吃鱼(8-9岁)

 

 

七、鲨鱼-续命

集满20个金币(被碰撞后吃到20条小鱼),增加一条命,最多3条,所以这里用了判断。续命以后,金币要减少20.

 

少儿编程Scratch第36讲:吃鱼(8-9岁)

 

八、鲨鱼-结束,隐藏

3条命都用完了,就结束游戏,切换到结束背景,播放声音。停止脚本。这是后来我要求清除背景,加上去的。

 

少儿编程Scratch第36讲:吃鱼(8-9岁)

 

九、鲨鱼的造型切换。

这里用了判断,如果没有碰到就正规造型。如果碰到了,就流血造型。流血的造型是后来加上去的。如果不判断,流一次血,鲨鱼往下掉,还是普通造型。

 

少儿编程Scratch第36讲:吃鱼(8-9岁)

 

十、鲨鱼:跟随鼠标

跟随鼠标。

 

少儿编程Scratch第36讲:吃鱼(8-9岁)

 

十一、克隆小鱼

 

少儿编程Scratch第36讲:吃鱼(8-9岁)

小鱼不停从右边飞出来。使用了克隆,克隆前更换造型,这样每条鱼都会不同。

 

看来已经是比较熟练了。能够使用方向和克隆指令了。

 

十二、小鱼-克隆器启动,飞出来。

少儿编程Scratch第36讲:吃鱼(8-9岁)

小鱼从右边往左移动。

 

十三、小鱼逃脱

小鱼逃掉后减分,播放了一段录制的声音-我逃走了。

后面是游戏结束时,没生命值时停止飞行,停止克隆。

 

少儿编程Scratch第36讲:吃鱼(8-9岁)

 

十四、河豚-克隆。

克隆河豚,从下方飞出。

 

少儿编程Scratch第36讲:吃鱼(8-9岁)

 

十五、河豚-造型变换,上浮。

少儿编程Scratch第36讲:吃鱼(8-9岁)

 

十六、河豚碰撞判断

 

河豚上浮,碰到鲨鱼判断。

少儿编程Scratch第36讲:吃鱼(8-9岁)

 

 

 

 

 

如何动态改变bootstrap-slider的最大,最小和当前值

下面就是Jquery的代码,注意要refresh一下,然后再setValue,要不然setValue再refresh会回到默认值。


min          = datasets[index]["min"];
max = datasets[index]["max"];
$(this).slider('setAttribute', 'max', max);
$(this).slider('setAttribute', 'min', min);
$(this).attr("data-slider-max",max)
$(this).attr("data-slider-min",min)
$(this).slider('refresh');
$(this).slider('setValue', value);

少儿编程Scratch第35讲:赛车-乐高入门机器人-WeDo(4-7岁)

—前言—-
        因为新病毒的关系,我们今天继续留在家里。本来想中午带他们找个地方踢一会球的,后来还是没有出门。确诊6086例,新增能确诊1456,新增数已经比昨天减少了三四百,治愈人数逐渐攀升。拐点已经出现,曙光就在眼前。未来几天,世界卫生组织WHO的评估和欧美的态度将非常关键。如果被评为疫区,如果和主要经济体的国际航班停摆,那对经济的打击将是非常大的。服务业占GDP已经超过50%,如今不少地方都切断了交通运转,整个地区进行隔离,大家都不出门,不敢聚会活动,这对经济的影响会很大。旅游、餐饮、酒店、娱乐游乐,很多人可能就直接没有工资了。如果工资或基本工资照发,那么有一些企业可能挨不过几个月。所以我们必须尽快的结束战斗,否则这将是一场大灾难。不过我们也不必惊慌,03年非典时期,我们也是被评为疫区,但两个月就把疫区的帽子摘掉了。如今国力强、技术强、人民富裕,相信会很快就能战胜困难。
        暂时,酒精和口罩都还供应不足,京东还显示无货,有人开始买高浓度的二锅头,还有买伏特加烈酒的。
—正文—-        
        乐高WEDO 套装45300还是比较简单的,很适合4-5岁的小孩在家长指导下搭建。我的多数时间都花在老大身上,有一段时间没有陪小女玩积木了,有几次做了积木作品也没有写文章。老二会问为什么不教她拼积木,还说已经有很长时间没有一起拼积木了,很多都忘记了。老二的确有点被我忽略了。现在8岁的老大基本上不玩这套WEDO 2.0套件,如果玩,也是从头到尾都他一个人搞定,我一个积木也不用给他找,他自己还会加很多其他功能上去。
        之前写过毛毛虫风车月球漫步车垃圾回收车机械手,今天做了一个赛车的作品,效果还不错。4-5岁小孩,大约一个小时能够完成。找积木还是要很多时间,多数积木都是我帮小孩找的。拼接完成后,我和小孩一起制作了一个简单的前进后退程序,大功告成。
来段视频:

 

 

手册:

 

这个作品的PDF手册可以在这里找到
https://education.lego.com/en-us/support/wedo-2/building-instructions

少儿编程Scratch第35讲:赛车-乐高入门机器人-WeDo(4-7岁)

后轮驱动,后轮底座。

 

少儿编程Scratch第35讲:赛车-乐高入门机器人-WeDo(4-7岁)

后面放主机

 

少儿编程Scratch第35讲:赛车-乐高入门机器人-WeDo(4-7岁)

这里放电动机

 

少儿编程Scratch第35讲:赛车-乐高入门机器人-WeDo(4-7岁)

前轮的架子

 

少儿编程Scratch第35讲:赛车-乐高入门机器人-WeDo(4-7岁)

搭得很认真。

 

少儿编程Scratch第35讲:赛车-乐高入门机器人-WeDo(4-7岁)

前面还有一个距离感应器,不过没在程序中编写距离传感器的程序。前后连段的衔接开始时是错误的,应该朝里,这样才结实。

 

少儿编程Scratch第35讲:赛车-乐高入门机器人-WeDo(4-7岁)

这样卡在一起,很结实。

 

少儿编程Scratch第35讲:赛车-乐高入门机器人-WeDo(4-7岁)

加前轮。

 

少儿编程Scratch第35讲:赛车-乐高入门机器人-WeDo(4-7岁)

底部。

 

 

Django内嵌的html页面显示主页面的变量

比如有两个页面a.html和b.html a.html里面使用{% include b.html %},然后在b.html里面使用a.html的view里面数据库的查询

a.html 的view文件

class HomePageView(TemplateView):
template_name = 'home.html'


def home(request):
allcategory = TypeList.objects.all()#通过Category表查出所有分类
print ("this is home device function")
#把查询出来的分类封装到上下文里
context = {
'allcategory': allcategory,
}
return render(request, 'home.html', context)#把上下文传到index.html页面
b.html里面是这个样子的:
<ul>

{% for device in allcategory %}
<li> {{device.type}} </li>
{% endfor %}

</ul>

关键的部分其实是在网站urls.py文件的定义里面,也就是网站启动的时候是不会启动这个home函数的,那么我们认为的把url修改成直接启动这个函数:
urlpatterns = [

path('',views.home),

]


Django后台添加管理内容

比如在后台添加一些用户看不见的内容,但是对网站运行需要的信息。下面就建立一个MQTT服务器的信息

1. Django-admin startapp mqtt

2.  打开新建目录下面的model文件,输入内容

from django.db import models
class MQTTHOST(models.Model):
name = models.CharField('name', max_length=100)
ip = models.CharField('ip', max_length=100)
port = models.CharField('port', max_length=100)

class Meta:
verbose_name = 'MQTT主机'
verbose_name_plural = verbose_name

def __str__(self):
return self.ip
3. 打开mqtt目录下面的admin.py输入
from django.contrib import admin
from .models import MQTTHOST

@admin.register(MQTTHOST)

class MQTTHOSTAdmin(admin.ModelAdmin):
list_display = ('name', 'ip', 'port')
4. 打开mqtt下面的app输入内容如下
from django.apps import AppConfig


class MqttConfig(AppConfig):
name = 'mqtt'
5. 打开setting 文件,在下面增加mqtt.apps.MqttConfig
INSTALLED_APPS = [
  ……
'mqtt.apps.MqttConfig'
]
6. 终端中输入python manage.py makemigrations
7. 终端中输入python manage.py migrate
8. 运行一下看看 python manage.py runserver

不得不说,Django做网站确实太轻松了,一旦你掌握它的规则,新建一个功能是非常轻松的。

Django登陆Admin后台错误的解决方案

最近学习使用Django来做网站,但是遇到一个问题,就是无法通过localhost:8000/admin来登陆后台,提示连接错误。但是如果输入错误的用户名的话,会提示你用户名或者密码错误,也就是说你输入正确了,需要跳转的时候就会出问题。在网络上找了不少的解决方案,但是都不能解决我的问题,除了下面这个。

1. 下载pipenv

2. $ pipenv shell

3. (code) $ django-admin startproject emaillogin_project #开始建立一个新的项目

4. (code) $ python manage.py startapp users #开始建立一个新的app, 叫做users

5. 更改项目的设定的文件,也就是setting.py,注意,红色部分就是新增加的

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',

# 3rd party
'allauth',
'allauth.account',
'allauth.socialaccount',

# Local
'users.apps.UsersConfig',
'pages.apps.PagesConfig',

]
# emaillogin_project/settings.py
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

AUTHENTICATION_BACKENDS = (
    # Needed to login by username in Django admin, regardless of `allauth`
    "django.contrib.auth.backends.ModelBackend",

    # `allauth` specific authentication methods, such as login by e-mail
    "allauth.account.auth_backends.AuthenticationBackend",
)

SITE_ID = 1

ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE = False
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_UNIQUE_EMAIL = True
6.(code) $ pipenv install django-allauth #安装这个第三方的插件,我直接pip安装
7. (code) $ python manage.py migrate
8. 项目urls文件里面是这样的。
from django.contrib import admin
from django.urls import path, include # new

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('allauth.urls')), # new
9. 当然还有模块文件夹和模块等等。。。
(code) $ mkdir templates
(code) $ mkdir templates/account
(code) $ touch templates/account/login.html
(code) $ touch templates/account/signup.html
<!-- templates/account/login.html -->
<h2>Log In</h2>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Log In</button>
</form>
<!-- templates/account/signup.html -->
<h2>Sign Up</h2>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Sign Up</button>
</form>
10. (code) $ python manage.py startapp pages #新建页面app
11. 。。。。太多内容了。其实git上有一个代码,下载下来就能用了。 

https://github.com/wsvincent/django-login-with-email

我用了这个代码以后,刚开始也不行,然后admin神奇的就可以用了。以为是电脑的环境变化了,重新新建一个项目,但是还是不能工作,重新用这个代码,然后还是可以使用。

这个代码的好处不仅是解决了后台的问题,同时给了我们一个新用户注册和登陆的解决方案,其他的内容可以在这个基础上增加即可。

ESPHOME通过MQTT发送指令控制ESP8266上面的灯

涉及到几个部分:

1、一个安装了MQTT的服务器,也可以在本机上模拟一个,我用的是https://www.emqx.io/cn/products/broker

2、把程序编译并烧录至ESP8266的模块中。注意API的功能要禁止,不能喝mqtt同时使用

mqtt:
broker: 服务器的IP地址
username: 用户名
password: 密码
discovery: True # 启用主动发现
discovery_prefix: homeassistant # 不设置默认就这个,要和ESPHome的一致

switch:
– platform: gpio
id: “logo_light”
name: “8266light_logo_light”
pin:
number: D0 #LED的正极接D0, 负极接一个GND
# HASS标准格式  状态话题  HASS接收来自设备的状态信息
state_topic: “8266light/switch/8266light_logo_light/state”
# HASS标准格式  命令话题  HASS发送控制设备的命令
command_topic: “8266light/switch/8266light_logo_light/command”

3、在homeassistant中会找到一盏灯。 确保操作开关,EPS8266上的灯会被点亮或者关闭

1577951505(1)

4、登录的MQTT的后台订阅一下8266light/#

1577951361(1)

然后发送消息给8266light/switch/8266light_logo_light/command这个主题,内容是on或者off。一切正常的话,板子上的灯会打开或者关闭

1577951425(1)

5、也可以电脑下载一个MQTT的客户端来做,我用的是MQTTBox,用来测试非常方便,输入on 或者off能起到相同的效果。

http://workswithweb.com/html/mqttbox/downloads.html

1577951849(1)