Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miscellanous updates #5

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
simple.py
flash_nuke.uf2
RPI_PICO_W-20240222-v1.22.2.uf2
55 changes: 55 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
PICO_RST=https://datasheets.raspberrypi.com/soft/flash_nuke.uf2
MP=https://micropython.org/resources/firmware/RPI_PICO_W-20240222-v1.22.2.uf2
UMQTT=https://github.com/micropython/micropython-lib/raw/master/micropython/umqtt.simple/umqtt/simple.py

all: deploy

$(shell basename $(PICO_RST)):
curl -O $(PICO_RST)

$(shell basename $(MP)):
curl -O $(MP)

$(shell basename $(UMQTT)):
curl -LRJO $(UMQTT)

.PHONY: dependencies
dependencies: $(shell basename $(PICO_RST)) $(shell basename $(MP)) $(shell basename $(UMQTT))

.PHONY: deploy
deploy: dependencies
cp $(shell basename $(PICO_RST)) /run/media/per/RPI-RP2

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cp $(shell basename $(PICO_RST)) /run/media/per/RPI-RP2
cp $(shell basename $(PICO_RST)) /media/$(USER)/RPI-RP2

sleep 15
cp $(shell basename $(MP)) /run/media/per/RPI-RP2

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cp $(shell basename $(MP)) /run/media/per/RPI-RP2
cp $(shell basename $(MP)) /media/$(USER)/RPI-RP2

sleep 5
# upgrade version string so we can follow we run the latest...
before=$$(cat main.py | grep ^version | cut -d\" -f2) ;\
sed -i s/^version.*/version\ =\ \"$$(($$before+1))\"/g main.py
grep ^version main.py
mpremote cp config.py :config.py
mpremote cp boot.py simple.py obis.py :
mpremote cp main.py :

.PHONY: redeploy
redeploy:
mpremote bootloader
sleep 4
make deploy

.PHONY: unit-test
unit-test:
sudo stty -F /dev/ttyUSB0 raw

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the path here depends on you operating system and slot selected

sudo stty -F /dev/ttyUSB0 -echo -echoe -echok
sudo stty -F /dev/ttyUSB0 115200
sudo stty -F /dev/ttyUSB0
while true; do cat unit-test/example.msg.crlf >> /dev/ttyUSB0; sleep 10; done

.PHONY: mqtt-viewer
mqtt-viewer:
sub --auto-reconnect \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall it be mqttcli sub --auto-reconnect ? Were is the mqttcli downloaded, multiple variants exists :)

--broker tcp://$$(grep MQTTHost config.py.home | cut -d\' -f2):1883 \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
--broker tcp://$$(grep MQTTHost config.py.home | cut -d\' -f2):1883 \
--broker tcp://$$(grep MQTTHost config.py | cut -d\' -f2):1883 \

