pihome-shc / pihome

PiHome - Smart Heating, Ventilation and Air Conditioning (HVAC)
http://www.pihome.eu
Other
52 stars 25 forks source link

Sonoff #324

Open twa127 opened 3 years ago

twa127 commented 3 years ago

Hi,

I'm playing around with the Sonoff as a dirt cheap mains switch add-on and thought I'd see what you think of the approach:-)

  1. These things are cheap, less than 10GBP on Amazon
  2. No way could you build anything for less
  3. ESP8266 based
  4. Can be easily hacked to work on the local network (bypassing the cloud based default setup)

Integration into PiHome

  1. Did not want the hassle or overhead of using MQTT, just wanted a controller node to use in the usual way
  2. Flashed the Tasmota firmware to enable HTTP control
  3. Created a new type of node called it Virtual
  4. Allocated a node ID
  5. Allocated a child_id which represents the last part of the IP address, this way a single virtual node could have a number of Sonoffs attached
  6. Modified the gateway script to capture the local IP address and POST ON/OFF status to the virtual node based on the payload and child_id of the message_out
  7. Captured the response from the Sonoff and set message_out.sent if okay

Downside is required a connection the the local network

Any thoughts :-))))

pihome-shc commented 3 years ago

@twa127 yes i agree, no one can build this cheap controller and they also have 1 relay 2 and 4. i have one relay module i bought for 5 euro i think while it was on sale. i agree MQTT is overhead but i think MQTT is the way to go and not only it cover huge amount of devices but also make PiHome compatible with industry standards, @dvdcut have done some basic work in #250 but that is just basic MySensors MQTT gateway sensors. On other hand using ip address have some issues. You have to have same network subnet in your place. if you have multiple subnet (which i have) then discovery is not going to work. second if ip address changes after reboot you need to manually change the ip address of node or some discovery process needs be initiated to establish connection again back to multi subnet. We can add ip compatible controllers and sensors.

aszumski commented 3 years ago

@twa127 this looks like great piece of hardware. Exactly what I was looking for. Will order couple of them from amazon to play around with them soon :) You can go cheaper with esp01 relay boards from aliexperss (around 2 euro), but then you need power supply and enclosure, so you will end up with similar price and not as compact/nice. If you don't mind waiting for delivery you can get 3 pack of those sonoff switches for 16 quid on ali.

twa127 commented 3 years ago

Hi,

See your point BUT for me MQTT is going to be too much of an overhead on the already hard pushed PiHome controller and I I don't particularly want to have to run and maintain another controller for the MQTT server.

I can see the issue with multiple subnets, the use of either use static IPs or router reservations to make sure of consistent ip address.

This approach is relatively simple and also works out-of-the box with voice control

There is also another device the Shelley 1 which would work the same way, this device is tiny and could fit behind a standard light switch

dvdcut commented 3 years ago

@twa127 i have one subnet at home so it wouldn't be a problem for people with one subnet, may be we can customize sketch for sonoff and other esp based relay boards to make them to look for pihome instead pihome looking for controller but on same time pihome can control status of these devices.

i know i have worked on mqtt but i m not sure if i can finish that work as my knowledge of python is extremely limited and there so much google can answer to get that finished.

twa127 commented 3 years ago

My start point was looking at customizing an existing sketch and letting it create a node, but decided it was too difficult with the ESP8266, tying to make some kind of handshake ACK to indicate the ESP8266 had received the message. So I decided to come at it from the other side, a bit like the I2C relay controller and manually create a virtual node with a tiny bit of code in the gateway script to hand the virtual node. It does work but am fully open to other suggestions, the gateway code is below:

import requests import socket, re

Get the local ip address

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(('google.com', 0)) ip = s.getsockname()[0] base_ip = re.search('^[\d]{1,3}.[\d]{1,3}.[\d]{1,3}.', ip) . . . . . .

