your script works, Thank you !
-
MOD-Bus Plugin
-
Can you help to create a new script ?
Problem is: I have an Modbus adress which needs to be calculates but it´s depended on many state swiches.e.g.: I have 6 rooms every room has it´s own switch. Every switch belongs to ONE Modbus Adress, but the Value depence on the calculation of every state.
So switch 4 is on, and switch 6 but every other switch is OFF, binary code is: 101000, decimal = 40.
We write in an decimal case, so we have to SAFE every switch state and calculate the code AND send it to the Master.any Idea in Python ?
-
I might be able to help, but at this moment I simply don’t understand it. I have no knowledge whatsoever about modbus. I did some reading but it is a very broad range of possibilities and technical implementations.
You mention that it’s one Modbus address but the value is changing. Can you please copy the lines from the script and show (some of) the possible options?
-
okay, so i try to explain the “way” it should work:
First, we need the State of the register with:
data = instrument.read_register(302, 0)
we got this result DECIMAL value,
so with this decimal result we know the SATE of every 6 rooms.
for example we have the value "40"
now we have to CONVERT the decimal value to BINARY
the result ist:
101000What we can read is: Room 4 and 6 is ON.
Now we want to turn ROOM 5 on, and let room 4 and 6 as they are.
The result ist:
111000Now convert the Binary back to decimal, and we have a result of:
56all we have to do is:
instrument.write_register(301, data, 0, 6)
data = 56 (as an example)
and we are finished.in conclusion, all we have to do is:
Read value -> convert Value to binary -> add or remove the bit, -> convert back to decimal -> write register back -
Ok i think i got it,… I have to test it when i´m at home…
This is to set ROOM 5 ON
#!/usr/bin/env python import minimalmodbus import serial import time instrument = minimalmodbus.Instrument('/dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0', 1) # port name, slave address (in decimal) #instrument.serial.port # this is the serial port name instrument.serial.baudrate = 9600 # Baud instrument.serial.bytesize = 8 instrument.serial.parity = serial.PARITY_EVEN instrument.serial.stopbits = 1 instrument.serial.timeout = 1 #minimalmodbus.CLOSE_PORT_AFTER_EACH_CALL=True instrument.address = 10 # this is the slave address number instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode data = instrument.read_register(302, 0) # read state of all switches maske = 16 #room 5 has an decimal value of 16 data2 = data | maske # calculate both print data2 time.sleep(2) instrument.write_register(301, data2, 0, 6) # write back to master time.sleep(2) print int(data2) # show state
-
Now I understand. I will have a look this weekend.
One thing though: you also need variables on pimatic side for all the switch statuses, and a rule (or rules) to check those statuses.
What is your plan/approach to do that? -
@Harry-van-der-Wolf
in my case i want to control “PTC- registers”these are heating-registers in the wall, so there are 3 things to work with:
first i want to SET FREE all the registers that i want with dummy switches in pimatic - ON -> allowed - OFF -> not allowed.
THEN,
i will create a dummypresent device, to know if the heating-registers are WORKING. in this case, i have to check e.g. every minute the result of another modbus register and calculate the correct value to set the dummypresent device as presence or absend.
-
I have again lost you completely.
What do you mean with “ON -> allowed” etc?And what do you mean with " the dummypresent device as presence or absend."?
presence = ON? absend = OFF?
or do you mean with absend that you can’t detect the switch, so some sort of error? -
Exactly. Present. Absent off.
It is hard to explain… Becaise i have a master which controlls the heating registers. This is why i need a switch which dies ‘allow’ the PTC to work in an specific rule which i dont care in pimatic.
I just want to turn in the SET FREE switch then the master later will turn in itself.So Ehen the PTC is in i want to See it via dummypresence device. Got it ?
-
I still don’t understand it completely.
With regard to your your first question:
"e.g.: I have 6 rooms every room has it´s own switch. Every switch belongs to ONE Modbus Adress, but the Value depence on the calculation of every state.So switch 4 is on, and switch 6 but every other switch is OFF, binary code is: 101000, decimal = 40.
We write in an decimal case, so we have to SAFE every switch state and calculate the code AND send it to the Master."That’s easy but alo requires 12 buttons (on/off) 6 variables (switchstates) and 6 or 12 rules. These 6 variables will be “pushed” to the scipt to build the decimal/binary “mask”.
But I still don’t understand the link to that question and the rest of the PTC-registers.
-
The problem is not to configure pimatic or the rules itself.
It is more to build the scripts for the binary/decimal conversation. -
The building of the script is not a problem for me. And neither is the conversion of decimal to binary or the other way round.
If you send the 6 switch state variables as parameters (0 or 1 for off and on) to the script, it is a simple calculation for switch 1 to 6 ofdecimal_value = switch_state1*2^0 + switch_state2*2^1 +....+ switch_state6*2^5
(pseudo code).But I still don’t understand what to do before sending out the data to the master.
-
Now I’m running into big Trouble!
The problem is pimatic is running the python shell scripts simultaneously. So there are many collisions on the MOD-Bus.
The wright way is to send a request and wait for the slave to answer. But sometimes another script is started by pimatic at the same time.
I cannot imagine how this is possible, because Linux always writes the serial interfaces “in use” to the /var/lock - directory?!Anyone an idea how to configure pimatic Shell-script plugin not to run simultaneously?
-
@heinleinm said:
Anyone an idea how to configure pimatic Shell-script plugin not to run simultaneously
I don’t think this is supported. You need to implement synchronization (e.g., a chaining of requests) as part of your python script.
"It always takes longer than you expect, even when you take into account Hofstadter's Law.", Hofstadter's Law
-
i have a similar problem, but this doesn´t happen very often, i am thinking to build a ERROR detection, just what harry has written to repeat the script.
-
@hyperx: You asked me via private chat how to read a decimal value and convert it to all single binary units to write to pimatic.
See below an example (untested as I don’t have a modbus):# The switches to push or pull; Give them the name of the vars in pimatic switches = ["switch1", "switch2", "switch3", "switch4", "switch5", "switch6"] #read your data # with 6 switches max 111111 = 63 data = instrument.read_register(302, 0) # read state of all switches # Convert decimal data to binary to string bin_data_string = str(bin(data)) # if data=56 this will give "0b111000" but for 15 it will give "0b1111" I assume and not "0b001111" # Remove 0b from string: replace 0b with nothing bin_data_string=bin_data_string.replace("0b","") # Convert to array like 111000 => ["1", "1", "1", "0", "0", "0"] bin_array = list(bin_data_string) # Now reverse list order (highest binary number becomes last "digit" in array) bin_array=bin_array[::-1] # check whether we had all switches # If we have 6 switches, the number should be at least 32 with switch 6 on # if it is less than 32, the switch state of 6 is 0 and it will only write 5 0/1 values I assume length_difference = len(switches) - len(bin_array) if length_difference > 0: for x in range(0, length_difference): bin_array.extend(["0"]) for x in range(0, len(bin_array)): #print (switches[x] + " is " + bin_array[x]) # write to pimatic os.system(curl_prefix + bin_array[x] + '"}\' --user "' + pim_user_pass + '" ' + pim_server_url + switches[x]) time.sleep(2) # 2 seconds sleep. check if shorter is possible like 1 or 1.5 or 0.5
Again: when writing or reading you could do some error checking like you mentioned yourself above
-
I made it!!!
I’m using pipes in python. Now you can control the python script be writing arguments to a “pipefile”.
Works like a charme for me:#/usr/bin/env python import minimalmodbus import pipes import time instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 6) instrument.serial.baudrate = 57600 instrument.serial.parity = 'N' instrument.serial.bytesize = 8 instrument.serial.stopbits = 1 instrument.serial.timeout = 2.00 t = pipes.Template() t.append('tr a-z A-Z', '--') # only for first run f = t.open('pipefile', 'w') f.write('empty') f.close() # do this till 'stop' while 1: x = open('pipefile').read() if x[:-1] == 'stop': break if x[:-1] == '10': try: instrument.write_bit(528, 1, 15) f.close f = t.open('pipefile', 'w') f.write('empty') f.close except IOError: print("Fehler beim schreiben") if x[:-1] == '6': try: gelesen = instrument.read_register(16, 0) print (gelesen) f.close f = t.open('pipefile', 'w') f.write('empty') f.close except IOError: print("Fehler beim lesen") else: time.sleep(1) f.close()
-
Can someone tell how to post code the right way?!
-
example for usage:
run the script above in one console.
on a second console type:
echo 6 > pipefile
orecho 10 > pipefile
to stop the script type:
echo stop > pipefile
-
@heinleinm said:
Can someone tell how to post code the right way?!
You can use 3 “back ticks” before and after the code like ```