--topic $$(grep MQTTTopic config.py.home | cut -d\' -f2)/#

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
--topic $$(grep MQTTTopic config.py.home | cut -d\' -f2)/#
--topic $$(grep MQTTTopic config.py | cut -d\' -f2)/#


.PHONY: clean
clean:
$(RM) $(shell basename $(PICO_RST)) $(shell basename $(MP)) $(shell basename $(UMQTT))
112 changes: 95 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,109 @@ Sätt ett pull upp motstånd på omkring 3 Kohm mellan 7 (UART1 Rx) 36 (3,3V) p
![bild2](bilder/schema.png)

## Mjukvara
Installera micropython och mpremote
* https://micropython.org/download/rp2-pico-w/
* https://docs.micropython.org/en/latest/reference/mpremote.html
Installationen är automatiserad i Makefile med en deploy regel.
Anslut picon till host samtidigt som BOOTSEL är nedtryckt och kör sedan deploy:

Modifiera `config.py`så innehållet passar ditt nätverk.
kopiera `config.py` till picon med `mpremote.py cp config.py :config.py`

Installera paketet umqtt.simple med följande
```python
import mip
import network
import config
```
per@home:~/fs/data/projects/el-mätare/picowhanport$ time make deploy
cp flash_nuke.uf2 /run/media/per/RPI-RP2
sleep 15
cp RPI_PICO_W-20240222-v1.22.2.uf2 /run/media/per/RPI-RP2
sleep 5
# upgrade version string so we can follow we run the latest...
before=$(cat main.py | grep ^version | cut -d\" -f2) ;\
sed -i s/^version.*/version\ =\ \"$(($before+1))\"/g main.py
grep ^version main.py
version = "4"
mpremote cp config.py.home :config.py
cp config.py.home :config.py
mpremote cp boot.py simple.py obis.py :
cp boot.py :
cp simple.py :
cp obis.py :
mpremote cp main.py :
cp main.py :
```

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(config.SSID, config.PSK)
## debug hjälpmedel

mip.install("umqtt.simple")
### mqtt-viewer
Installera paketet "mqttcli" och kör sedan "make mqtt-viewer" så visas de mqtt meddelanden
som picon publicerar :
```
per@home:~/fs/data/projects/el-mätare/picowhanport$ make mqtt-viewer
sub --auto-reconnect \
--broker tcp://$(grep MQTTHost config.py.home | cut -d\' -f2):1883 \
--topic $(grep MQTTTopic config.py.home | cut -d\' -f2)/#
2024/03/28 16:53:00 subscribed: electric-meter/main/#
2024/03/28 16:53:00 connected: tcp://192.168.10.10:1883
2024/03/28 16:53:19 [electric-meter/main/P1mqttID] P1mqtt-e661ac8863429b21
2024/03/28 16:53:19 [electric-meter/main/debug/version] 4
```

kopiera `boot.py` och `main.py` till picon med mpremote
### "torrkörning"
Vid programutveckling kan det vara behjälpligt att slippa springa fram och tillbaka
mellan dator och elskåp... då går det att sätta variabeln "unittest" till 1 så läses
från en referens fil istället för från serieporten.

## Installation i elskåpet
koppla in picon till din elmätares HAN port med en rak (altså pin 1 går till pin 1 o.s.v) RJ-12 kabel. LED'en blinkar med omkring 2 Hz medan picon försöker koppla sig till WLAN. När den är uppkopplad lyser den med fast sken men släcks en kort stund för varje gång den får data från elmätaren som skickas till MQTT brokern. Denna släckning skall ske var tionde sekund. Hade det varit en fyr så hade den haft karaktären `Oc 10s`

### komponentlista
### exempel på data

```
per@home:~/fs/data/projects/el-mätare/picowhanport$ make mqtt-viewer | tee unit-test/example.mqttlog
sub --auto-reconnect \
--broker tcp://$(grep MQTTHost config.py.home | cut -d\' -f2):1883 \
--topic $(grep MQTTTopic config.py.home | cut -d\' -f2)/#
2024/03/28 16:56:01 connected: tcp://192.168.10.10:1883
2024/03/28 16:56:01 subscribed: electric-meter/main/#
2024/03/28 16:57:00 [electric-meter/main/P1mqttID] P1mqtt-e661ac8863429b21
2024/03/28 16:57:00 [electric-meter/main/debug/version] 4
2024/03/28 16:57:01 [electric-meter/main/model] LGF5E360
2024/03/28 16:57:01 [electric-meter/main/1-0:1.8.0] 14697.126
2024/03/28 16:57:01 [electric-meter/main/0-0:1.0.0] 240328165700
2024/03/28 16:57:01 [electric-meter/main/1-0:2.8.0] .056
2024/03/28 16:57:01 [electric-meter/main/1-0:3.8.0] .547
2024/03/28 16:57:01 [electric-meter/main/1-0:4.8.0] 668.432
2024/03/28 16:57:01 [electric-meter/main/1-0:2.7.0] .000
2024/03/28 16:57:01 [electric-meter/main/1-0:3.7.0] .000
2024/03/28 16:57:01 [electric-meter/main/1-0:1.7.0] .869
2024/03/28 16:57:01 [electric-meter/main/1-0:41.7.0] .192
2024/03/28 16:57:01 [electric-meter/main/1-0:22.7.0] .000
2024/03/28 16:57:01 [electric-meter/main/1-0:21.7.0] .278
2024/03/28 16:57:01 [electric-meter/main/1-0:42.7.0] .000
2024/03/28 16:57:01 [electric-meter/main/1-0:4.7.0] .131
2024/03/28 16:57:01 [electric-meter/main/1-0:62.7.0] .000
2024/03/28 16:57:01 [electric-meter/main/1-0:61.7.0] .398
2024/03/28 16:57:01 [electric-meter/main/1-0:23.7.0] .000
2024/03/28 16:57:01 [electric-meter/main/1-0:24.7.0] .057
2024/03/28 16:57:01 [electric-meter/main/1-0:44.7.0] .028
2024/03/28 16:57:01 [electric-meter/main/1-0:43.7.0] .000
2024/03/28 16:57:01 [electric-meter/main/1-0:63.7.0] .000
2024/03/28 16:57:01 [electric-meter/main/1-0:64.7.0] .046
2024/03/28 16:57:01 [electric-meter/main/1-0:52.7.0] 226.4
2024/03/28 16:57:01 [electric-meter/main/1-0:32.7.0] 226.5
2024/03/28 16:57:01 [electric-meter/main/1-0:31.7.0] 1.2
2024/03/28 16:57:01 [electric-meter/main/1-0:72.7.0] 226.1
2024/03/28 16:57:01 [electric-meter/main/1-0:51.7.0] .8
2024/03/28 16:57:01 [electric-meter/main/1-0:71.7.0] 1.7
2024/03/28 16:57:11 [electric-meter/main/0-0:1.0.0] 240328165710
2024/03/28 16:57:11 [electric-meter/main/1-0:4.8.0] 668.433
2024/03/28 16:57:11 [electric-meter/main/1-0:1.8.0] 14697.128
2024/03/28 16:57:11 [electric-meter/main/1-0:41.7.0] .193
2024/03/28 16:57:11 [electric-meter/main/1-0:32.7.0] 226.2
2024/03/28 16:57:11 [electric-meter/main/1-0:44.7.0] .027
2024/03/28 16:57:11 [electric-meter/main/1-0:72.7.0] 226.0
2024/03/28 16:57:11 [electric-meter/main/1-0:52.7.0] 226.5
2024/03/28 16:57:20 [electric-meter/main/0-0:1.0.0] 240328165720
2024/03/28 16:57:20 [electric-meter/main/1-0:1.8.0] 14697.131
2024/03/28 16:57:20 [electric-meter/main/1-0:41.7.0] .900
2024/03/28 16:57:20 [electric-meter/main/1-0:1.7.0] 1.577
```


## komponentlista
Detta är de delar jag använt i bygget, man kan naturligtvis köpa motsvarande någon annanstans. Du behöver också en tång för att klämma modularkontakterna.

* https://www.electrokit.com/produkt/modularkontakt-6-6/
Expand Down
9 changes: 5 additions & 4 deletions config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
SSID = '<yourSSID>'
PSK = '<yourPSK>'
MQTTHost = '<yourMQTTHost>'
MQTTTopic = 'exampletopic/data'
ID = 'P1mqtt-'
SSID = '<SSID>'
PSK = '<PSK>'
MQTTHost = '<IP to mqtt server>'
MQTTTopic = 'electric-meter/main'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybee add user and password for the MQTT client?

9 changes: 9 additions & 0 deletions install-umqtt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import mip
import network
import config

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(config.SSID, config.PSK)

mip.install("umqtt.simple")
128 changes: 108 additions & 20 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,37 @@
import time
import gc
import machine
import sys
import config
import ubinascii
from machine import UART
from machine import Pin
from umqtt.simple import MQTTClient
from machine import WDT
from simple import MQTTClient
from obis import *

def DebugPrint(topic, txt):
mqc.publish(str.encode(config.MQTTTopic + '/debug/' + topic), str.encode(txt))

uart = UART(1, baudrate=115200, invert=UART.INV_RX, rx=Pin(5), timeout=11000)
unittest = 0

if unittest:
try:
uart = open("example.msg.crlf", "rb")
except:
print('Please do "mpremote cp unit-test/example.msg.crlf :"')
sys.exit(-1)
else:
uart = UART(1, baudrate=115200, invert=UART.INV_RX, rx=Pin(5), timeout=11000)

led = machine.Pin("LED", machine.Pin.OUT)
led.on()

network.hostname('HANmeter')
version = "6"

hostname = config.ID + ubinascii.hexlify(machine.unique_id()).decode()

network.hostname(hostname)
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(config.SSID, config.PSK)
Expand All @@ -28,36 +47,105 @@
led.off()
machine.reset()

#led on when connected to wlan
# led on when connected to wlan
led.on()
print("WIFI CONNECTED")
mqc = MQTTClient("HANMeter", config.MQTTHost, 1883)

mqc = MQTTClient(hostname, config.MQTTHost, 1883)
try:
mqc.connect()
except:
machine.soft_reset()
print("MQTT CONNECTED")
print('error')
#machine.reset()

mqc.publish(str.encode(config.MQTTTopic + '/P1mqttID'), str.encode(hostname))
DebugPrint('version', version)

workbuffert = bytearray(1024)
mv = memoryview(workbuffert)
PublishedModel = b''

s = b''
MeterModel = b''

#wdt = WDT(timeout=8000)
a = 0
while True:
mvpos=0
s = uart.readline()
while s[0] != ord('/'):
if unittest:
a += 1
if a > 3:
sys.exit(0)

if unittest:
DebugPrint('log', 'search start of frame')

# Sync in to start of frame, "/<meter model>"
while True:
s = uart.readline()
#print("NEW HAN PACKAGE")
if (s != None) and (s[0] == b'/'[0]):
MeterModel = s[1:].split(b'\r\n')[0]
mv[mvpos : mvpos+len(s)] = s
mvpos += len(s)
break

mv[mvpos : mvpos+len(s)] = s
mvpos += len(s)
led.off()
while s[0]!= ord('!'):
if s == None:
continue

if unittest:
DebugPrint('log', 'frame found')
DebugPrint('log', ' reading data...')

while True:
s = uart.readline()
if s[0] == b'!'[0]:
mv[mvpos] = ord('!')
mvpos += 1
msgcrc = s[1:].split(b'\r\n')[0]
break
mv[mvpos : mvpos+len(s)] = s
mvpos += len(s)
try:
mqc.publish(config.MQTTTopic,workbuffert[0:mvpos])
except:
machine.soft_reset()

led.off()

if unittest:
DebugPrint('log', ' calculating crc')

# Verify CRC
calculatedcrc = OBIS_crc(workbuffert[0:mvpos])
framecrc = int(msgcrc.decode(),16)
if framecrc != calculatedcrc:
DebugPrint('log', 'CRC ERROR')
time.sleep(2)
gc.collect()
led.on()
#wdt.feed()
continue

if MeterModel != PublishedModel:
PublishedModel = MeterModel
mqc.publish(str.encode(config.MQTTTopic + '/model'), PublishedModel)

for p1msg in workbuffert.split(b'\r\n'):
if len(p1msg) == 0:
continue
if p1msg[0] >= b'0'[0] and p1msg[0] <= b'9'[0]:
obis = p1msg.split(b'(')[0]
if obis == b'0-0:1.0.0':
value = p1msg.split(b'(')[1].split(b'W')[0].lstrip(b'0')
else:
value = p1msg.split(b'(')[1].split(b'*')[0].lstrip(b'0')
if value[0] == b'.'[0]:
value = b'0' + value
if value != OBIS_db[obis.decode()][1]:
try:
mqc.publish(str.encode(config.MQTTTopic + '/' + obis.decode()), value)
except:
machine.reset()
OBIS_db[obis.decode()][1] = value

if unittest:
uart.seek(0)

gc.collect()
led.on()
led.on()
#wdt.feed()
Loading