Outgoing messages

            con.commit()
            cur.execute('SELECT COUNT(*) FROM `messages_out` where sent = 0') # MySQL query statement
            count = cur.fetchone() # Grab all messages from database for Outgoing.
            count = count[0] # Parse first and the only one part of data table named "count" - there is number of records grabbed in SELECT above
            if count > 0: #If greater then 0 then we have something to send out.
                    cur.execute('SELECT * FROM `messages_out` where sent = 0') #grab all messages that where not send yet (sent ==0)
                    msg = cur.fetchone();   #Grab first record and build a message: if you change table fields order you need to change following lines as well.
                    out_id = int(msg[0])    #Record ID - only DB info,
                    out_node_id = msg[3]    #Node ID
                    out_child_id = msg[4]   #Child ID of the node where sensor/relay is attached.
                    out_sub_type = msg[5]   #Command Type
                    out_ack = msg[6]                #Ack req/resp
                    out_type = msg[7]               #Type
                    out_payload = msg[8]    #Payload to send out.
                    sent = msg[9]                   #Status of message either its sent or not. (1 for sent, 0 for not sent yet)
                    cur.execute('SELECT type FROM `nodes` where node_id = (%s)', (out_node_id, ))
                    nd = cur.fetchone();
                    node_type = nd[0]
                    if dbgLevel >= 1 and dbgMsgOut == 1: # Debug print to screen
                            print(bc.grn + "\nTotal Messages to Sent:      ",count, bc.ENDC) # Print how many Messages we have to send out.
                            print("Date & Time:                 ",time.ctime())
                            print("Message From Database:       ",out_id, out_node_id, out_child_id, out_sub_type, out_ack, out_type, out_payload, sent) #Print what will be sent includ$
                    msg = str(out_node_id)  #Node ID
                    msg += ';'                              #Separator
                    msg += str(out_child_id) #Child ID of the Node.
                    msg += ';'                              #Separator
                    msg += str(out_sub_type)
                    msg += ';'                              #Separator
                    msg += str(out_ack)
                    msg += ';'                              #Separator
                    msg += str(out_type)
                    msg += ';'                              #Separator
                    msg += str(out_payload) #Payload from DB
                    msg += ' \n'                    #New line
                    if dbgLevel >= 3 and dbgMsgOut == 1:
                            print("Full Message to Send:        ",msg.replace("\n","\\n")) #Print Full Message
                            print("Node ID:                     ",out_node_id)
                            print("Child Sensor ID:             ",out_child_id)
                            print("Command Type:                ",out_sub_type)
                            print("Ack Req/Resp:                ",out_ack)
                            print("Type:                        ",out_type)
                            print("Pay Load:                    ",out_payload)
                            print("Node Type:                   ",node_type)
                    # node-id ; child-sensor-id ; command ; ack ; type ; payload \n
                    if node_type.find("Virtual") == -1: # process normal node
                            if gatewaytype == 'serial':
                                    gw.write(msg.encode('utf-8')) # !!!! send it to serial (arduino attached to rPI by USB port)
                            else:
                                    print('write')
                                    gw.write(msg.encode('utf-8'))
                            cur.execute('UPDATE `messages_out` set sent=1 where id=%s', [out_id]) #update DB so this message will not be processed in next loop
                            con.commit() #commit above
                    else:
                            # process the Sonoff device HTTP action
                            url = 'http://' + base_ip.group(0) + str(out_child_id) + '/cm'
                            if out_payload.find('1') != -1:
                                    myobj = {'cmnd': 'Power ON'}
                                    test_str = 'ON'
                            else:
                                    myobj = {'cmnd': 'Power OFF'}
                                    test_str = 'OFF'

                            x = requests.post(url, data = myobj) # send request to Sonoff device
                            if x.status_code == 200:
                                    if (x.json().get("POWER")).find(test_str) != -1: # clear send if response is okay
                                            print(x.text)
                                            cur.execute('UPDATE `messages_out` set sent=1 where id=%s', [out_id])
                                            con.commit() #commit above

    ## Incoming messages
pihome-shc commented 3 years ago

@twa127, can you share sketch as well, i will try to use spare esp for this testing, my multiple subnet system may be unique but lets not stop your idea, adding ip based nodes wouldn’t hurt anything.

