homecontrol-neopixel: work with homecontrol
This commit is contained in:
		
						commit
						1367690f70
					
				
					 6 changed files with 174 additions and 0 deletions
				
			
		
							
								
								
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | .idea/* | ||||||
|  | Pipfile.lock | ||||||
							
								
								
									
										14
									
								
								Pipfile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Pipfile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | ||||||
|  | [[source]] | ||||||
|  | name = "pypi" | ||||||
|  | url = "https://pypi.org/simple" | ||||||
|  | verify_ssl = true | ||||||
|  | 
 | ||||||
|  | [dev-packages] | ||||||
|  | 
 | ||||||
|  | [packages] | ||||||
|  | pyserial = ">=3.3,<4.0" | ||||||
|  | docopt = "<0.7,>=0.6.2" | ||||||
|  | adafruit-ampy = ">=1.0.5,<1.1" | ||||||
|  | 
 | ||||||
|  | [requires] | ||||||
|  | python_version = "3.7" | ||||||
							
								
								
									
										1
									
								
								boot.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								boot.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | # not doing anything | ||||||
							
								
								
									
										112
									
								
								main.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								main.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,112 @@ | ||||||
|  | import machine | ||||||
|  | import neopixel | ||||||
|  | import utime as time | ||||||
|  | import urequests as requests | ||||||
|  | import uuid | ||||||
|  | import ujson | ||||||
|  | import math | ||||||
|  | import wifi | ||||||
|  | 
 | ||||||
|  | CONFIG = "config.json" | ||||||
|  | ADDRESS = "http://192.168.11.21:5000" | ||||||
|  | TIMEOUT_UPDATE = 1 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ActorNP: | ||||||
|  |     def __init__(self): | ||||||
|  |         self.config = {} | ||||||
|  |         try: | ||||||
|  |             config_file = open(CONFIG, "r") | ||||||
|  |             self.config = ujson.load(config_file) | ||||||
|  |         except Exception as ex: | ||||||
|  |             print("Exception\n\ttype: %s\n\targs: %s" % (type(ex).__name__, ex.args)) | ||||||
|  | 
 | ||||||
|  |         update_config = False | ||||||
|  |         if not self.config.get("id"): | ||||||
|  |             update_config = True | ||||||
|  |             self.config["id"] = uuid.uuid4().hex | ||||||
|  |         if not self.config.get("type"): | ||||||
|  |             update_config = True | ||||||
|  |             self.config["type"] = "neopixel" | ||||||
|  |         if not self.config.get("levels"): | ||||||
|  |             update_config = True | ||||||
|  |             self.config["levels"] = 0xffffff | ||||||
|  |         if update_config: | ||||||
|  |             with open(CONFIG, "w") as config_file: | ||||||
|  |                 ujson.dump(self.config, config_file) | ||||||
|  | 
 | ||||||
|  |         self.id_a = self.config["id"] | ||||||
|  |         self.type_a = self.config["type"] | ||||||
|  |         self.levels = self.config["levels"] | ||||||
|  |         self.color = (0, 0, 0) | ||||||
|  |         self.np = neopixel.NeoPixel(machine.Pin(2), 16) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def update(self): | ||||||
|  |         url = "%s/actors/update" % ADDRESS | ||||||
|  |         level = ((self.color[0] << 16) + (self.color[1] << 8) + self.color[2]) & 0xffffff | ||||||
|  |         data = {"id": self.id_a, "type": self.type_a, "levels": self.levels, "level": level} | ||||||
|  |         try: | ||||||
|  |             res = requests.post(url, json=data) | ||||||
|  |             content = res.json() | ||||||
|  |             if "command" in content: | ||||||
|  |                 command = content["command"] | ||||||
|  |                 if command == "set_level": | ||||||
|  |                     data = content["data"] | ||||||
|  |                     level = int(data["level"]) | ||||||
|  |                     self.set_level(level) | ||||||
|  |             # remember to close | ||||||
|  |             res.close() | ||||||
|  |         except Exception as ex: | ||||||
|  |             print("Exception\n\tdata: %s\n\ttype: %s\n\targs: %s" % (data, type(ex).__name__, ex.args)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def set_level(self, level): | ||||||
|  |         print("set_level: level: 0x%06x" % (level)) | ||||||
|  |         t = 1 | ||||||
|  |         steps = 25 | ||||||
|  |         t_step = t/steps | ||||||
|  |         br_step = 1/steps | ||||||
|  |         # turn off | ||||||
|  |         br = 1 | ||||||
|  |         r = self.color[0] | ||||||
|  |         g = self.color[1] | ||||||
|  |         b = self.color[2] | ||||||
|  |         if (r or g or b): | ||||||
|  |             for i in range(steps): | ||||||
|  |                 br = br - br_step | ||||||
|  |                 self.np.fill(self.col(r, g, b, br)) | ||||||
|  |                 self.np.write() | ||||||
|  |                 time.sleep(t_step) | ||||||
|  | 
 | ||||||
|  |         # turn on | ||||||
|  |         r = (level >> 16) & 0xff | ||||||
|  |         g = (level >> 8) & 0xff | ||||||
|  |         b = level & 0xff | ||||||
|  |         br = 0 | ||||||
|  |         if (r or g or b): | ||||||
|  |             for i in range(steps): | ||||||
|  |                 br = br + br_step | ||||||
|  |                 self.np.fill(self.col(r, g, b, br)) | ||||||
|  |                 self.np.write() | ||||||
|  |                 time.sleep(t_step) | ||||||
|  | 
 | ||||||
|  |         self.color = (r, g, b) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def col(self, r, g, b, br): | ||||||
|  |         rr = int(math.ceil(r * br)) | ||||||
|  |         gg = int(math.ceil(g * br)) | ||||||
|  |         bb = int(math.ceil(b * br)) | ||||||
|  |         c = (rr, gg, bb) | ||||||
|  |         return(c) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     w = wifi.wifi() | ||||||
|  |     w.connect() | ||||||
|  |     np = ActorNP() | ||||||
|  |     while True: | ||||||
|  |         np.update() | ||||||
|  |         time.sleep(TIMEOUT_UPDATE) | ||||||
|  | 
 | ||||||
							
								
								
									
										28
									
								
								uuid.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								uuid.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | ||||||
|  | import uos | ||||||
|  | import ubinascii | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class UUID: | ||||||
|  |     def __init__(self, bytes): | ||||||
|  |         if len(bytes) != 16: | ||||||
|  |             raise ValueError('bytes arg must be 16 bytes long') | ||||||
|  |         self._bytes = bytes | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def hex(self): | ||||||
|  |         return ubinascii.hexlify(self._bytes).decode() | ||||||
|  | 
 | ||||||
|  |     def __str__(self): | ||||||
|  |         h = self.hex | ||||||
|  |         return '-'.join((h[0:8], h[8:12], h[12:16], h[16:20], h[20:32])) | ||||||
|  | 
 | ||||||
|  |     def __repr__(self): | ||||||
|  |         return "<UUID: %s>" % str(self) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def uuid4(): | ||||||
|  |     """Generates a random UUID compliant to RFC 4122 pg.14""" | ||||||
|  |     random = bytearray(uos.urandom(16)) | ||||||
|  |     random[6] = (random[6] & 0x0F) | 0x40 | ||||||
|  |     random[8] = (random[8] & 0x3F) | 0x80 | ||||||
|  |     return UUID(bytes=random) | ||||||
							
								
								
									
										17
									
								
								wifi.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								wifi.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | ||||||
|  | import network | ||||||
|  | NET_SSID="omnomnom" | ||||||
|  | NET_PASS="Ne!HabIchNicht!" | ||||||
|  | 
 | ||||||
|  | class wifi: | ||||||
|  |     def __init__(self): | ||||||
|  |         self.if_ap = network.WLAN(network.AP_IF) | ||||||
|  |         self.if_sta = network.WLAN(network.STA_IF) | ||||||
|  | 
 | ||||||
|  |     def connect(self): | ||||||
|  |         self.if_ap.active(False) | ||||||
|  |         self.if_sta.active(True) | ||||||
|  |         self.if_sta.connect(NET_SSID, NET_PASS) | ||||||
|  |         while not self.if_sta.isconnected(): | ||||||
|  |             pass | ||||||
|  |         print("network config: ", self.if_sta.ifconfig()) | ||||||
|  | 
 | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue