Raspberry Pi Smart Home

October 5, 2023, 14:09

null

Let me ask you a question about this Node Red. I have to install it on the server. But now I have a temperature sensor and it is not connected to the server Pi 4 but to a pi zero. Do I have to install the Node Red also on the Zero?

k9t33n

how are you connecting it to the pi zero? via gpio pins?

k9t33n

depends how your using it

k9t33n

if the pi 4 is doing the computing power and the pi zero is just listening for inputs on the gpio pins then maybe not

null

Yes according to these instructions I have connected the sensor. https://st-page.de/2018/01/20/tutorial-raspberry-pi-temperaturmessung-mit-ds18b20/ Yes, the zero should only read out the value and pass it on to the pi 4 or the pi 4 should be able to get the value. No matter how you do it. I would like to see the temperatures then as a graph for week and month.

k9t33n

which is doing what?

k9t33n

like I'm guessing the pi zero is controlling the stuff whilst the pi 4 is doing the hard work like deciding which should do what

k9t33n

why not just have the pi 4 control them directly and do the computing?

null

Um currently no one controls anything. I want to measure and record the temperature outside the kitchen window. So the Zero should not control anything, and neither should the pi 4. I need this data only because I can only plant flowers bulbs from a certain temperature. And but a certain temperatures over a certain period, it is time to do something. But both is not done by the computers! Hope you understand what I have in mind?

oops.se

I have a lot of sensors on different devices and I uses MQTT to transport measurements from the devices to a MQTT broker (Mosquitto) on the same Raspberry Pi as I have Node Red installed.

oops.se

And to write a small program that collect data from the sensor and sends it via MQTT is quite easy and there is a lot of tutorials on Internet about it.

null

Quite simply, the Pi4 (server) is in the living room. The Zero is in the kitchen. I don't want to run a cable from the living room through the hallway to the kitchen, so I put the sensor on the Zero.

null

But one more question. If I install the Node Red with docker, do I have to install the mqtt as docker too?

oops.se

Yes

oops.se

Sorry, Yes as, you don't install Mosquitto in the same docker as Node-Red. And "No" you can installit in the docker host.

oops.se

Do you use docker-compose ?

oops.se

Just run ex. a python script that you invoke from cron tab with an interval. No need for a container

oops.se

If you need a docker compose for mosquitto (MQTT broker), let me know

oops.se

One of either Zero or Pi4 can be MQTT Broker (mosquitto). And Yes the: - Sensor publish the value to a topic on the broker (ex. temp/sensor1) - Node Red subscribe to a topic or more (ex. temp/sensor1, temp/sensor2) - Mosquitto is the MQTT broker that collects values that is published to a topic and deliver values when a subscriber ask for a topic. To install the MQTT broker: apt install mosquitto To install the MQTT client: apt install mosquitto-clients And to allow anonymous MQTT clients add allow_anonymous true to mosquitto.conf also add log_dest stdout to save writes to the SD card

null

Ok question has been solved. It won't start without mosquitto, so you have to install both.

oops.se

Ohhh. I was sure that you only needed sudo apt install mosquitto-clients to get the command mosquitto_sub and mosquitto_pub that you uses from the commandline to publish or subscribe to a topic. So that was confusing.

oops.se

Open two terminal windows. Replace 192.168.111.10 with YOUR IP adr. to your MQTT broker. Start a subscriber: mosquitto_sub -h 192.168.111.10 -t "sensors/temp1" Publish something in the first terminal: mosquitto_pub -h 192.168.111.10 -t "sensors/temp1" -m "Test" And a hint, topic is created dynamic the first time someone is publishing. Subscribing to all topics mosquitto_sub -h 192.168.111.10 -t \# -d Some reading: http://www.steves-internet-guide.com/mosquitto_pub-sub-clients/

null

oh wow i made it. Now I see the temperature in a graph. I also installed the whole thing at the place where it should measure. I am curious how the graphic looks tomorrow. Thanks for your help. And yes, later other devices will come, but I have to get a few things first, so that it works.

k9t33n

great

null

Now I have a question after all. The temperature is displayed with 3 decimal places. How can I shorten this to 1 decimal place?
def read_temp_raw():
    f = open(device_file, 'r')
    lines = f.readlines()
    f.close()
    return lines
 
def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000.0
        #temp_f = temp_c * 9.0 / 5.0 + 32.0
        return temp_c#, temp_f
 
while True:
    temp = read_temp()
    if temp is not None:
        publish.single(pub_topic, str(temp),
                hostname=broker, port=1883,
                #auth=auth, tls={}
                )
    break

k9t33n

one second I did this before but forgot

k9t33n

ok got it

k9t33n

py
number = 123.456
shortened_number = round(number, 1)
print(shortened_number)

k9t33n

why do you put float(temp_string) / 1000.0 again?

k9t33n

but yes that should work

null

So I know where I have to add it, so in which place ^^

k9t33n

py
def read_temp_raw():
    f = open(device_file, 'r')
    lines = f.readlines()
    f.close()
    return lines
 
def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000.0
        temp_c = round(temp_c, 1) #it should be here
        #temp_f = temp_c * 9.0 / 5.0 + 32.0
        return temp_c#, temp_f
 
while True:
    temp = read_temp()
    if temp is not None:
        publish.single(pub_topic, str(temp),
                hostname=broker, port=1883,
                #auth=auth, tls={}
                )
    break

k9t33n

should be that