twa127 commented 3 years ago

Attached the gateway script, Sonoff loaded with the latest tasmota build, configured as a Sonoff Basic and manually added an new entry to the nodes table. Add a new Lamp type Add-On zone, so able to toggle the Sonoff from the PiHome GUI

virtual

gateway.zip

pihome-shc commented 3 years ago

@twa127 how id is handled for esp with tasmota ?

twa127 commented 3 years ago

Hi,

Everything you need is in this video https://www.youtube.com/watch?v=08_GBROKQH0

tasmota.bin can be found at http://thehackbox.org/tasmota/release/ or http://github.com/arendst/Sonoff-Tasmota/releases

PyFlasher can be found at https://github.com/marcelstoer/nodemcu-pyflasher/releases

I used a WeMos Mini board I had lying around to do the development, any ESp8266 board will do, you don't need a Sonoff to have a play around

twa127 commented 3 years ago

Tasmota is not the only way to go, an alternative is EspEasy https://www.letscontrolit.com/wiki/index.php/ESPEasy which can be used in the same way via HTTP

twa127 commented 3 years ago

I had a look at the static IP address issue and it can be handled in two ways, on the router by reserving an IP address using the devices MAC address, or by using the Tasmota WEB console.

dvdcut commented 3 years ago

@twa127 i manage to write bin file http://thehackbox.org/tasmota/release/tasmota.bin to my esp8266 and all worked ok apart from it gave me only 4 gpio, am i doing something wrong?

twa127 commented 3 years ago

Have a look at https://www.youtube.com/watch?v=08_GBROKQH0 the bit you need is about 7 minutes in

twa127 commented 3 years ago

when loading the bin file to a Sonoff mine worked without having to do anything

twa127 commented 3 years ago

Hi

I'd like to save the local network gateway address somewhere in the database rather than have to retrieve it from system, perhaps in the system table. Any thoughts ?

pihome-shc commented 3 years ago

@twa127 system table can be used but i suggest to crate another table for network related config i.e network_setting may be in future we can implement static ip from database, what do you think?

twa127 commented 3 years ago

founds good to me, okay if I work on it?

pihome-shc commented 3 years ago

Yes, sure. I will try my nodemcu dev board for testing this tomorrow.

twa127 commented 3 years ago

Hi,

I'm currently using 'Virtual' as the node.type for the Sonoff device, I did this as I initially thought that the same process could be used for other add-ons, but as I'm using HTTP requests which are specific to the Sonoff (or more correctly to the Tasmota firmware), I think it would be better to use 'Tasmota' as the node.type. Any thoughts ?

pihome-shc commented 3 years ago

I think using tasmota is better option, we could have another type of http nodes in future.

From: twa127 notifications@github.com Sent: Monday 20 July 2020 10:52 To: pihome-shc/pihome pihome@noreply.github.com Cc: PiHomeHVAC info@pihome.eu; Comment comment@noreply.github.com Subject: Re: [pihome-shc/pihome] Sonoff (#324)

Hi,

I'm currently using 'Virtual' as the node.type for the Sonoff device, I did this as I initially thought that the same process could be used for other add-ons, but as I'm using HTTP requests which are specific to the Sonoff (or more correctly to the Tasmota firmware), I think it would be better to use 'Tasmota' as the node.type. Any thoughts ?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/pihome-shc/pihome/issues/324#issuecomment-660926844 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AH6KHWHNXEZ6GBCMUFMB4H3R4QHVHANCNFSM4OZR4YZA . https://github.com/notifications/beacon/AH6KHWG2ANIRBRE6FVYCQOLR4QHVHA5CNFSM4OZR4YZKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOE5SPC7A.gif

twa127 commented 3 years ago

Okay changes committed

twa127 commented 3 years ago

A first go at a Sonoff user guide Using the Sonoff Basic with PiHome.zip

pihome-shc commented 3 years ago

@twa127 great work, can i publish this one website?

twa127 commented 3 years ago

only a first draft but feel free :-)

harvybob commented 3 years ago

Hey, this is looking interesting - is there any way to include the temperature and humidity sensors?

