西维蜀黍

【IoT】米家设备与 Home Assistant 集成

12 Jan 2025 Update: use https://github.com/XiaoMi/ha_xiaomi_home directly as official support

ha_xiaomi_home

ref https://github.com/XiaoMi/ha_xiaomi_home

Useful Tool

python-miio

$ virtualenv mymiio -p python3; cd mymiio/; source bin/activate; pip3 install python-miio

# upgrade python-miio
$ pip3 install python-miio --upgrade   -i https://pypi.python.org/simple

# 探测所有设备
$ mirobo discover --handshake 1

# 连接设备
$ miiocli device --ip 192.168.2.192 --token 8c201e5611a03347ef1f4d30e2dac6f8 info

$ miiocli --help
Usage: miiocli [OPTIONS] COMMAND [ARGS]...

Options:
  -d, --debug
  -o, --output [default|json|json_pretty]
  --version                       Show the version and exit.
  --help                          Show this message and exit.

Commands:
  ...

Reference

  ...


【IoT】Home Assistant 折腾

Config File

# 修改port
http:
  server_port: 8123
  ssl_certificate: '/etc/letsencrypt/live/your server host/fullchain.pem'
  ssl_key: '/etc/letsencrypt/live/your server host/privkey.pem
  
  
# debug
logger:
  default: debug
  ...


【Golang】类型 - Channel

Channel

Channels are type safe message queues that have the intelligence to control the behavior of any goroutine attempting to receive or send on it. A channel acts as a conduit between two goroutines and will synchronize the exchange of any resource that is passed through it. It is the channel’s ability to control the goroutines interaction that creates the synchronization mechanism.

When a channel is created with no capacity, it is called an unbuffered channel. In turn, a channel created with capacity is called a buffered channel.

熟悉Golang的人都知道一句名言:“使用通信(channel)来共享内存,而不是通过共享内存来通信”。这句话有两层意思,Go语言确实在sync包中提供了传统的锁机制,但更推荐使用channel来解决并发问题。

它的操作符是箭头 <-

ch <- v    // 发送值v到Channel ch中
v := <-ch  // 从Channel ch中接收数据,并将数据赋值给v
  ...


【Golang】使用 - 限时调用一个函数(超时退出)

使用 time.After

package main

import (
   "fmt"
   "time"
)

func main() {

   c1 := make(chan string, 1)
   go func() {
      fmt.Printf("before sleep: %v\n", time.Now())
      time.Sleep(2 * time.Second)
      c1 <- "result 1"
      // Never go to here
      fmt.Printf("after sleep: %v\n", time.Now())
   }()

   fmt.Printf("before select: %v\n", time.Now())
   select {
   case res := <-c1:
      fmt.Println(res)
   case <-time.After(1 * time.Second):
      fmt.Println("timeout 1")
   }
   fmt.Printf("after select: %v\n", time.Now())
}

Output:

before select: 2020-11-24 22:57:40.129712 +0800 +08 m=+0.000122644
before sleep: 2020-11-24 22:57:40.129721 +0800 +08 m=+0.000131671
timeout 1
after select: 2020-11-24 22:57:41.13308 +0800 +08 m=+1.003459705
  ...


【Golang】map 并发问题

Problem

If you need to read from and write to a map from concurrently executing goroutines, the accesses must be mediated by some kind of synchronization mechanism. One common way to protect maps is with sync.RWMutex.

package main
func main() {
	m := make(map[int]int)
	go func() {
		for {
			_ = m[1]
		}
	}()
	go func() {
		for {
			m[2] = 2
		}
	}()
	select {}

}

错误信息是: fatal error: concurrent map read and map write

  ...