k9t33n

also why do you # out temp_f?

null

I live in Germany and I can't do anything with Fahrenheit πŸ˜…

k9t33n

me neither, so why include it at all?

null

it just said so. And I don't want to remove it in case you need it. And since I currently have to learn a lot and things that I do not often, forget again, I prefer to comment them out before I delete them. πŸ˜†

k9t33n

ok that's fine

k9t33n

I've always looked at you as pretty knowledgeable, are you new to python?

null

To be honest, I still see myself as a complete beginner. I am new to Python, yes. I had a little bit to do in the retraining, but not so much that I could write it completely by myself. Since I need in any case always templates. Unfortunately, I do not have the time to concentrate on individual things at the moment to learn them completely. Because professionally I also have to learn a lot, the retraining has brought very little.

k9t33n

ah I see, well your doing well so far

null

Thanks ☺️

null

<@796000224690307072> Do you have a tip on how I can change the size in the dashboard on Node Red? Everything is displayed so small for me...

oops.se

Hold down the button ctrl and then zoom in/out with the mouse wheel

null

Really only this option? Ok I must probably live with πŸ˜…

oops.se

Well it is a web app, and that is the way to do it in web apps. So if you wish another way, start coding πŸ˜‰

null

I am still years away from programming. It's just stupid when you have a big monitor with high resolution. Apparently most of the designers go by pixels instead of %, which then looks correspondingly tiny on large monitors with high resolution. Well is just so, I have to live with, until I maybe sometime have the time and knowledge to do something myself πŸ˜…

oops.se

I agree, the world is full of less smart people πŸ˜‰ That is like "Smart Home" there is no SMART homes, they are stupid homes that can be automated!

null

Can you help me again. I really have no idea about Python... I would like to give the current date and time to the message that goes from the Zero to the Pi. The reason is: I want to write this data additionally to a file csv or txt, because apparently the data is not saved in general. Or do I not need this at all? The message that comes on looks like this:
 {"topic":"sensors/kitchen","payload":8.7,"qos":0,"retain":false,"_msgid":"d16f4349d152bda7"}
By the way the data should definitely be written to the Pi, because the Zero only has the SD card in it and I want to save it.

k9t33n

do you need to be able to get the date and time in python? I can help you with that

k9t33n

I don't know about sending the payload and stuff but I can help you with getting the date and time and putting it in a variable

null

I found a way to get the date and time, but the problem is that the date and time is a string and the temperature is a float. And unfortunately the publish.single doesn't seem to like it when you have string and float in str. Or I just don't know the way how to insert that there properly.... I tried it with ; and with , and with +, but it only spits out errors.

null

Or just make the temperature a string again and then put it all in the message? Would probably be the easiest?

k9t33n

you can do both

null

YAY I found out πŸ˜„

k9t33n

oh ok

k9t33n

did you convert the temp to a string?

k9t33n

it's just temp = str(temp)if I remember correctly

null

the joke is what I did not know, the temperature was already made string
publish.single(pub_topic, str(temp),
I just needed to add the date string, but didn't know how. But just found out how and like this
publish.single(pub_topic, current_time + str(temp),

k9t33n

good enough

k9t33n

btw to make your code easier to read you can surround it in triple backticks like this: .py then put your code here and another triple backticks. but without the full stops

k9t33n

nvm I can't send it

k9t33n

basically just like this

null

Yes I know that sry I had just forgotten for joy to have found the solution πŸ˜„

k9t33n

it's alright

null

How can I save the data of this display? When I restart the server they are lost...

k9t33n

that's an interesting question

k9t33n

so would it work if they were set in variables for you?

k9t33n

like permanently set in variables?

null

no idea what you mean? I have no idea how the save works in Node Red, that's why I ask ^^

oops.se

Normally you save data to a databaase and uses the data from the database to generate graphs

null

ok this is my compose
version: "3.7"

services:
  node-red:
    image: nodered/node-red:latest
    container_name: node-red
    environment:
      - TZ=Europe/Amsterdam
    ports:
      - "1880:1880"
    volumes:
      - node-red-data:/data
    restart: unless-stopped
    networks:
      - node-red-net

volumes:
  node-red-data:

networks:
  node-red-net:
    external: true
    name: node-red-net
i have no database ^^ I followed this instruction: https://nodered.org/docs/getting-started/docker Can you put a database in there that easily?

oops.se

  db:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root_password
    ports:
      - "3306:3306"
Ref.: https://blog.christian-schou.dk/creating-and-running-a-mysql-database-with-docker-compose/

null

Yes, that was not my point but where in the Node Red part I have to specify the database and how.

oops.se

I haven't done it this way but I think that it fits your needs https://www.youtube.com/watch?v=L4RTrXKXd7M&t=12s

oops.se

Same here, cya

oops.se

Well <@1071178789939331253> that is one way to do it, and I susspect there are like 10 other waays to do it πŸ˜‰

k9t33n

you mean with a variable?

null

I think this is what I need to save the data from the chart permanently. https://nodered.org/docs/user-guide/context#saving-context-data-to-the-file-system

null

I got myself a Pi Pico. However, I do not get further with the statement: TypeError: object of type 'float' has no len() I do not understand what he wants...

null

yay i found it out πŸ˜„ πŸ₯³

oops.se

And that is ?

null

For me temp_1 = float(sensor_ds.read_temp(device)) temp_2 = round(temp_1, 1) temp = str(temp_2) 😁