twa127 commented 3 years ago

Hi,

Are you thinking of something like the Sonoff TH16, if so I don't see why not, it only requires processing additional HTTP commands but if you are not going to uses the mains voltage switching capability, then I would have thought a MySensors option was a better way to go.

harvybob commented 3 years ago

I was thinking of the Sonoff TH16, but i will have a look at the My Sensors option. I have a sensor in the bathroom behind tiles thats died, so cant replace and now cant monitor the room!

harvybob commented 3 years ago

Also is there any way to pulse the switching for sonoff? My fish tank has a silly light - if its just switched on, its white. If its switched on, off and then on, its blue+ white. If its switched on, off, on, off and then on, its just blue...

Looking for a way to set this up on timer so blue comes on for a while at say 6 am, blue/white at 7am, white at 8, and then the reverse for 7pm, 8pm 9pm etc...

This way i can loop in the fish tank temp, and lights into pihome - one interface for everything :)

twa127 commented 3 years ago

anything is possible :-) its a kind of schedule activity but with a startup sequence, the PiHome scheduling is built around on/off timers, there is currently no repeat sequencing

twa127 commented 3 years ago

Worth looking at the Tasmota command set, there is a 'PulseTime' command which perhaps could be used with the 'Backlog' command to send the sequence of on/off commands you need. At the moment the HTTP commands are hard coded in gateway.py as I'm only using 'POWER ON' or 'POWER OFF', this would need to change and perhaps use the payload of messages_out (just thinking out loud)

twa127 commented 3 years ago

I've made a change to use the Sonoff HTTP command message text as the message_out payload, rather than using '1' for ON and '0' for 'OFF'

The eventual goal if to be able to make more use of the Tasmota command set.

twa127 commented 3 years ago

Hi,

I've implemented a table for the Sonoff HTTP messages with an associated GUI. The idea is that we can (perhaps) exploit more of the Tasmota firmware capabilities for things like @harvybob fish tank :-) I've only tested with the basic POWER command so far.

Attached an updated user guide Using the Sonoff Basic with PiHome.zip

pihome-shc commented 3 years ago

@twa127 this is great work, i been busy working on PiConnect. but this is great addition to PiHome. Appreciate your hard work

twa127 commented 3 years ago

User guide update Using the Sonoff Basic with PiHome.zip

pihome-shc commented 3 years ago

@twa127 after recent pull request, gui is still the same for me, dependent on boiler.php

twa127 commented 3 years ago

Hi

If you look at the code lines 435 to 445 in homelist.php the call to getIndicators($conn, $add_on_mode, $zone_temp_target) uses the locally determined $add_on_mode so can't see why it is waiting for boiler.php

twa127 commented 3 years ago

by the way the change only works for the home screen button, the Sonoff button still has to wait to be polled by boiler.php

twa127 commented 3 years ago

Oops I forgot a couple of changes in the last commit, posting an update

twa127 commented 3 years ago

can you let me know if this works better now

pihome-shc commented 3 years ago

@twa127 yes that worked perfectly

twa127 commented 3 years ago

great

pihome-shc commented 3 years ago

@twa127 have you tried wifi thermostat, these comes with esp chip

twa127 commented 3 years ago

Look interesting, I'll did a bit deeper

scottagecheeseandcrackers commented 3 years ago

Just a thought... I have a pihome zone set up for my child's bedroom. I also have a Sonoff s20 in the same room with a fan connected. I have set up a simple action in Node-red to query the zone temp every 30 minutes and turn in the fan if the temp exceeds a set value. And vice versa when the lower threshold is reached.

My plan is flash the S20 with tasmota.

If I set this device in pihome in tasmota, could I set up a night climate to trigger the tasmota device? Basically a low cost cooling setup.

@twa127 - building off your great work in this feature...

twa127 commented 3 years ago

Hi,

Never used the night climate feature but if you create a new zone type 'Fan' as a category 1 type and then setup a new zone using the relevant sensor and a Tasmota controller could that do what you want if you configure a night climate schedule for the new zone